[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How to build xscheme for the mac



In article <2091@cunixc.cc.columbia.edu>, puglia@cunixc.cc.columbia.edu (Paul Puglia) writes:
> How does you build xscheme on a macintosh ? I have a copy of 
> the xscheme sources compiles fine on a unix machine, and works
> great on a pc with turbo c.  When I tried to compile it on a 
> friends mac II using his copy of lightspeed c. I have no luck. 
> Could someone please describe the procedure to compile this program, and
> comment on if anything else is need to compile xscheme. I know that you 
> need some resource to compile xlisp on a mac. Do you need the same sort of 
> stuff for xscheme
> Thanks in advance
> Paul Puglia
> Dept of Civil Engineering 
> Columbia University



Porting Xlisp/XScheme:

Awhile back, while I was taking an AI course, I was spending a lot of time
trekking to campus and using their LISP system.  To avoid travel time (and
to work on LISP at any hour I wanted), I got into porting XLisp. In looking at 
the code, I'd say XLisp and XScheme are two of the most portable C programs
I have ever seen.  Now, I've spent most of my time on XLisp, so your
mileage may vary, but...

XLisp seems to place most Operating System (OS)-dependent features in 
separate files, named dosstuff.c, osptrs.h, osdefs.h.  On UNIX, the "stuff:
file is called unixstuf.c and on the Mac its called macstuff.c (all file
names are <= 8 chars for MS-DOS).  The mac version also has a resource
compiler file (that is, a file you run through the resource compiler to
generate a resource file).

I assume (hope) XScheme is similiar.  Below, I placed all my Mac-related
files from XLisp (2.0, I think).  The XScheme stuff should be similiar.
I hope these help.  (Note: I don't have the full sources around now, just
the Mac and UNIX-specific files.)  (Note2: Two extra files, macfun.c and
macinit.c are below, its been so long that I'm not sure if these are extras
or necessary--Sorry.)

I'm placing these files here in hopes they can help you with your porting.  I
do know that binary executable versions of XScheme are available on the
BIX bulletin board (Byte magazine Information eXchange)--see Byte mag
for details.  Getting the binaries would solve all the Mac porting
problems in one fell swoop.

Anyway, hope this helps,
-Eric


======================== macfun.c =============================================

/* macfun.c - macintosh user interface functions for xlisp */

#include <Quickdraw.h>
#include <WindowMgr.h>
#include <MemoryMgr.h>
#include "xlisp.h"

/* external variables */
extern GrafPtr cwindow,gwindow;

/* forward declarations */
FORWARD LVAL do_0();
FORWARD LVAL do_1();
FORWARD LVAL do_2();

/* xptsize - set the command window point size */
LVAL xptsize()
{
    LVAL val;
    val = xlgafixnum();
    xllastarg();
    TextSize((int)getfixnum(val));
    InvalRect(&cwindow->portRect);
    SetupScreen();
    return (NIL);
}

/* xhidepen - hide the pen */
LVAL xhidepen()
{
    return (do_0('H'));
}

/* xshowpen - show the pen */
LVAL xshowpen()
{
    return (do_0('S'));
}

/* xgetpen - get the pen position */
LVAL xgetpen()
{
    LVAL val;
    Point p;
    xllastarg();
    SetPort(gwindow);
    GetPen(&p);
    SetPort(cwindow);
    xlsave1(val);
    val = consa(NIL);
    rplaca(val,cvfixnum((FIXTYPE)p.h));
    rplacd(val,cvfixnum((FIXTYPE)p.v));
    xlpop();
    return (val);
}

/* xpenmode - set the pen mode */
LVAL xpenmode()
{
    return (do_1('M'));
}

/* xpensize - set the pen size */
LVAL xpensize()
{
    return (do_2('S'));
}

/* xpenpat - set the pen pattern */
LVAL xpenpat()
{
    LVAL plist;
    char pat[8],i;
    plist = xlgalist();
    xllastarg();
    for (i = 0; i < 8 && consp(plist); ++i, plist = cdr(plist))
	if (fixp(car(plist)))
	    pat[i] = getfixnum(car(plist));
    SetPort(gwindow);
    PenPat(pat);
    SetPort(cwindow);
    return (NIL);
}

/* xpennormal - set the pen to normal */
LVAL xpennormal()
{
    xllastarg();
    SetPort(gwindow);
    PenNormal();
    SetPort(cwindow);
    return (NIL);
}

/* xmoveto - Move to a screen location */
LVAL xmoveto()
{
    return (do_2('m'));
}

/* xmove - Move in a specified direction */
LVAL xmove()
{
    return (do_2('M'));
}

/* xlineto - draw a Line to a screen location */
LVAL xlineto()
{
    return (do_2('l'));
}

/* xline - draw a Line in a specified direction */
LVAL xline()
{
    return (do_2('L'));
}

/* xshowgraphics - show the graphics window */
LVAL xshowgraphics()
{
    xllastarg();
    scrsplit(1);
    return (NIL);
}

/* xhidegraphics - hide the graphics window */
LVAL xhidegraphics()
{
    xllastarg();
    scrsplit(0);
    return (NIL);
}

/* xcleargraphics - clear the graphics window */
LVAL xcleargraphics()
{
    xllastarg();
    SetPort(gwindow);
    EraseRect(&gwindow->portRect);
    SetPort(cwindow);
    return (NIL);
}

/* do_0 - Handle commands that require no arguments */
LOCAL LVAL do_0(fcn)
  int fcn;
{
    xllastarg();
    SetPort(gwindow);
    switch (fcn) {
    case 'H':	HidePen(); break;
    case 'S':	ShowPen(); break;
    }
    SetPort(cwindow);
    return (NIL);
}

/* do_1 - Handle commands that require one integer argument */
LOCAL LVAL do_1(fcn)
  int fcn;
{
    int x;
    x = getnumber();
    xllastarg();
    SetPort(gwindow);
    switch (fcn) {
    case 'M':	PenMode(x); break;
    }
    SetPort(cwindow);
    return (NIL);
}

/* do_2 - Handle commands that require two integer arguments */
LOCAL LVAL do_2(fcn)
  int fcn;
{
    int h,v;
    h = getnumber();
    v = getnumber();
    xllastarg();
    SetPort(gwindow);
    switch (fcn) {
    case 'l':	LineTo(h,v); break;
    case 'L':	Line(h,v);   break;
    case 'm':   MoveTo(h,v); break;
    case 'M':	Move(h,v);   break;
    case 'S':	PenSize(h,v);break;
    }
    SetPort(cwindow);
    return (NIL);
}

/* getnumber - get an integer parameter */
LOCAL int getnumber()
{
    LVAL num;
    num = xlgafixnum();
    return ((int)getfixnum(num));
}

/* xtool - call the toolbox */
LVAL xtool()
{
    LVAL val;
    int trap;

    trap = getnumber();
/*

    asm {
	move.l	args(A6),D0
	beq	L2
L1:	move.l	D0,A0
	move.l	2(A0),A1
	move.w	4(A1),-(A7)
	move.l	6(A0),D0
	bne	L1
L2:	lea	L3,A0
	move.w	trap(A6),(A0)
L3:	dc.w	0xA000
	clr.l	val(A6)
    }
*/

    return (val);
}

/* xtool16 - call the toolbox with a 16 bit result */
LVAL xtool16()
{
    int trap,val;

    trap = getnumber();
/*

    asm {
	clr.w	-(A7)
	move.l	args(A6),D0
	beq	L2
L1:	move.l	D0,A0
	move.l	2(A0),A1
	move.w	4(A1),-(A7)
	move.l	6(A0),D0
	bne	L1
L2:	lea	L3,A0
	move.w	trap(A6),(A0)
L3:	dc.w	0xA000
	move.w	(A7)+,val(A6)
    }
*/

    return (cvfixnum((FIXTYPE)val));
}

/* xtool32 - call the toolbox with a 32 bit result */
LVAL xtool32()
{
    int trap;
    long val;

    trap = getnumber();
/*

    asm {
	clr.l	-(A7)
	move.l	args(A6),D0
	beq	L2
L1:	move.l	D0,A0
	move.l	2(A0),A1
	move.w	4(A1),-(A7)
	move.l	6(A0),D0
	bne	L1
L2:	lea	L3,A0
	move.w	trap(A6),(A0)
L3:	dc.w	0xA000
	move.l	(A7)+,val(A6)
    }
*/

    return (cvfixnum((FIXTYPE)val));
}

/* xnewhandle - allocate a new handle */
LVAL xnewhandle()
{
    LVAL num;
    long size;
    num = xlgafixnum(); size = getfixnum(num);
    xllastarg();
    return (cvfixnum((FIXTYPE)NewHandle(size)));
}

/* xnewptr - allocate memory */
LVAL xnewptr()
{
    LVAL num;
    long size;
    num = xlgafixnum(); size = getfixnum(num);
    xllastarg();
    return (cvfixnum((FIXTYPE)NewPtr(size)));
}
    
/* xhiword - return the high order 16 bits of an integer */
LVAL xhiword()
{
    unsigned int val;
    val = (unsigned int)(getnumber() >> 16);
    xllastarg();
    return (cvfixnum((FIXTYPE)val));
}

/* xloword - return the low order 16 bits of an integer */
LVAL xloword()
{
    unsigned int val;
    val = (unsigned int)getnumber();
    xllastarg();
    return (cvfixnum((FIXTYPE)val));
}

/* xrdnohang - get the next character in the look-ahead buffer */
LVAL xrdnohang()
{
    int ch;
    xllastarg();
    if ((ch = scrnextc()) == EOF)
	return (NIL);
    return (cvfixnum((FIXTYPE)ch));
}

/* ossymbols - enter important symbols */
ossymbols()
{
    LVAL sym;

    /* setup globals for the window handles */
    sym = xlenter("*COMMAND-WINDOW*");
    setvalue(sym,cvfixnum((FIXTYPE)cwindow));
    sym = xlenter("*GRAPHICS-WINDOW*");
    setvalue(sym,cvfixnum((FIXTYPE)gwindow));
}


======================== macint.c =============================================

/* macint.c - macintosh interface routines for xlisp */

#include <MacTypes.h>
#include <Quickdraw.h>  
#include <WindowMgr.h>
#include <EventMgr.h>
#include <DialogMgr.h>
#include <MenuMgr.h>
#include <PackageMgr.h>
#include <StdFilePkg.h>
#include <MemoryMgr.h>
#include <DeskMgr.h>
#include <FontMgr.h>
#include <ControlMgr.h>
#include <SegmentLdr.h>
#include <FileMgr.h>

/* program limits */
#define SCRH		40	/* maximum screen height */
#define SCRW		100	/* maximum screen width */
#define CHARMAX 	100	/* maximum number of buffered characters */
#define TIMEON		40	/* cursor on time */
#define TIMEOFF		20	/* cursor off time */

/* useful definitions */
#define MenuBarHeight	20
#define TitleBarHeight	20
#define SBarWidth	16
#define MinWidth	80
#define MinHeight	40
#define ScreenMargin	2
#define TextMargin	4
#define GHeight		232

/* menu id's */
#define appleID		1
#define fileID		256
#define editID		257
#define controlID	258

/* externals */
extern char *s_unbound;
extern char *PtoCstr();

/* screen dimensions */
int screenWidth;
int screenHeight;

/* command window (normal screen) */
int nHorizontal,nVertical,nWidth,nHeight;

/* command window (split screen) */
int sHorizontal,sVertical,sWidth,sHeight;

/* graphics window */
int gHorizontal,gVertical,gWidth,gHeight;

/* menu handles */
MenuHandle appleMenu;
MenuHandle fileMenu;
MenuHandle editMenu;
MenuHandle controlMenu;

/* misc variables */
OSType filetypes[] = { 'TEXT' };

/* font information */
int tmargin,lmargin;
int xinc,yinc;

/* command window */
WindowRecord cwrecord;
WindowPtr cwindow;

/* graphics window */
WindowRecord gwrecord;
WindowPtr gwindow;

/* window mode */
int splitmode;

/* cursor variables */
long cursortime;
int cursorstate;
int x,y;

/* screen buffer */
char screen[SCRH*SCRW],*topline,*curline;
int scrh,scrw;

/* type ahead buffer */
char charbuf[CHARMAX],*inptr,*outptr;
int charcnt;

macinit()
{
    /* initialize the toolbox */
    InitGraf(&thePort);
    InitFonts();
    InitWindows();
    InitMenus();
    TEInit();
    InitDialogs(0L);
    InitCursor();

    /* setup the menu bar */
    SetupMenus();

    /* get the size of the screen */
    screenWidth  = screenBits.bounds.right  - screenBits.bounds.left;
    screenHeight = screenBits.bounds.bottom - screenBits.bounds.top;

    /* Create the graphics and control windows */
    gwindow = GetNewWindow(129,&gwrecord,-1L);
    cwindow = GetNewWindow(128,&cwrecord,-1L);

    /* establish the command window as the current port */
    SetPort(cwindow);

    /* compute the size of the normal command window */
    nHorizontal = ScreenMargin;
    nVertical = MenuBarHeight + TitleBarHeight + ScreenMargin - 2;
    nWidth = screenWidth - (ScreenMargin * 2) - 1;
    nHeight = screenHeight - MenuBarHeight - TitleBarHeight - (ScreenMargin * 2);

    /* compute the size of the split command window */
    sHorizontal = nHorizontal;
    sVertical = nVertical + GHeight + 1;
    sWidth = nWidth;
    sHeight = nHeight - GHeight - 1;

    /* compute the size of the graphics window */
    gHorizontal = nHorizontal;
    gVertical = MenuBarHeight + ScreenMargin;
    gWidth = screenWidth - (ScreenMargin * 2);
    gHeight = GHeight;

    /* move and size the graphics window */
    MoveWindow(gwindow,gHorizontal,gVertical,0);
    SizeWindow(gwindow,gWidth,gHeight,0);

    /* setup the font, size and writing mode for the command window */
    TextFont(monaco); TextSize(9); TextMode(srcCopy);

    /* setup command mode */
    scrsplit(FALSE);

    /* disable the Cursor */
    cursorstate = -1;

    /* setup the input ring buffer */
    inptr = outptr = charbuf;
    charcnt = 0;
    
    /* lock the font in memory */
    SetFontLock(-1);
}

SetupMenus()
{
    appleMenu = GetMenu(appleID);	/* setup the apple menu */
    AddResMenu(appleMenu,'DRVR');
    InsertMenu(appleMenu,0);
    fileMenu = GetMenu(fileID);		/* setup the file menu */
    InsertMenu(fileMenu,0);
    editMenu = GetMenu(editID);		/* setup the edit menu */
    InsertMenu(editMenu,0);
    controlMenu = GetMenu(controlID);	/* setup the control menu */
    InsertMenu(controlMenu,0);
    DrawMenuBar();
}

int scrgetc()
{
    CursorOn();
    while (charcnt == 0)
	DoEvent();
    CursorOff();
    return (scrnextc());
}

int scrnextc()
{
    int ch;
    if (charcnt > 0) {
	ch = *outptr++; charcnt--;
	if (outptr >= &charbuf[CHARMAX])
	    outptr = charbuf;
    }
    else {
	charcnt = 0;
	ch = -1;
    }
    return (ch);
}

scrputc(ch)
  int ch;
{
    switch (ch) {
    case '\r':
	x = 0;
	break;
    case '\n':
	nextline(&curline);
	if (++y >= scrh) {
	    y = scrh - 1;
	    scrollup();
	}
	break;
    case '\t':
	do { scrputc(' '); } while (x & 7);
	break;
    case '\010':
	if (x) x--;
	break;
    default:
	if (ch >= 0x20 && ch < 0x7F) {
	    scrposition(x,y);
	    DrawChar(ch);
	    curline[x] = ch;
	    if (++x >= scrw) {
		nextline(&curline);
		if (++y >= scrh) {
		    y = scrh - 1;
		    scrollup();
		}
		x = 0;
	    }
	}
	break;
    }
}

scrdelete()
{
    scrputc('\010');
    scrputc(' ');
    scrputc('\010');
}

scrclear()
{
    curline = screen;
    for (y = 0; y < SCRH; y++)
	for (x = 0; x < SCRW; x++)
	    *curline++ = ' ';
    topline = curline = screen;
    x = y = 0;
}

scrflush()
{
    inptr = outptr = charbuf;
    charcnt = -1;
    osflush();
}

scrposition(x,y)
  int x,y;
{
    MoveTo((x * xinc) + lmargin,(y * yinc) + tmargin);
}

DoEvent()
{
    EventRecord myEvent;
    
    SystemTask();
    CursorUpdate();

    while (GetNextEvent(everyEvent,&myEvent))
	switch (myEvent.what) {
	    case mouseDown:
		DoMouseDown(&myEvent);
		break;
	    case keyDown:
	    case autoKey:
		DoKeyPress(&myEvent);
		break;
	    case activateEvt:
		DoActivate(&myEvent);
		break;
	    case updateEvt:
		DoUpdate(&myEvent);
		break;
	    }
}

DoMouseDown(myEvent)
  EventRecord *myEvent;
{
    WindowPtr whichWindow;

    switch (FindWindow(myEvent->where,&whichWindow)) {
    case inMenuBar:
	DoMenuClick(myEvent);
	break;
    case inSysWindow:
	SystemClick(myEvent,whichWindow);
	break;
    case inDrag:
	DoDrag(myEvent,whichWindow);
	break;
    case inGoAway:
	DoGoAway(myEvent,whichWindow);
	break;
    case inGrow:
	DoGrow(myEvent,whichWindow);
	break;
    case inContent:
	DoContent(myEvent,whichWindow);
	break;
    }
}

DoMenuClick(myEvent)
  EventRecord *myEvent;
{
    long choice;
    if (choice = MenuSelect(myEvent->where))
	DoCommand(choice);
}

DoDrag(myEvent,whichWindow)
  EventRecord *myEvent;
  WindowPtr whichWindow;
{
    Rect dragRect;
    SetRect(&dragRect,0,MenuBarHeight,screenWidth,screenHeight);
    InsetRect(&dragRect,ScreenMargin,ScreenMargin);
    DragWindow(whichWindow,myEvent->where,&dragRect);
}

DoGoAway(myEvent,whichWindow)
  EventRecord *myEvent;
  WindowPtr whichWindow;
{
    if (TrackGoAway(whichWindow,myEvent->where))
	wrapup();
}

DoGrow(myEvent,whichWindow)
  EventRecord *myEvent;
  WindowPtr whichWindow;
{
    Rect sizeRect;
    long newSize;
    if (whichWindow != FrontWindow() && whichWindow != gwindow)
	SelectWindow(whichWindow);
    else {
	SetRect(&sizeRect,MinWidth,MinHeight,screenWidth,screenHeight-MenuBarHeight);
	newSize = GrowWindow(whichWindow,myEvent->where,&sizeRect);
	if (newSize) {
	    EraseRect(&whichWindow->portRect);
	    SizeWindow(whichWindow,LoWord(newSize),HiWord(newSize),-1);
	    InvalRect(&whichWindow->portRect);
	    SetupScreen();
	    scrflush();
	}
    }
}

DoContent(myEvent,whichWindow)
  EventRecord *myEvent;
  WindowPtr whichWindow;
{
    if (whichWindow != FrontWindow() && whichWindow != gwindow)
	SelectWindow(whichWindow);
}

DoKeyPress(myEvent)
  EventRecord *myEvent;
{
    long choice;
    
    if (FrontWindow() == cwindow) {
	if (myEvent->modifiers & 0x100) {
	    if (choice = MenuKey((char)myEvent->message))
		DoCommand(choice);
	}
	else {
	    if (charcnt < CHARMAX) {
		*inptr++ = myEvent->message & 0xFF; charcnt++;
		if (inptr >= &charbuf[CHARMAX])
		    inptr = charbuf;
	    }
	}
    }
}

DoActivate(myEvent)
  EventRecord *myEvent;
{
    WindowPtr whichWindow;
    whichWindow = (WindowPtr)myEvent->message;
    SetPort(whichWindow);
    if (whichWindow == cwindow)
	DrawGrowIcon(whichWindow);
}

DoUpdate(myEvent)
  EventRecord *myEvent;
{
    WindowPtr whichWindow;
    GrafPtr savePort;
    GetPort(&savePort);
    whichWindow = (WindowPtr)myEvent->message;
    SetPort(whichWindow);
    BeginUpdate(whichWindow);
    EraseRect(&whichWindow->portRect);
    if (whichWindow == cwindow) {
	DrawGrowIcon(whichWindow);
	RedrawScreen();
    }
    EndUpdate(whichWindow);
    SetPort(savePort);
}

DoCommand(choice)
  long choice;
{
    int theMenu,theItem;
    
    /* decode the menu choice */
    theMenu = HiWord(choice);
    theItem = LoWord(choice);
    
    CursorOff();
    HiliteMenu(theMenu);
    switch (theMenu) {
    case appleID:
	DoAppleMenu(theItem);
	break;
    case fileID:
	DoFileMenu(theItem);
	break;
    case editID:
	DoEditMenu(theItem);
	break;
    case controlID:
	DoControlMenu(theItem);
	break;
    }
    HiliteMenu(0);
    CursorOn();
}

pascal aboutfilter(theDialog,theEvent,itemHit)
  DialogPtr theDialog; EventRecord *theEvent; int *itemHit;
{
    return (theEvent->what == mouseDown ? -1 : 0);
}

DoAppleMenu(theItem)
  int theItem;
{
    DialogRecord mydialog;
    char name[256];
    GrafPtr gp;
    int n;

    switch (theItem) {
    case 1:
	GetNewDialog(129,&mydialog,-1L);
	ModalDialog(aboutfilter,&n);
	CloseDialog(&mydialog);
	break;
    default:
	GetItem(appleMenu,theItem,name);
	GetPort(&gp);
	OpenDeskAcc(name);
	SetPort(gp);
	break;
    }
}

pascal int filefilter(pblock)
  ParmBlkPtr pblock;
{
    unsigned char *p; int len;
    p = pblock->fileParam.ioNamePtr; len = *p++ &0xFF;
    return (len >= 4 && strncmp(p+len-4,".lsp",4) == 0 ? 0 : -1);
}

DoFileMenu(theItem)
  int theItem;
{
    SFReply loadfile;
    Point p;

    switch (theItem) {
    case 1:	/* load */
    case 2:	/* load noisily */
	p.h = 100; p.v = 100;
	SFGetFile(p,"\P",filefilter,-1,filetypes,0L,&loadfile);
	if (loadfile.good) {
	    HiliteMenu(0);
	    SetVol(0L,loadfile.vRefNum);
	    if (xlload(PtoCstr(loadfile.fName),1,(theItem == 1 ? 0 : 1)))
		scrflush();
	    else
		xlabort("load error");
	}
	break;
    case 4:	/* quit */
	wrapup();
    }
}

DoEditMenu(theItem)
  int theItem;
{
    switch (theItem) {
    case 1:	/* undo */
    case 3:	/* cut */
    case 4:	/* copy */
    case 5:	/* paste */
    case 6:	/* clear */
	SystemEdit(theItem-1);
	break;
    }
}

DoControlMenu(theItem)
  int theItem;
{
    scrflush();
    HiliteMenu(0);
    switch (theItem) {
    case 1:	/* break */
	xlbreak("user break",s_unbound);
	break;
    case 2:	/* continue */
	xlcontinue();
	break;
    case 3:	/* clean-up error */
	xlcleanup();
	break;
    case 4:	/* Cancel input */
	xlabort("input canceled");
	break;
    case 5:	/* Top Level */
	xltoplevel();
	break;
    case 7:	/* split screen */
	scrsplit(splitmode ? FALSE : TRUE);
	break;
    }
}

scrsplit(split)
  int split;
{
    ShowHide(cwindow,0);
    if (split) {
	CheckItem(controlMenu,7,-1);
	ShowHide(gwindow,-1);
	MoveWindow(cwindow,sHorizontal,sVertical,-1);
	SizeWindow(cwindow,sWidth,sHeight,-1);
	InvalRect(&cwindow->portRect);
	SetupScreen();
    }
    else {
	CheckItem(controlMenu,7,0);
	ShowHide(gwindow,0);
	MoveWindow(cwindow,nHorizontal,nVertical,-1);
	SizeWindow(cwindow,nWidth,nHeight,-1);
	InvalRect(&cwindow->portRect);
	SetupScreen();
    }
    ShowHide(cwindow,-1);
    splitmode = split;
}

SetupScreen()
{
    FontInfo info;
    Rect *pRect;

    /* get font information */
    GetFontInfo(&info);

    /* compute the top and bottom margins */
    tmargin = TextMargin + info.ascent;
    lmargin = TextMargin;

    /* compute the x and y increments */
    xinc = info.widMax;
    yinc = info.ascent + info.descent + info.leading;

    /* compute the character dimensions of the screen */
    pRect = &cwindow->portRect;
    scrh = (pRect->bottom - (2 * TextMargin) - (SBarWidth - 1)) / yinc;
    if (scrh > SCRH) scrh = SCRH;
    scrw = (pRect->right - (2 * TextMargin) - (SBarWidth - 1)) / xinc;
    if (scrw > SCRW) scrw = SCRW;
    
    /* clear the screen */
    scrclear();
}

CursorUpdate()
{
    if (cursorstate != -1)
	if (cursortime < TickCount()) {
	    scrposition(x,y);
	    if (cursorstate) {
		DrawChar(' ');
		cursortime = TickCount() + TIMEOFF;
		cursorstate = 0;
	    }
	    else {
		DrawChar('_');
		cursortime = TickCount() + TIMEON;
		cursorstate = 1;
	    }
	}
}

CursorOn()
{
    cursortime = TickCount();
    cursorstate = 0;
}

CursorOff()
{
    if (cursorstate == 1) {
	scrposition(x,y);
	DrawChar(' ');
    }
    cursorstate = -1;
}

RedrawScreen()
{
    char *Line; int y;
    Line = topline;
    for (y = 0; y < scrh; y++) {
	scrposition(0,y);
	DrawText(Line,0,scrw);
	nextline(&Line);
    }
}

nextline(pline)
  char **pline;
{
    if ((*pline += SCRW) >= &screen[SCRH*SCRW])
	*pline = screen;
}

scrollup()
{
    RgnHandle updateRgn;
    Rect rect;
    int x;
    updateRgn = NewRgn();
    rect = cwindow->portRect;
    rect.bottom -= SBarWidth - 1;
    rect.right -= SBarWidth - 1;
    ScrollRect(&rect,0,-yinc,updateRgn);
    DisposeRgn(updateRgn);
    for (x = 0; x < SCRW; x++)
	topline[x] = ' ';
    nextline(&topline);
}

======================== macstuff.c ==========================================

/* macstuff.c - macintosh interface routines for xlisp */

#include <stdio.h>

/* program limits */
#define LINEMAX 	200	/* maximum line length */

/* externals */
extern FILE *tfp;
extern int x;

/* local variables */
static char linebuf[LINEMAX+1],*lineptr;
static int linepos[LINEMAX],linelen;
static long rseed = 1L;

osinit(name)
  char *name;
{
    /* initialize the mac interface routines */
    macinit();

    /* initialize the line editor */
    linelen = 0;
}

osfinish()
{
}

oserror(msg)
{
    char line[100],*p;
    sprintf(line,"error: %s\n",msg);
    for (p = line; *p != '\0'; ++p)
	ostputc(*p);
}

int osrand(n)
  int n;
{
    long k1;
    
    /* make sure we don't get stuck at zero */
    if (rseed == 0L) rseed = 1L;
    
    /* algorithm taken from Dr. Dobbs Journal, November 1985, Page 91 */
    k1 = rseed / 127773L;
    if ((rseed = 16807L * (rseed - k1 * 127773L) - k1 * 2836L) < 0L)
	rseed += 2147483647L;
	
    /* return a random number between 0 and n-1 */
    return ((int)(rseed % (long)n));
}

FILE *osaopen(name,mode)
  char *name,*mode;
{
    return (fopen(name,mode));
}

FILE *osbopen(name,mode)
  char *name,*mode;
{
    char nmode[4];
    strcpy(nmode,mode); strcat(nmode,"b");
    return (fopen(name,nmode));
}

int osclose(fp)
  FILE *fp;
{
    return (fclose(fp));
}

int osagetc(fp)
  FILE *fp;
{
    return (getc(fp));
}

int osbgetc(fp)
  FILE *fp;
{
    return (getc(fp));
}

int osaputc(ch,fp)
  int ch; FILE *fp;
{
    return (putc(ch,fp));
}

int osbputc(ch,fp)
  int ch; FILE *fp;
{
    return (putc(ch,fp));
}

int ostgetc()
{
    int ch,i;

    if (linelen--) return (*lineptr++);
    linelen = 0;
    while ((ch = scrgetc()) != '\r')
	switch (ch) {
	case EOF:
	    return (ostgetc());
	case '\010':
	    if (linelen > 0) {
		linelen--;
		while (x > linepos[linelen])
		    scrdelete();
	    }
	    break;
	default:
	    if (linelen < LINEMAX) {
	        linebuf[linelen] = ch;
		linepos[linelen] = x;
		linelen++;
	    }
	    scrputc(ch);
	    break;
	}
    linebuf[linelen++] = '\n';
    scrputc('\r'); scrputc('\n');
    if (tfp)
	for (i = 0; i < linelen; ++i)
	    osaputc(linebuf[i],tfp);
    lineptr = linebuf; linelen--;
    return (*lineptr++);
}

int ostputc(ch)
  int ch;
{
    if (ch == '\n')
	scrputc('\r');
    scrputc(ch);
    if (tfp)
	osaputc(ch,tfp);
    return (1);
}

osflush()
{
    lineptr = linebuf;
    linelen = 0;
}

oscheck()
{
    DoEvent();
}


=========================== osdefs.h =====================================

extern LVAL xptsize(),
	    xhidepen(),xshowpen(),xgetpen(),xpensize(),xpenmode(),
            xpenpat(),xpennormal(),xmoveto(),xmove(),xlineto(),xline(),
	    xshowgraphics(),xhidegraphics(),xcleargraphics(),
	    xtool(),xtool16(),xtool32(),xnewhandle(),xnewptr(),
	    xhiword(),xloword(),xrdnohang();

=========================== osptrs.h =====================================

{	"HIDEPEN",			S, xhidepen		}, /* 300 */
{	"SHOWPEN",			S, xshowpen		}, /* 301 */
{	"GETPEN",			S, xgetpen		}, /* 302 */
{	"PENSIZE",			S, xpensize		}, /* 303 */
{	"PENMODE",			S, xpenmode		}, /* 304 */
{	"PENPAT",			S, xpenpat		}, /* 305 */
{	"PENNORMAL",			S, xpennormal		}, /* 306 */
{	"MOVETO",			S, xmoveto		}, /* 307 */
{	"MOVE",				S, xmove		}, /* 308 */
{	"LINETO",			S, xlineto		}, /* 309 */
{	"LINE",				S, xline		}, /* 310 */
{	"SHOW-GRAPHICS",		S, xshowgraphics	}, /* 311 */
{	"HIDE-GRAPHICS",		S, xhidegraphics	}, /* 312 */
{	"CLEAR-GRAPHICS",		S, xcleargraphics	}, /* 313 */
{	"TOOLBOX",			S, xtool		}, /* 314 */
{	"TOOLBOX-16",			S, xtool16		}, /* 315 */
{	"TOOLBOX-32",			S, xtool32		}, /* 316 */
{	"NEWHANDLE",			S, xnewhandle		}, /* 317 */
{	"NEWPTR",			S, xnewptr		}, /* 318 */
{	"HIWORD",			S, xhiword		}, /* 319 */
{	"LOWORD",			S, xloword		}, /* 320 */
{	"READ-CHAR-NO-HANG",		S, xrdnohang		}, /* 321 */
{	"COMMAND-POINT-SIZE",		S, xptsize		}, /* 322 */


======================== Xlisp.Rsrc ==========================================

XLisp.Rsrc

TYPE WIND
  ,128
XLISP version 2.0
41 4 339 508
InVisible GoAway
0
0

TYPE WIND
  ,129
Graphics Window
22 4 254 508
InVisible NoGoAway
2
0

TYPE DLOG
  ,129
About XLISP
50 100 290 395
Visible NoGoAway
3
0
129

TYPE DITL
  ,129
9

staticText
20 20 40 275
XLISP v2.0, February 6, 1988

staticText
40 20 60 275
Copyright (c) 1988, by David Betz

staticText
60 20 80 275
All Rights Reserved

staticText
90 20 110 275
Author contact information:

staticText
110 40 130 275
David Betz

staticText
130 40 150 275
127 Taylor Road

staticText
150 40 170 275
Peterborough, NH  03458

staticText
170 40 190 275
(603) 924-6936

staticText
200 20 220 275
Portions Copyright Think Technologies

TYPE MENU
  ,1
\14
About XLISP
(-

TYPE MENU
  ,256
File
Load.../L
Load Noisily.../N
(-
Quit/Q

TYPE MENU
  ,257
Edit
Undo/Z
(-
Cut/X
Copy/C
Paste/V
Clear

TYPE MENU
  ,258
Control
Break/B
Continue/P
Clean Up Error/G
Cancel Input/U
Top Level/T
(-
Split Screen/S


======================== Alles ist gemacht  ==================================


-- 
Eric F. Johnson, Boulware Technologies, Inc. 
415 W. Travelers Trail, Burnsville, MN 55337 USA.  Phone: +1 612-894-0313. 
erc@pai.mn.org    - or -   bungia!pai!erc
(We have a very dumb mailer, so please send a bang-!-style return address.)