[mod.mac.sources] TransDisplay.pit.Hqx Human Readable Version

dubois@uwmacc.UUCP (Paul DuBois) (11/25/86)

#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	TransDisplay/TransDisplay.c
#	TransDisplay/TransDisplay.h
#
#	MODERATOR'S NOTE:  Tab-width is 4
#
sed 's/^X//' << 'SHAR_EOF' > TransDisplay/TransDisplay.c
X/*
X	TransDisplay version 1.0 - TransSkel plug-in module supporting
X	an arbitrary number of generic display windows with memory.
X
X	TransSkel and TransDisplay are public domain, and are written by:
X
X			Paul DuBois
X			Wisconsin Regional Primate Research Center
X			1220 Capital Court
X			Madison WI  53706  USA
X
X	UUCP:	{allegra,ihnp4,seismo}!uwvax!uwmacc!dubois
X	ARPA:	dubois@unix.macc.wisc.edu
X			dubois@rhesus.primate.wisc.edu
X
X	This version of TransDisplay written for LightspeedC.  LightspeedC
X	is a trademark of:
X			THINK Technologies, Inc
X			420 Bedford Street  Suite 350
X			Lexington, MA  02173  USA
X
X  History
X  08/25/86	Genesis.  Beta version.
X  09/15/86	Changed to allow arbitrary number of windows.  Changed
X 			version number to 1.0.
X*/
X
X
X/*
X	The following symbol controls the compile mode.  If it is #define'd,
X	TransDisplay allows only a single display window, and generates
X	less code.  If it is #undef'ed, TransDisplay allows an arbitrary
X	number of display windows, but generates more code.
X*/
X
X# undef	singleDisplay
X
X# include	<ControlMgr.h>	/* includes WindowMgr.h, QuickDraw.h, MacTypes.h */
X# include	<TextEdit.h>
X# include	"TransDisplay.h"
X
X
X/*
X	Display window types, constants, variables.
X*/
X
X
X# define	monaco		4
X
X
X/*
X	Default values for display window characteristics
X*/
X
Xstatic int		d_font = monaco;		/* default font              */
Xstatic int		d_size = 9;				/* default pointsize         */
Xstatic int		d_wrap = 0;				/* default word wrap (on)    */
Xstatic int		d_just = teJustLeft;	/* default justification     */
Xstatic long		d_maxText = 30000L;		/* default max text allowed  */
Xstatic long		d_flushAmt = 25000L;	/* default autoflush amount  */
Xstatic ProcPtr	d_activate = nil;		/* default notification proc */
X
X
X/*
X	Lowest allowable values for autoflush characteristics
X*/
X
X# define	d_loMaxText		(100L)
X# define	d_loFlushAmt	(100L)
X
X
X# ifndef	singleDisplay
X
X/*
X	New(TypeName) returns handle to new object, for any TypeName.
X	If there is insufficient memory, the result is nil.
X*/
X
X# define	New(x)	(x **) NewHandle ((Size) sizeof (x))
X
X
X/*
X	dwList points to a list of structures describing the known display
X	windows.
X
X	curDispWind is the current output window.
X	If curDispWind = nil, output is currently turned off.
X*/
X
X
Xtypedef struct DisplayInfo
X{
X	WindowPtr			dWind;			/* display window         */
X	TEHandle			dTE;			/* window text            */
X	ControlHandle		dScroll;		/* window scroll bar      */
X	ProcPtr				dActivate;		/* notification procedure */
X	long				dMaxText;		/* max text length        */
X	long				dFlushAmt;		/* amount to autoflush    */
X	struct DisplayInfo	**dNext;		/* next window structure  */
X} DisplayInfo, *DIPtr, **DIHandle;
X
X
Xstatic DIHandle		dwList = nil;
X
X# endif
X
X/*
X	Variables pertaining to the display window being operated on
X	(updated, resized, etc.).  This window is not necessarily the
X	same as curDispWind!  These variables are synced to the window
X	with SyncGlobals.
X*/
X
X# ifndef	singleDisplay
Xstatic DIHandle			dispInfo;		/* info structure         */
X# endif
X
Xstatic WindowPtr		dispWind = nil;	/* the window             */
Xstatic TEHandle			dispTE;			/* window text            */
Xstatic ControlHandle	dispScroll;		/* the scroll bar         */
Xstatic ProcPtr			dActivate;		/* notification procedure */
Xstatic long				dMaxText;		/* max text allowed       */
Xstatic long				dFlushAmt;		/* amount to flush        */
X
X
X/*
X	curDispWind is the current output window.
X	If curDispWind = nil, output is turned off.
X*/
X
Xstatic WindowPtr	curDispWind = nil;
X
X
X/* -------------------------------------------------------------------- */
X/*				Miscellaneous Internal (private) Routines				*/
X/* -------------------------------------------------------------------- */
X
X
X/*
X	Draw grow box of dispWind in lower right hand corner
X*/
X
X
Xstatic DrawGrowBox ()
X{
Xregister RgnHandle	oldClip;
XRect				r;
X
X	r = dispWind->portRect;
X	r.left = r.right - 15;		/* draw only in corner */
X	r.top = r.bottom - 15;
X	oldClip = NewRgn ();
X	GetClip (oldClip);
X	ClipRect (&r);
X	DrawGrowIcon (dispWind);
X	SetClip (oldClip);
X	DisposeRgn (oldClip);
X}
X
X
X
X/* -------------------------------------------------------------------- */
X/*			Lowest-level Internal (Private) Display Window Routines		*/
X/* -------------------------------------------------------------------- */
X
X
X# ifndef	singleDisplay
X
X/*
X	Get display window info associated with window.
X	Return nil if window isn't a known display window.
X*/
X
Xstatic DIHandle GetDInfo (theWind)
XWindowPtr	theWind;
X{
Xregister DIHandle	h;
X
X	for (h = dwList; h != nil; h = (**h).dNext)
X	{
X		if ((**h).dWind == theWind)
X			return (h);
X	}
X	return (nil);
X}
X
X# endif
X
X# ifdef	singleDisplay
X# define	SyncGlobals(x)	;	/* make it a nop */
X# else
X
X/*
X	Synchronize globals to a display window.  theWind must be a legal
X	display window, with one exception:  if theWind is nil, the
X	variables are synced to the current port.  That is safe (and
X	correct) because:
X	(i)	 nil is only passed by display window handler procedures,
X		 which are only called by TransSkel for display window
X		 events.
X	(ii) TransSkel always sets the port to the window before
X		 calling the handler proc.
X	Hence, use of the current port under these circumstances
X	always produces a legal display window.
X	
X	SyncGlobals is not used in single display mode, because the
X	globals are all set by SetupDWindow and do not change thereafter.
X*/
X
Xstatic SyncGlobals (theWind)
XWindowPtr	theWind;
X{
Xregister DIPtr	dp;
X
X	if (theWind == nil)					/* use current window */
X		GetPort (&theWind);
X
X	dispWind = theWind;
X	dispInfo = GetDInfo (dispWind);
X	dp = *dispInfo;
X	dispScroll = (*dp).dScroll;
X	dispTE = (*dp).dTE;
X	dActivate = (*dp).dActivate;
X	dMaxText = (*dp).dMaxText;
X	dFlushAmt = (*dp).dFlushAmt;
X}
X
X# endif
X
X
X/*
X	Calculate the dimensions of the editing rectangle for
X	dispWind (which must be set properly and is assumed to be
X	the current port).  (The viewRect and destRect are the
X	same size.)  Assumes the port, text font and text size are all
X	set properly.  The viewRect is sized so that an integral
X	number of lines can be displayed in it, i.e., so that a
X	partial line never shows at the bottom.
X*/
X
Xstatic CalcEditRect (r)
XRect		*r;
X{
XFontInfo		f;
Xregister int	lineHeight;
X
X	GetFontInfo (&f);
X	lineHeight = f.ascent + f.descent + f.leading;
X	*r = dispWind->portRect;
X	r->left += 4;
X	r->right -= 17;			/* leave room for scroll bar + 2 */
X	r->top += 2;
X	r->bottom = r->top + ((r->bottom - r->top - 2) / lineHeight) * lineHeight;
X}
X
X
X/*
X	Calculate the dimensions of the scroll bar rectangle for the
X	window.  Make sure that the edges overlap the window frame and
X	the grow box.
X*/
X
Xstatic CalcScrollRect (r)
XRect		*r;
X{
X	*r = dispWind->portRect;
X	++r->right;
X	--r->top;
X	r->left = r->right - 16;
X	r->bottom -= 14;
X}
X
X
X/*
X	Calculate the number of lines currently scrolled off
X	the top.
X*/
X
Xstatic LinesOffTop ()
X{
Xregister TEPtr	ePtr;
X
X	ePtr = *dispTE;
X	return (((*ePtr).viewRect.top - (*ePtr).destRect.top)
X				/ (*ePtr).lineHeight);
X}
X
X
X/*
X	Highlight the scroll bar properly.  This means that it's not
X	made active if the window itself isn't active, even if
X	there's enough text to fill the window.
X*/
X
Xstatic HiliteScroll ()
X{
X	HiliteControl (dispScroll, dispWind == FrontWindow () &&
X								GetCtlMax (dispScroll) > 0 ? 0 : 255);
X}
X
X
X/*
X    Scroll to the correct position.  lDelta is the
X    amount to CHANGE the current scroll setting by.
X    Positive scrolls the text up, negative down.
X*/
X
Xstatic ScrollText (lDelta)
Xint		lDelta;
X{
Xregister int	lHeight;
Xregister int	newLine;
Xregister int	topLine;
X
X	lHeight = (**dispTE).lineHeight;
X	topLine = LinesOffTop ();
X    newLine = topLine + lDelta;
X    if (newLine < 0)
X    	newLine = 0;
X    if (newLine > GetCtlMax (dispScroll))
X		newLine = GetCtlMax (dispScroll);
X    SetCtlValue (dispScroll, newLine);
X    TEScroll (0, (topLine - newLine ) * lHeight, dispTE);
X}
X
X
X/*
X	Filter proc for tracking mousedown in scroll bar.  The code for
X	the part originally hit is stored in the control's reference
X	value by Mouse () before calling this.
X
X	Scroll by one line if the mouse is in an arrow.  Scroll by a half
X	window's worth of lines if the mouse is in a page region.
X*/
X
Xstatic pascal void TrackScroll (theScroll, partCode)
XControlHandle	theScroll;
Xint				partCode;
X{
Xregister int	lDelta;
Xregister int	halfPage;
X
X    if (partCode == GetCRefCon (theScroll))	/* still in same part? */
X    {
X		halfPage = (((**dispTE).viewRect.bottom - (**dispTE).viewRect.top)
X						/ (**dispTE).lineHeight) / 2;
X		if (halfPage == 0)
X			++halfPage;
X        switch (partCode)
X        {
X            case inUpButton: lDelta = -1; break;
X            case inDownButton: lDelta = 1; break;
X            case inPageUp: lDelta = -halfPage; break;
X            case inPageDown: lDelta = halfPage; break;
X        }
X        ScrollText (lDelta);
X    }
X}
X
X
X/*
X	Adjust the text in the text record and the scroll bar.  This is
X	called for major catastrophes, such as resizing the window, or
X	changing the word wrap style.  It makes sure the view and
X	destination rectangles are sized properly, and that the bottom
X	line of text never scrolls up past the bottom line of the
X	window, if there's enough to fill the window, and that the
X	scroll bar max and current values are set properly.
X
X	Resizing the dest rect just means resetting the right edge
X	(the top is NOT reset), since text might be scrolled off the
X	top (i.e., destRect.top != 0).
X*/
X
Xstatic OverhaulDisplay ()
X{
XRect			r;
Xregister int	nLines;			/* number of lines in TERec */
Xregister int	visLines;		/* number of lines displayable in window */
Xregister int	topLines;		/* number of lines currently scrolled off top */
Xregister int	scrollLines;	/* number of lines to scroll down */
Xregister int	lHeight;
X
X	CalcEditRect (&r);
X	(**dispTE).destRect.right = r.right;
X	(**dispTE).viewRect = r;
X	TECalText (dispTE);		/* recalc line starts */
X	/*r = (**dispTE).viewRect;*/	/* ?? */
X	lHeight = (**dispTE).lineHeight;
X	nLines = (**dispTE).nLines;
X	visLines = (r.bottom - r.top) / lHeight;
X	topLines = LinesOffTop ();
X
X/*
X	If the text doesn't fill the window (visLines > nLines - topLines),
X	pull the text down if possible (if topLines > 0).  Make sure not
X	to try to scroll down by more lines than are hidden off the top.
X*/
X	scrollLines = visLines - (nLines - topLines);
X	if (scrollLines > 0 && topLines > 0)
X	{
X		if (scrollLines > topLines)
X			scrollLines = topLines;
X		TEScroll (0, scrollLines * lHeight, dispTE);
X		topLines -= scrollLines;
X	}
X	TEUpdate (&r, dispTE);
X
X	SetCtlMax (dispScroll, nLines - visLines < 0 ? 0 : nLines - visLines);
X	SetCtlValue (dispScroll, topLines);
X	HiliteScroll ();
X}
X
X
X/* ---------------------------------------------------------------- */
X/*						Window Handler Routines						*/
X/* ---------------------------------------------------------------- */
X
X
X/*
X	When the window comes active, highlight the scroll bar appropriately.
X	When the window is deactivated, un-highlight the scroll bar.
X	Redraw the grow box.
X
X	Notify the host as appropriate.
X
X	Note that clicking close box hides the window, which generates a
X	deactivate event, so there is no need for a close notifier.
X*/
X
Xstatic Activate (isActive)
XBoolean	isActive;
X{
X	SyncGlobals (nil);				/* sync to current port */
X	DrawGrowBox ();
X	HiliteScroll ();
X
X	if (dActivate != nil)
X		(*dActivate) (isActive);
X}
X
X
X/*
X	Update window.  The update event might be in response to a
X	window resizing.  If so, move and resize the scroll bar,
X	and recalculate the text display.
X
X	The ValidRect call is done because the HideControl adds the
X	control bounds box to the update region - which would generate
X	another update event!  Since everything is redrawn below anyway,
X	the ValidRect is used to cancel the update.
X*/
X
Xstatic Update (resized)
XBoolean	resized;
X{
XRect	r;
X
X	SyncGlobals (nil);					/* sync to current port */
X	r = dispWind->portRect;
X	EraseRect (&r);
X	if (resized)
X	{
X		HideControl (dispScroll);
X		r = (**dispScroll).contrlRect;
X		ValidRect (&r);
X		CalcScrollRect (&r);
X		SizeControl (dispScroll, 16, r.bottom - r.top);
X		MoveControl (dispScroll, r.left, r.top);
X		OverhaulDisplay ();
X		ShowControl (dispScroll);
X	}
X	else
X	{
X		r = (**dispTE).viewRect;
X		TEUpdate (&r, dispTE);		/* redraw text display */
X	}
X
X	DrawGrowBox ();
X	DrawControls (dispWind);	/* redraw scroll bar */
X}
X
X
X/*
X    Handle mouse clicks in window
X*/
X
Xstatic Mouse (thePt, t, mods)
XPoint	thePt;
Xlong	t;
Xint		mods;
X{
Xregister int	thePart;
Xregister int	oldCtlValue;
X
X	SyncGlobals (nil);				/* sync to current port */
X
X	if ((thePart = TestControl (dispScroll, thePt)) == inThumb)
X	{
X		oldCtlValue = GetCtlValue (dispScroll);
X		if (TrackControl (dispScroll, thePt, nil) == inThumb)
X			ScrollText (GetCtlValue (dispScroll) - oldCtlValue);
X	}
X	else if (thePart != 0)
X	{
X		SetCRefCon (dispScroll, (long) thePart);
X		(void) TrackControl (dispScroll, thePt, &TrackScroll);
X	}
X}
X
X
X
X/*
X	Remove the display window from the list, and dispose of it.
X	Since the clobber procedure is never called except for real display
X	windows, and since the list must therefore be non-empty, it is
X	not necessary to check the legality of the window or that the
X	window's in the list.
X
X	Must do SetDWindow (nil) to turn output off, if the window being
X	clobbered is the current output window.
X*/
X
Xstatic Clobber ()
X{
X# ifndef	singleDisplay
Xregister DIHandle	h, h2;
X# endif
X
X	SyncGlobals (nil);					/* sync to current port */
X
X	if (dispWind == curDispWind)
X		SetDWindow (nil);
X
X# ifndef	singleDisplay
X
X	if ((**dwList).dWind == dispWind)	/* is it the first window in list? */
X	{
X		h2 = dwList;
X		dwList = (**dwList).dNext;
X	}
X	else
X	{
X		for (h = dwList; h != nil; h = h2)
X		{
X			h2 = (**h).dNext;
X			if ((**h2).dWind == dispWind)	/* found it */
X			{
X				(**h).dNext = (**h2).dNext;
X				break;
X			}
X		}
X	}
X	DisposHandle (h2);		/* get rid of information structure */
X
X# endif
X
X	TEDispose (dispTE);			/* toss text record */
X	DisposeWindow (dispWind);	/* toss window and scroll bar */
X	dispWind = nil;
X}
X
X
X/* ---------------------------------------------------------------- */
X/*							Control Routines						*/
X/* ---------------------------------------------------------------- */
X
X
X/*
X	Test whether a window is a legal display window or not
X*/
X
XBoolean IsDWindow (theWind)
XWindowPtr	theWind;
X{
X
X# ifdef	singleDisplay
X	return (theWind == dispWind && dispWind != nil);
X# else
X	return (GetDInfo (theWind) != nil);
X# endif
X}
X
X
X/*
X	Return handle to display window's text record
X*/
X
XTEHandle GetDWindowTE (theWind)
XWindowPtr	theWind;
X{
X
X# ifndef	singleDisplay
Xregister DIHandle	dInfo;
X	return (GetDInfo (theWind) == nil ? nil : (**dInfo).dTE);
X# else
X	return (IsDWindow (theWind) ? dispTE : nil);
X# endif
X}
X
X
X/*
X	Change the text display characteristics of a display window
X	and redisplay it.  As a side effect, this always scrolls to the
X	home position.
X*/
X
XSetDWindowStyle (theWind, font, size, wrap, just)
XWindowPtr	theWind;
Xint			font;
Xint			size;
Xint			wrap;
Xint			just;
X{
XGrafPtr				savePort;
XFontInfo			f;
Xregister TEHandle	te;
XRect				r;
X
X	if (theWind == nil)			/* reset window creation defaults */
X	{
X		d_font = font;
X		d_size = size;
X		d_wrap = wrap;
X		d_just = just;
X		return;
X	}
X
X	if (IsDWindow (theWind))
X	{
X		GetPort (&savePort);
X		SyncGlobals (theWind);
X		SetPort (dispWind);
X		te = dispTE;
X		r = (**te).viewRect;
X		EraseRect (&r);
X		r = (**te).destRect;	/* scroll home without redrawing */
X		OffsetRect (&r, 0, 2 - r.top);
X		(**te).destRect = r;
X
X		(**te).crOnly = wrap;	/* set word wrap */
X		TESetJust (just, te);	/* set justification */
X
X		TextFont (font);	 	/* set the font and point size */
X		TextSize (size);		/* of text record (this is the */
X		GetFontInfo (&f);		/* hard part) */
X		(**te).lineHeight = f.ascent + f.descent + f.leading;
X		(**te).fontAscent = f.ascent;
X		(**te).txFont = font;
X		(**te).txSize = size;
X
X		OverhaulDisplay ();
X		SetPort (savePort);
X	}
X}
X
X
X/*
X	Scroll the text in the window so that line lineNum is at the top.
X	First line is line zero.
X*/
X
XSetDWindowPos (theWind, lineNum)
XWindowPtr	theWind;
Xint			lineNum;
X{
XGrafPtr		savePort;
X
X	if (IsDWindow (theWind))
X	{
X		GetPort (&savePort);
X		SyncGlobals (theWind);
X		SetPort (dispWind);
X		ScrollText (lineNum - GetCtlValue (dispScroll));
X		SetPort (savePort);
X	}
X}
X
X
X/*
X	Set display window activate notification procedure.
X	Pass nil to disable it.
X*/
X
XSetDWindowNotify (theWind, p)
XWindowPtr	theWind;
XProcPtr		p;
X{
X# ifndef	singleDisplay
Xregister DIHandle	dInfo;
X# endif
X
X	if (theWind == nil)			/* reset window creation default */
X	{
X		d_activate = p;
X		return;
X	}
X
X# ifdef	singleDisplay
X
X	if (IsDWindow (theWind))
X		dActivate = p;
X
X# else
X
X	if ((dInfo = GetDInfo (theWind)) != nil)
X	{
X		(**dInfo).dActivate = p;
X	}
X
X# endif
X}
X
X
X/*
X	Set display window autoflush characteristics
X*/
X
XSetDWindowFlush (theWind, maxText, flushAmt)
XWindowPtr	theWind;
Xlong		maxText;
Xlong		flushAmt;
X{
X# ifndef	singleDisplay
Xregister DIHandle	dInfo;
X# endif
X
X	if (maxText > 32767L)
X		maxText = 32767L;
X	if (maxText < d_loMaxText)
X		maxText = d_loMaxText;
X	if (flushAmt < d_loFlushAmt)
X		flushAmt = d_loFlushAmt;
X
X	if (theWind == nil)			/* reset window creation defaults */
X	{
X		d_maxText = maxText;
X		d_flushAmt = flushAmt;
X		return;
X	}
X
X# ifdef	singleDisplay
X
X	if (IsDWindow (theWind))
X	{
X
X		dMaxText = maxText;
X		dFlushAmt = flushAmt;
X	}
X
X# else
X
X	if ((dInfo = GetDInfo (theWind)) != nil)
X	{
X		(**dInfo).dMaxText = maxText;
X		(**dInfo).dFlushAmt = flushAmt;
X	}
X
X# endif
X}
X
X
X/*
X	Set which display window is to be used for output.  If theWind
X	is nil, output is turned off.  If theWind is not a legal display
X	window, nothing is done.
X*/
X
XSetDWindow (theWind)
XWindowPtr	theWind;
X{
X	if (theWind == nil || IsDWindow (theWind))
X	{
X		curDispWind = theWind;
X	}
X}
X
X
X/*
X	Get the WindowPtr of the current output display window.  If
X	output is turned off, this will be nil.
X*/
X
XGetDWindow (theWind)
XWindowPtr	*theWind;
X{
X	*theWind = curDispWind;
X}
X
X
X/*
X	Flush text from the window and readjust the display.
X*/
X
XFlushDWindow (theWind, byteCount)
XWindowPtr	theWind;
Xlong		byteCount;
X{
X	if (IsDWindow (theWind))
X	{
X		SyncGlobals (theWind);
X		TESetSelect (0L, byteCount, dispTE);	/* select text */
X		TEDelete (dispTE);						/* clobber it */
X		OverhaulDisplay ();
X	}
X}
X
X
X/*
X	Create and initialize a display window and the associated data
X	structures, and return the window pointer.  Install window in
X	list of display windows.
X*/
X 
Xstatic SetupDWindow ()
X{
XRect				r;
XGrafPtr				savePort;
X
X# ifndef	singleDisplay
Xregister DIHandle	dInfo;
X# endif
X
X
X	GetPort (&savePort);
X	SkelWindow (dispWind,	/* the window */
X				Mouse,		/* mouse click handler */
X				nil,		/* key clicks are ignored */
X				Update,		/* window updating procedure */
X				Activate,	/* window activate/deactivate procedure */
X				nil,		/* TransSkel hides window if no close proc */
X							/* (generates deactivate event) */
X				Clobber,	/* window disposal procedure */
X				nil,		/* no idle proc */
X				false);		/* irrelevant since no idle proc */
X
X/*
X	Build the scroll bar.  Make sure the borders overlap the
X	window frame and the frame of the grow box.
X*/
X
X	CalcScrollRect (&r);
X	dispScroll = NewControl (dispWind, &r, "\p", true, 0, 0, 0,
X								scrollBarProc, 0L);
X
X/*
X	Create the TE record used for text display.  Use defaults for
X	display characteristics.  Setting window style overhauls
X	display, so can cancel and update event pending for the window.
X*/
X
X	CalcEditRect (&r);
X	dispTE = TENew (&r, &r);
X
X# ifndef	singleDisplay
X
X/*
X	Get new information structure, attach to list of known display
X	windows.
X*/
X	dInfo = New (DisplayInfo);
X	(**dInfo).dNext = dwList;
X	dwList = dInfo;
X	(**dInfo).dWind = dispWind;
X	(**dInfo).dScroll = dispScroll;
X	(**dInfo).dTE = dispTE;
X	
X# endif
X
X	SetDWindowNotify (dispWind, d_activate);
X	SetDWindowFlush (dispWind, d_maxText, d_flushAmt);
X	SetDWindowStyle (dispWind, d_font, d_size, d_wrap, d_just);
X
X/*
X	Make window current display output window
X*/
X
X	SetDWindow (dispWind);
X	SetPort (savePort);
X}
X
X
X/*
X	Create and initialize a display window and the associated data
X	structures, and return the window pointer.  Install window in
X	list of display windows.  In single-window mode, disallow
X	creation of a new window if one already exists.
X
X	The parameters are similar to those for NewWindow.  See Inside
X	Macintosh.
X*/
X 
XWindowPtr NewDWindow (bounds, title, visible, behind, goAway, refCon)
XRect		*bounds;
XStringPtr	title;
XBoolean		visible;
XWindowPtr	behind;
XBoolean		goAway;
Xlong		refCon;
X{
X
X# ifdef	singleDisplay
X
X	if (dispWind != nil)
X		return (nil);
X
X# endif
X
X	dispWind = NewWindow (nil, bounds, title, visible,
X							documentProc, behind, goAway, refCon);
X	SetupDWindow ();
X	return (dispWind);
X}
X
X
X/*
X	Create and initialize a display window (using a resource) and
X	the associated data structures, and return the window pointer.
X	Install window in list of display windows.  In single-window
X	mode, disallow creation of a new window if one already exists.
X
X	The parameters are similar to those for GetNewWindow.  See Inside
X	Macintosh.
X*/
X 
XWindowPtr GetNewDWindow (resourceNum, behind)
Xint			resourceNum;
XWindowPtr	behind;
X{
X
X# ifdef	singleDisplay
X
X	if (dispWind != nil)
X		return (nil);
X
X# endif
X
X	dispWind = GetNewWindow (resourceNum, nil, behind);
X	SetupDWindow ();
X	return (dispWind);
X}
X
X
X
X
X/* ------------------------------------------------------------ */
X/*						Output Routines							*/
X/* ------------------------------------------------------------ */
X
X
X/*
X	Write text to display area if output is on (curDispWind != nil).
X	DisplayText is the fundamental output routine.  All other
X	output calls map (eventually) to it.
X
X	First check whether the insertion will cause overflow and flush
X	out some stuff if so.  Insert new text at the end, then test
X	whether lines must be scrolled to get the new stuff to show up.
X	If yes, then do the scroll.  Set values of scroll bar properly
X	and highlight as appropriate.
X
X	The current port is preserved.  Since all output calls end up
X	here, it's the only output routine that has to save the port
X	and check whether output is on.
X*/
X
XDisplayText (theText, len)
XPtr		theText;
Xlong	len;
X{
Xregister int	nLines;			/* number of lines in TERec */
Xregister int	dispLines;		/* number of lines displayable in window */
Xregister int	topLines;		/* number of lines currently scrolled off top */
Xregister int	scrollLines;	/* number of lines to scroll up */
Xregister int	lHeight;
XRect			r;
XGrafPtr			savePort;
Xregister TEHandle	dTE;
X
X	if (curDispWind == nil)
X		return;
X
X	GetPort (&savePort);
X	SetPort (curDispWind);
X	SyncGlobals (curDispWind);
X	dTE = dispTE;
X
X	if ((**dTE).teLength + len > dMaxText)	/* check overflow */
X	{
X		FlushDWindow (dispWind, dFlushAmt);
X		DisplayString ("\p\r(autoflush occurred)\r");
X	}
X
X	lHeight = (**dTE).lineHeight;
X	TESetSelect (32767L, 32767L, dTE);	/* set to insert at end */
X	TEInsert (theText, len, dTE);
X	r = (**dTE).viewRect;
X	nLines = (**dTE).nLines;
X	dispLines = (r.bottom - r.top) / lHeight;
X	topLines = LinesOffTop ();
X	scrollLines = nLines - (topLines + dispLines);
X	if (scrollLines > 0) /* must scroll up */
X		TEScroll (0, -lHeight * scrollLines, dTE); /* scroll up */
X	topLines = nLines - dispLines;
X	if (topLines >= 0 && GetCtlMax (dispScroll) != topLines)
X	{
X		SetCtlMax (dispScroll, topLines);
X		SetCtlValue (dispScroll, topLines);
X	}
X	HiliteScroll ();
X	SetPort (savePort);
X}
X
X
X/*
X	Derived output routines:
X
X	DisplayString	Write (Pascal) string
X
X	DisplayLong		Write value of long integer
X	DisplayInt		Write value of integer
X	DisplayChar		Write character
X
X	DisplayHexLong	Write value of long integer in hex (8 digits)
X	DisplayHexInt	Write value of integer in hex (4 digits)
X	DisplayHexChar	Write value of character in hex (2 digit)
X
X	DisplayBoolean	Write boolean value
X	DisplayLn		Write carriage return
X*/
X
XDisplayString (theStr)
XStringPtr	theStr;
X{
X	DisplayText (theStr+1, (long) theStr[0]);
X}
X
X
XDisplayLong (l)
Xlong		l;
X{
XStr255		s;
X
X	NumToString (l, s);
X	DisplayString (s);
X}
X
X
XDisplayInt (i)
Xint		i;
X{
X	DisplayLong ((long) i);
X}
X
X
XDisplayChar (c)
Xchar	c;
X{
X	DisplayText (&c, 1L);
X}
X
X
XDisplayLn ()
X{
X	DisplayChar ('\r');
X}
X
X
XDisplayBoolean (b)
XBoolean	b;
X{
X	DisplayString (b ? "\ptrue" : "\pfalse");
X}
X
X
Xstatic HexByte (value)	/* should be 0..15 */
Xint		value;
X{
X	DisplayChar ((char) (value + (value < 10 ? '0' : 'a' - 10)));
X}
X
X
XDisplayHexChar (c)
Xchar	c;
X{
X	HexByte ((int) (c >> 4) & 0x0f);
X	HexByte ((int) c & 0x0f);
X}
X
X
XDisplayHexInt (i)
Xint		i;
X{
X	DisplayHexChar ((char) ((i >> 8) & 0xff));
X	DisplayHexChar ((char) (i & 0xff));
X}
X
X
XDisplayHexLong (l)
Xlong	l;
X{
X	DisplayHexInt ((int) (l >> 16) & 0xffff);
X	DisplayHexInt ((int) l & 0xffff);
X}
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > TransDisplay/TransDisplay.h
X/*
X	TransDisplay.h - TransDisplay header file
X*/
X
X# ifndef	_WindowMgr_
X# include	"WindowMgr.h"
X# endif
X
X# ifndef	_TextEdit_
X# include	"TextEdit.h"
X# endif
X
X
X# ifndef	nil
X# define	nil		(0L)
X# endif
X
X
X/*
X	Functions returning non-int values
X*/
X
XWindowPtr	NewDWindow ();
XWindowPtr	GetNewDWindow ();
XBoolean		IsDWindow ();
XTEHandle	GetDWindowTE ();
SHAR_EOF
exit