/* Mode: C; Tab-Width: 4.; */
/*                                                                       */
/*                                                                       */
/*                      RESTRICTED RIGHTS LEGEND                         */
/*                                                                       */
/* Use, duplication, or disclosure by the Government is subject to       */
/* restrictions as set forth in subdivision (c)(1)(ii) of the Rights in  */
/* Technical Data and Computer Software clause at 252.227-7013.          */
/*                                                                       */
/*                    TEXAS INSTRUMENTS INCORPORATED.                    */
/*                            P.O. BOX 149149                            */
/*                         AUSTIN, TEXAS 78714-9149                      */
/*                              MS 2151                                  */
/*                                                                       */
/*  Copyright (C) 1987,1988,1989,1990 Texas Instruments Incorporated.    */
/*  All rights reserved.                                                 */
/*                                                                       */

#include "types.h"
#include "quickdraw.h"
#include "toolutils.h"
#include "textedit.h"
#include "menus.h"
#include "events.h"
#include <osevents.h>
#include "controls.h"
#include "windows.h"
#include "dialogs.h"
#include "fonts.h"
#include <memory.h> /* needed for NewPtr - clm 08/30/89 */
#include <osutils.h> /* needed for EqualString - clm 09/01/89 */

/* #define GGGDEBUG	1 */

#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))

#define FALSE		0
#define TRUE		1

#define NUMLINES	550

WindowPtr gDebugWindowPtr = NULL ;

Boolean debugFlag = FALSE ;

Boolean gWrToWindow ;			/* enable writes to window */
Boolean gWrToFile ;			/* enable writes to file */


int WWNew(Rect *, char *, Boolean, Boolean, int, int) ;
int WWForceOutput(WrForceOptions, WrForceOptions) ;
OSErr WWRedirect(int, char *) ;
char WWReadch() ;
pascal long WWReadLn(Ptr, int) ; 
pascal void WWAddText(Ptr, int) ;

int WWActivateEvent(int);
int WWMouseDown(int, Point, int);
int WWUpdateEvent() ;
int WWScroll(int);

long WWFirstLGlob() ;

long WWLastLGlob() ;
long WWFirstGlob() ;
long WWLastGlob() ;

#define kWWHMargin	5
#define	kWWVMargin	11

#define	_CODEV		1		/* console device number */

typedef struct gLineCtrlStruct		/* Text array control structure allocated in the heap */
	{
	char 	*gText ;				/* Pointer to entire array of text lines */
	char 	*gLine[NUMLINES] ;		/* Pointers to individual text lines */
	short 	gLineLen[NUMLINES] ;	/* Lengths of individual text lines */
} gLineCtrlStruct ;

gLineCtrlStruct		*gLineCtrl ;	/* Pointer to heap structure controlling text array */

typedef struct {
    Boolean toWindow ;
    Boolean toFile ;
} ForceState ;

typedef char *IEFilePath ;
typedef IEFilePath *IEFilePathPtr ;

typedef long IEFRefNum ;


short gLines;			/* number of lines saved */
short gPerLine;			/* number of characters per line */
long gTotal ;			/* number of characters in all lines together */

Point gScroll ;			/* line at upper left corner */
short gBase ;

Rect gViewRect ;		/* Portion of window actually useable */

short gMaxWindowWidth ;
short gMaxWindowHeight ;
short gHeight;			/* font height */
short gLnAscent;			/* font ascent */
short gLnDescent ;
short gWidMax;			/* font char width (must be monospaced) */
ControlHandle gSBars[2];	/* the window scroll bars */
Point gScrollOffset;		/* the position to which we are scrolled */
Point gViewSize;		/* total view size */
Point gEndOfText;		/* the pen position after drawing all the lines */
Point gCursor ;			/* text cursor position */

Rect gStdDrag;
Rect gStdSize;
short gOrthogonal[2] ;
WindowRecord gWRec;
RgnHandle gARgn;

Boolean	gGotRefnum;
short gRefnum;			/* refnum for redirect output */
short gVRefNum;			/* likewise, vrefnum */

RgnHandle GetSaveVisRgn() ;


RgnHandle
GetSaveVisRgn()
{
    return(*(RgnHandle *)0x9f2) ;
}

/* $S WWSeg */
LongerSide(r)
register Rect *r ;
{
    if ((r->bottom - r->top) >= (r->left - r->right))
	return(0) ;
    return(1) ;
}

/* $S WWSeg */
WindowFocus()
{
    SetPort(gDebugWindowPtr);
    SetOrigin(0, 0);
    ClipRect(&qd.thePort->portRect);
}

CalcViewRect(r)
register Rect *r ;
{
    *r = gDebugWindowPtr->portRect ;
    r->right -= 15 ;
    r->bottom = r->top + ((r->bottom - r->top - 15) / gHeight) * gHeight + gLnDescent ;
}

/* $S WWSeg */
ContentFocus()
{
    Rect r ;

    SetPort(gDebugWindowPtr);
    SetOrigin(gScroll.h * gWidMax - kWWHMargin, gScroll.v * gHeight - kWWVMargin);
    CalcViewRect(&r) ;
    ClipRect(&r);
}

/* #define __SEG__ WWInit */
WWInit()
{
    GrafPtr savePort ;
    Rect drawRect ;
    FontInfo fInfo ;
    short i ;
    short vhs ;

    gGotRefnum = FALSE ;

#ifdef MAC
    WWInstall() ;
#endif

    gWrToWindow = TRUE ;

    GetPort(&savePort) ;

    gMaxWindowWidth = (qd.screenBits.bounds.right - qd.screenBits.bounds.left) - 8 ;
    gMaxWindowHeight = (qd.screenBits.bounds.bottom - qd.screenBits.bounds.top) - 20 -
				 20 - 15 - 1 ;
    drawRect = qd.screenBits.bounds ;
    drawRect.top += 40 ;
    InsetRect(&drawRect, 4, 4) ;
    if (qd.screenBits.bounds.right - qd.screenBits.bounds.left > 800)
	drawRect.right -= 80 ;
                               /* clm 10/04/89 - cast arg gwRec to Ptr */
    gDebugWindowPtr = NewWindow((Ptr)&gWRec, &drawRect, "\pmicroExplorer Cold Load Stream",
		TRUE, zoomDocProc, (WindowPtr)-1, TRUE, 0);

	    /* this is suggested in Inside Macintosh */
    SetRect(&gStdDrag, qd.screenBits.bounds.left + 4, qd.screenBits.bounds.top + 24,
    		qd.screenBits.bounds.right - 4,
		qd.screenBits.bounds.bottom - 4);
	    /*arbitrary Min size; Max size is screen */
    gStdSize = drawRect ;

    /* SetRect(&gStdSize, 20, 20, qd.screenBits.bounds.right,
		qd.screenBits.bounds.bottom - 20); */

    gARgn = NewRgn();

    SetPort(gDebugWindowPtr);
    SetOrigin(-kWWHMargin, -kWWVMargin) ;		/* border around window */
    TextFont(monaco);
    if (qd.screenBits.bounds.bottom - qd.screenBits.bounds.top > 480)
	TextSize(12) ;
    else
	TextSize(9) ;
    TextMode(srcCopy) ;
    GetFontInfo(&fInfo);

    gHeight = fInfo.ascent + fInfo.descent + fInfo.leading;
    gLnAscent = fInfo.ascent;
    gWidMax = fInfo.widMax;
    gLnDescent = fInfo.descent ;
    gLines = NUMLINES;
    CalcViewRect(&gViewRect) ;
    gPerLine = (gViewRect.right - gViewRect.left) / gWidMax ;
    gTotal = (long)gLines * (long)gPerLine;

	gLineCtrl = (gLineCtrlStruct *)NewPtr(sizeof(gLineCtrlStruct)) ;
	if (gLineCtrl == NULL) {
		printf ("Not enough memory to allocate the Debug Window's Line Control Array: \
%d bytes needed.\n", sizeof(gLineCtrlStruct)) ;
		return (FALSE) ;
	}
	
    gLineCtrl->gText = (char *)NewPtr(gTotal) ;
    if (gLineCtrl->gText == NULL) {
		printf("Not enough memory to allocate the Debug Window's Line Array: %d * %d\n",
					gLines, gPerLine);
		return(FALSE) ;
    }

    memset(gLineCtrl->gText, gTotal, ' ') ;
    for (i=0; i < gLines; i++) {
		gLineCtrl->gLine[i] = &gLineCtrl->gText[(long)i*(long)gPerLine] ;
		gLineCtrl->gLineLen[i] = 0 ;
    }

    gCursor.h = 0 ;
    gCursor.v = gBase = gLines - (gViewRect.bottom - gViewRect.top) / gHeight ;
    gScroll.h = 0 ;
    gScroll.v = gBase ;
    

    gOrthogonal[0] = 1;
    gOrthogonal[1] = 0;


	    /* Scroll Bars */
    for (vhs = 0; vhs <= 1; vhs++)
	gSBars[vhs] = newcontrol(gDebugWindowPtr, &gDebugWindowPtr->portRect, "",
				 FALSE, 0, 0, 1, scrollBarProc, 0);

	/* put the scroll bars in the right place */

    SetCtlMax(gSBars[0], gBase /* gLines */) ;
    SetCtlMax(gSBars[1], gPerLine) ;
    SetCtlValue(gSBars[0], gScroll.v) ;
    WWGrown() ;

	/* force an update */
    WWUpdateEvent() ;

	/* scroll to the end, in case there is info that needs to be displayed */

    WWDoScrolling() ;

#ifdef GGGDEBUG
    printw("widmax = %d, height = %d\n", gWidMax, gHeight) ;
    printw("gLines = %d  gPerLine = %d\n", gLines, gPerLine) ;
#endif

    SetPort(savePort);
    return(TRUE) ;
}


WWforcetotop()
{
    extern WindowPtr gDebugWindowPtr ;

    if (FrontWindow() != gDebugWindowPtr) {
		ShowWindow(gDebugWindowPtr) ;
	    UpdateSavedBitMapsFromScreen () ;
		SelectWindow(gDebugWindowPtr) ;
		ReestablishToScreenDrawing() ;
    }
}

/* #define __SEG__ WWSeg */
WWActivateEvent(modifiers)
short modifiers ;
{
 /*   short vhs ;			*/
    ControlHandle anSBar ;
    GrafPtr savePort ;

    GetPort(&savePort) ;

    WindowFocus() ;

/*
    for (vhs = 0 ; vhs <= 1 ; vhs++) {
	anSBar = gSBars[vhs];
	if (modifiers & activeFlag)
	    ShowControl(anSBar) ;
	else
	    HideControl(anSBar) ;
    }
*/

	anSBar = ((WindowPeek)gDebugWindowPtr)->controlList ;	/* get the first one */
	while (anSBar != NULL) {
	    if (modifiers & activeFlag)
			ShowControl(anSBar) ;
		else
			HideControl(anSBar) ;
	    anSBar = (*anSBar)->nextControl ;
	}

    DrawGrowIcon(gDebugWindowPtr) ;

    SetPort(savePort) ;
}

/* $S WWSeg */
pascal void WWAddText(textBuf, byteCount)
Ptr textBuf ;
short byteCount ;
{
    Boolean gotEOL ;
    QDByte b ;
    Ptr startPtr ;
    short startCount ;
    GrafPtr savePort ;
    Boolean deleted ;
    Rect r ;
    short lpos ;

    if (gWrToFile && gGotRefnum) {
	if (write(gRefnum, textBuf, (long)byteCount) != byteCount) {
/*	if (FSWrite(gRefnum, (long)byteCount, textBuf) != noErr) { */
		/* report error ?? */
	}
    }

    if (gWrToWindow) {
	if (gDebugWindowPtr != NULL)
	    GetPort(&savePort) ;

	deleted = FALSE ;
	while (byteCount > 0) {
	    gotEOL = 0 ;
	    startPtr = textBuf ;
	    startCount = byteCount ;
	    lpos = gCursor.h ;

	    while ((byteCount > 0) && (gCursor.h < gPerLine) && (!gotEOL)) {
		b = *(QDPtr)textBuf ;
		byteCount-- ;
		textBuf++ ;
		if (b == 0x0d || b == 0x0a)
		    gotEOL = 1 ;
		else if (b != 0x08) {		/* backspace */
		    gLineCtrl->gLine[gCursor.v][gCursor.h++] = (char)b ;
		} else if (gCursor.h > 0) {		/* Backspace */
		    SetRect(&r, gCursor.h*gWidMax - gWidMax,
		    		gCursor.v*gHeight - gLnAscent,
				gCursor.h*gWidMax,
				gCursor.v*gHeight + gHeight - gLnAscent) ;
		    gEndOfText.h -= gWidMax ;
		    if (gDebugWindowPtr != NULL) {
			ContentFocus() ;
			EraseRect(&r) ;
		    }
		    gCursor.h-- ;
		    deleted = TRUE ;
		} else
		    deleted = TRUE ;
	    }

	    if (!deleted && (gDebugWindowPtr != NULL)) {
		ContentFocus() ;
		WWSetPen(lpos, gCursor.v) ;
		DrawText((QDPtr)startPtr, 0, startCount - byteCount - gotEOL) ;
	    }

	    if (gCursor.h >= gPerLine || gotEOL) {
		    /* remember # characters in this line */
		gLineCtrl->gLineLen[gCursor.v] = max(gLineCtrl->gLineLen[gCursor.v], gCursor.h) ;
		WWNewLine(TRUE) ;
		if (byteCount > 0 && !gotEOL) {
		    gLineCtrl->gLine[gCursor.v-1][gPerLine-1] = '\311' ;
		    gCursor.h = 1 ;
		}
	    }
	}

	gLineCtrl->gLineLen[gCursor.v] = max(gLineCtrl->gLineLen[gCursor.v], gCursor.h) ;

	if (gDebugWindowPtr != NULL)
	    SetPort(savePort) ;
    }
}


WWDoScrolling()
{
    Point newOffset ;
    Point delta ;
    Rect r ;

    newOffset.v = GetCtlValue(gSBars[0]);
    delta.v = gScroll.v - newOffset.v;
    newOffset.h = GetCtlValue(gSBars[1]);
    delta.h = gScroll.h - newOffset.h;

    if (delta.h != 0 || delta.v != 0) {
	ContentFocus() ;

	if (delta.h == 0) {
	    SetRect(&r, 0, -gLnAscent, (qd.thePort->portRect.right - qd.thePort->portRect.left),
								gLines * gHeight - gLnAscent) ;
	    ScrollRect(&r, 0, delta.v*gHeight, gARgn);
	} else
	    ScrollRect(&qd.thePort->portRect, delta.h*gWidMax, delta.v*gHeight, gARgn);
	gScroll = newOffset ;

	InvalRgn(gARgn) ;

	WWUpdateEvent() ;
    }
}

WWSetPos(x, y)
short x, y ;
{
    gCursor.h = x / gWidMax ;
    gCursor.v = gBase + y / gHeight ;
    if (gCursor.v > gLines - 1)
	gCursor.v = gLines - 1 ;
}

WWGetPos(x,y)
short *x,*y;
{
    *x = gCursor.h * gWidMax;
    *y = (gCursor.v - gBase) * gHeight;
}

WWSetPen(x, y)
short x, y;
{
    MoveTo(x * gWidMax, y * gHeight /* + gLnAscent */) ;
}

WWEreol()
{
    Rect r ;
    short i ;
    GrafPtr savePort ;
    short x, y ;

    GetPort(&savePort) ;
    ContentFocus() ;
    x = gCursor.h * gWidMax ;
    y = gCursor.v * gHeight ;
    r.top = y - gLnAscent ;
    r.left = x ;
    r.bottom = y + gLnDescent ;
    r.right = gDebugWindowPtr->portRect.right - 15 ;
    EraseRect(&r) ;

    for (i=gCursor.h; i < gPerLine; i++)
	gLineCtrl->gLine[gCursor.v][i] = ' ' ;
    gLineCtrl->gLineLen[gCursor.v] = gCursor.h ;

    SetPort(savePort) ;
}

WWClrScr()
{
    Rect r ;
    GrafPtr savePort ;
    short dispLines ;
    short i ;

    GetPort(&savePort) ;
    ContentFocus() ;
    r = gDebugWindowPtr->portRect ;
    r.bottom -= 15 ;
    r.right -= 15 ;
    ClipRect(&r) ;
    EraseRect(&r) ;

	/* the boundary conditions on the wrap were too hard, so I wimped out */
    dispLines = (gViewRect.bottom - gViewRect.top) / gHeight ;
    for (i=0; i<dispLines; i++) {
	WWNewLine(FALSE) ;
    }
    i = GetCtlValue(gSBars[0]) ;
    SetCtlValue(gSBars[0], i + dispLines) ;
    SetPort(savePort) ;
}

WWCursor(state)
short state ;
{
#pragma unused(state)

    GrafPtr savePort ;
    Rect r ;
    PenState pen ;

    GetPort(&savePort) ;
    ContentFocus() ;

    GetPenState(&pen) ;
    PenMode(patXor) ;
    PenPat(qd.black) ;

    SetRect(&r, gCursor.h * gWidMax, gCursor.v * gHeight - gLnAscent,
    			gCursor.h * gWidMax + gWidMax,
			gCursor.v * gHeight + gHeight - gLnAscent) ;

    PaintRect(&r) ;

    PenMode(pen.pnMode) ;
    PenPat(pen.pnPat) ;

    SetPort(savePort) ;
}

WWScreenInfo(info)
long *info ;
{
    info[0] = (gViewRect.right - gViewRect.left) - (gViewRect.right - gViewRect.left) % gWidMax;
    info[1] = (gViewRect.bottom - gViewRect.top) - (gViewRect.bottom - gViewRect.top) % gHeight;
    info[2] = gWidMax ;
    info[3] = gHeight ;
#ifdef GGGDEBUG
    printw("ScreenInfo = (%d, %d)   widmax = %d, height = %d\n", info[0], info[1], info[2],
		info[3]) ;
#endif
}


/* $S WWSeg */
WWDraw()
{
    short i ;
    short y ;
    short start ;
    Rect r ;
    short count ;

    CalcViewRect(&r) ;
    count = (r.bottom - r.top) / gHeight ;
    start = gScroll.v ;
    count = (start + count > gLines) ? gLines - start : start + count ;
    y = start * gHeight ;
    for (i = start; i < count; i++) {
	MoveTo(0, y);

	if (gLineCtrl->gLineLen[i]) {
	    DrawText(gLineCtrl->gLine[i], 0, gLineCtrl->gLineLen[i]);
	}

	y += gHeight;
    }
}


WWGrown()
{
    Rect r ;
    short vhs ;
    ControlHandle anSBar ;
    short newMax ;
    GrafPtr savePort ;

    GetPort(&savePort);

    WindowFocus();
    r.top = r.left = 0;
    r.bottom = r.right = 0 ;
    ClipRect(&r);

    for (vhs = 0; vhs <= 1; vhs++) {
	anSBar = gSBars[vhs];

	r = qd.thePort->portRect;

	if (vhs)
	    newMax = gPerLine - (r.right - r.left - 15) / gWidMax ;
	else
	    newMax = gLines - (r.bottom - r.top - 15) / gHeight ;

	    /* Calculate new position of scroll bar */
	if (vhs == 0) {			/* vertical */
	    r.top-- ;
	    r.left = r.right - 15 ;
	    r.bottom -= 14 ;
	    r.right = r.left + 16 ;
	} else {
	    r.left-- ;
	    r.top = r.bottom - 15 ;
	    r.right -= 14 ;
	    r.bottom = r.top + 16 ;
	}
	
	    /* Move the scroll bar */
	MoveControl(anSBar, r.left, r.top);
	SizeControl(anSBar, r.right-r.left, r.bottom-r.top);

	if (newMax < 0)
		newMax = 0;
	SetCtlMax(anSBar, newMax);
    }

    WWInvalGrowBox() ;

    WWDoScrolling() ;	/* in case we are showing too much white space */

    SetPort(savePort);
}


/* $S WWSeg */
WWInvalGrowBox()
{
    Rect r ;

    r.bottom = qd.thePort->portRect.bottom ;
    r.right = qd.thePort->portRect.right ;
    r.top = r.bottom - 15;
    r.left = r.right - 15;
    InvalRect(&r);
}

/* $S WWSeg */
WWMouseDown(where, pt, modifiers)
int where ;
Point pt ;
int modifiers ;
{
#pragma unused(modifiers)
#ifdef MAC
    pascal void WWTrackScroll() ;
#else
    int WWTrackScroll() ;
#endif
    short partCode ;
    ControlHandle whichControl ;
    Point oldSize ;
    GrafPtr savePort ;
    long newSize ;
    short newWidth, newHeight ;

    GetPort(&savePort);

    switch (where) {
	case inDrag:
	    dragwindow(gDebugWindowPtr, &pt, &gStdDrag);
	    break ;

	case inGrow:
	    WindowFocus() ;
	    oldSize.h = gDebugWindowPtr->portRect.right - gDebugWindowPtr->portRect.left;
	    oldSize.v = gDebugWindowPtr->portRect.bottom - gDebugWindowPtr->portRect.top;

	    newSize = growwindow(gDebugWindowPtr, &pt, &gStdSize);
	    newWidth = LoWord(newSize) ;
	    newHeight = HiWord(newSize) ;
	    if (newSize != 0 && (newWidth != oldSize.h || newHeight != oldSize.v)) {
		WWInvalGrowBox() ;
		if (newWidth < 16)
		    newWidth = 16 ;
		if (newHeight < 16)
		    newHeight = 16 ;
		SizeWindow(gDebugWindowPtr, newWidth, newHeight, TRUE);
		WWGrown() ;
	    }
	    break ;

	case inGoAway:
		if (trackgoaway(gDebugWindowPtr, &pt))
		    HideWindow(gDebugWindowPtr);
		break ;

	case inContent:
		if (gDebugWindowPtr == FrontWindow()) {
		    WindowFocus() ;
		    GlobalToLocal(&pt);
		    partCode = findcontrol(&pt, gDebugWindowPtr, &whichControl);
		    switch (partCode) {
			case inUpButton:
			case inDownButton:
			case inPageUp:
			case inPageDown:
			    partCode = trackcontrol(whichControl,&pt,(ProcPtr)WWTrackScroll);
			    break ;
			case inThumb:
			    partCode = trackcontrol(whichControl, &pt, NULL);
			    WWDoScrolling() ;
			    break ;

			default:
			    break ;
		    }
		} else
		    SelectWindow(gDebugWindowPtr);
		break ;
	case inZoomIn:
	case inZoomOut:
	    WindowFocus() ;
	    if (trackbox(gDebugWindowPtr,&pt,where)) {
		SetPort(gDebugWindowPtr);
		ZoomWindow(gDebugWindowPtr, where, TRUE);
		WWGrown() ;
	    }
	    break ;
	}

    SetPort(savePort);
}

/* $S WWSeg */
WWNewLine(doscroll)
int doscroll ;
{
    GrafPtr savePort ;
    short i ;
    Rect r ;
    char *tc ;
    short tl ;

    GetPort(&savePort);

#ifdef TRASH
	Point pt ;
	
    SetPt(&pt, kWWHMargin, gEndOfText.v);
    WWShowPoint(pt);
#endif

    gCursor.h = 0 ;
    gCursor.v++ ;

    ContentFocus() ;
    CalcViewRect(&r) ;
    if (gCursor.v > gLines - 1) {
	gCursor.v = gLines - 1 ;
	tc = gLineCtrl->gLine[0] ;
	tl = gLineCtrl->gLineLen[0] ;
	for (i=0; i < gLines - 1; i++) {
	    gLineCtrl->gLine[i] = gLineCtrl->gLine[i + 1] ;
	    gLineCtrl->gLineLen[i] = gLineCtrl->gLineLen[i+1] ;
	}
	gLineCtrl->gLineLen[gLines-1] = 0 ;
	gLineCtrl->gLine[gLines-1] = tc ;

	if (doscroll) {
	    SetRect(&r, 0, -gLnAscent, (r.right - r.left), gLines * gHeight - gLnAscent) ;
	    ScrollRect(&r, 0, -gHeight, gARgn) ;
	    InvalRgn(gARgn) ;
	    WWUpdateEvent() ;
	}
    }

    SetPort(savePort);
}

#ifdef TRASH
WWShowPoint(pt)
Point pt ;
{
    Point mintoSee ;
    short deltaCd ;

    if (gDebugWindowPtr != NULL) {

	WindowFocus() ;
	
	SetPt(&mintoSee, 0 /*50*/, gHeight);
	
	    /* the following code is actually better than writing a loop with VHSelect */
	deltaCd = pt.v + mintoSee.v - (qd.thePort->portRect.bottom-15+gScrollOffset.v);
	if (deltaCd <= 0 ) {
	    deltaCd = pt.v - mintoSee.v - (qd.thePort->portRect.top + gScrollOffset.v);
	    if (deltaCd > 0)
		deltaCd = 0;
	}

	SetCtlValue(gSBars[0], GetCtlValue(gSBars[0]) + deltaCd);
	
	deltaCd = pt.h + mintoSee.h - (qd.thePort->portRect.right-15+gScrollOffset.h);
	if (deltaCd <= 0) {
	    deltaCd = pt.h - mintoSee.h - (qd.thePort->portRect.left + gScrollOffset.h);
	    if (deltaCd > 0)
		deltaCd = 0;
	}
	SetCtlValue(gSBars[1], GetCtlValue(gSBars[1]) + deltaCd);
	
	WWDoScrolling() ;
    }
}
#endif

/*
    This is the assembler wrappers for the trackScroll routine.  This routine
is called by the toolbox while the scrollbar is being tracked.  It converts
its parameters into C-style and calls trackScroll.
*/

#ifndef MAC
asm("WWTrackScroll:			");
asm("        mov.w   4(%a7),-(%a7)	");
asm("        clr.w   -(%a7)		");
asm("        mov.l   10(%a7),-(%a7)	");
asm("        jsr     CWWTrackScroll	");
asm("        mov.l   8(%a7),%a1		");
asm("        add.l   &18,%a7		");
asm("        jmp     (%a1)		");
#endif

/* $S WWSeg */
#ifndef MAC
CWWTrackScroll(aControl, partCode)
#else
pascal void WWTrackScroll(aControl, partCode)
#endif
ControlHandle aControl ;
short partCode ;
{
    Boolean up ;
    short ctlValue ;
    short vhs ;
    Rect r ;
    short delta ;


    if (partCode != 0) {
	up = (partCode == inUpButton) || (partCode == inPageUp);
	ctlValue = GetCtlValue(aControl);

	   /* avoid flicker in setting thumb, IF user tries to scroll past end */
	if ((up && (ctlValue > GetCtlMin(aControl))) ||
		   (! up && (ctlValue < GetCtlMax(aControl)))) {
	    r = (*aControl)->contrlRect;   /* heap may compact when we call LongerSide */
	    vhs = LongerSide(&r);	   /* this tells us which way we are scrolling */

	    if ((partCode == inPageUp) || (partCode == inPageDown)) {
		if (vhs == 0) {	/* vertical */
		   delta = (gDebugWindowPtr->portRect.bottom -
					 gDebugWindowPtr->portRect.top - gHeight) / gHeight ;
		} else
		   delta = (gDebugWindowPtr->portRect.right -
					 gDebugWindowPtr->portRect.left - gWidMax) / gWidMax ;
	    } else
		delta = 1 ; 	/* gHeight; */
	    if (up)
		delta = -delta;

	    SetCtlValue(aControl, ctlValue + delta);
	    WWDoScrolling() ;

	    WindowFocus() ;
	}
    }
}

/* $S WWSeg */
WWUpdateEvent()
{
    GrafPtr savePort ;
    RgnHandle saveSaveVisRgn ;
    RgnHandle saveVisRgn ;

    GetPort(&savePort);

    saveSaveVisRgn = NewRgn();
    saveVisRgn = GetSaveVisRgn();

    CopyRgn(saveVisRgn, saveSaveVisRgn);

    BeginUpdate(gDebugWindowPtr);

    WindowFocus();

    EraseRect(&qd.thePort->portRect);

    DrawGrowIcon(gDebugWindowPtr);
    DrawControls(gDebugWindowPtr);

    ContentFocus() ;
    WWDraw() ;

    EndUpdate(gDebugWindowPtr);

    CopyRgn(saveSaveVisRgn, saveVisRgn);
    DisposeRgn(saveSaveVisRgn);

    SetPort(savePort);
}

WWReadCh(wait)
int wait ;
{
    GrafPtr 	savePort ;
    int 		ch ;
    EventRecord anEvent ;
    Rect		 r ;
    int 		status ;

	if (FrontWindow() != gDebugWindowPtr)
		return(0) ;
   
    GetPort(&savePort) ;

    ContentFocus() ;

    SetRect(&r, gEndOfText.h, gEndOfText.v - gLnAscent, gEndOfText.h + gWidMax,
			gEndOfText.v + gHeight - gLnAscent) ;

    FillRect(&r, qd.black) ;

    if (wait) {
		while (!GetOSEvent(keyDownMask | autoKeyMask, &anEvent))
	    	continue ;
		status = TRUE ;
    } else
		status = GetOSEvent(keyDownMask | autoKeyMask, &anEvent) ;

    EraseRect(&r) ;

#ifdef TRASH
    if (wait)
		ch = anEvent.message & charCodeMask ;
    else {
#endif
	if (status) {
	    ch = anEvent.message & (charCodeMask | keyCodeMask) | 0x8000 ;
	} else
	    ch = 0 ;
#ifdef TRASH
    }
#endif

    SetPort(savePort) ;
    return(ch) ;
}

pascal long WWReadLn(buffer, byteCount)
char *buffer ;
int byteCount ;
{
    typedef char PA1000[1000] ;
    typedef PA1000 *StrPtr ;
    char ch ;
    int len ;

    len = 0 ;
    do {
	ch = WWReadCh(TRUE) ;
	if (ch != '\b') {
	    WWAddText(&ch, 1) ;
	    (*(StrPtr)buffer)[len++] = ch ;
	} else if (len > 0) {
	    WWAddText(&ch, 1) ;
	    (*(StrPtr)buffer)[--len] = ' ' ;
	}
    } while (ch != '\r' && len != byteCount) ;

    return(len) ;
}

/* 9/1/89 clm - adding these functions back into the system, just to see what dies. 
    pulling them back out.  
	 Link problem occurring: EqualString is being referenced by wwFAccess but it is
	 at this point undefined, as is wwFAccess.  How these are being touched on is a 
	 mystery to me.  including osutils.h for EqualString; this is a grasp.
wwFAccess(name, opcode, arg)
char *name ;
int opcode ;
int arg ;
{
    return(0) ;
}


wwClose(fdesc)
int fdesc ;
{
    return(0) ;
}

wwRead(fdesc, bufp, count)
int fdesc ;
char *bufp ;
int count ;
{
    return(WWReadLn(bufp, count)) ;

}

wwWrite(fdesc, bufp, count)
int fdesc ;
char *bufp ;
int count ;
{
    typedef char PA1000[1000] ;
    typedef PA1000 *StrPtr ;

    WWAddText(*(StrPtr)bufp, count) ;
    return(count) ;
}

wwIoctl(fdesc, request, arg)
int fdesc ;
int request ;
int arg ;
{
     return(0) ;
}
*/

/* 08/30/89 clm - since the functions have been commented out, why not delete the following? */
extern WWFACCESS(), WWCLOSE(), WWREAD(), WWWRITE(), WWIOCTL() ; 
extern pascal void xxSetVBuf() ;

WWInstall()
{
    extern Ptr OUTPUT ;
    long slot ;

    slot = _addDevHandler(_CODEV, 0, WWFACCESS, WWCLOSE, WWREAD, WWWRITE, WWIOCTL); 
	xxSetVBuf() ;
}


printw(cs, a0, a1, a2, a3, a4, a5, a6)
char *cs ; 
int a0, a1, a2, a3, a4, a5, a6 ;
{
/*    char buff[512] ;	*/				/* 11/21/89 sbw */		

    debugPrint(6, cs, a0, a1, a2, a3, a4, a5, a6) ;

/*
    sprintf(buff, cs, a0, a1, a2, a3, a4, a5, a6) ;
    WWAddText(buff, (short)strlen(buff)) ;
*/
}

bigprintw(cs, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)
char *cs ;
int a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 ;
{
    debugPrint (16, cs, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) ;
}


printrect(label, rect)
char *label ;
register Rect *rect ;
{
    debugPrint(5, " %s: %d %d %d %d\n", label, rect->left, rect->top, rect->right,
				 rect->bottom) ; 
}
