//CHATDISINIT.BCPL - Bob Sproull - Display protocol initialization
// Copyright Xerox Corporation 1979
// modified: April 13, 1979  6:05 PM (Taft)

get "Chat.d"
get "ChatDis.d"
get "Streams.d"
get "AltoDefs.d"

//outgoing procedure
external [
	ChatDISInit
	]


//incoming procedures
external [
//CHAT
	BigStack
	SmallStack

//CHATDIS
	ChatDIS
	DisTypeIn
	DisTypeOut
	DisDisplay
	DisEvent
	DisReadFont

//OS
	InitializeZone
	Allocate
	Zero
	MyFrame
	CallSwat

//QUEUE
	Enqueue

//CONTEXT
	InitializeContext
	]


//incoming statics
external [
//CHAT
	ChatZone
	ChatZoneSize
	ScreenBuffer
	ScreenBufferLength
	YMax
	DISSoc; DISStr
	Parm
	ctxQ

//CHATDIS
	SS
	disTypeInCtx
	disTypeOutCtx
	disDisplayCtx
	disEventCtx
	DisplayVersion

//Os
	lvSysZone
	sysZone
	]


let ChatDISInit() be
[
	ScreenBuffer=(ChatDISInit+1)&(-2)
	YMax=(Parm>>PARM.YMax eq 0) ? YMaxDefault, Parm>>PARM.YMax
	ScreenBufferLength=disWidth*(YMax+1)+lDCB
	let zoneBot=ScreenBuffer+ScreenBufferLength
	let zoneTop=MyFrame()-100		//Enough for ChatTTY
	ChatZone=InitializeZone(zoneBot,zoneTop-zoneBot)
	@#335=zoneTop

	BigStack()

	@lvSysZone=ChatZone
	sysZone=ChatZone

//Check even word alignment
	compileif offset REG.Function rem 32 ne 0 then [ foo=nil ]
	compileif size REG rem 32 ne 0 then [ foo=nil ]
	compileif offset DISV.regions rem 32 ne 0 then [ foo=nil ]

	let len=Parm>>PARM.nRegions*(size REG/16)+(size DISV/16)
	SS=Allocate(ChatZone, len, 0, true)
	Zero(SS, len)
	SS>>DISV.Version=DisplayVersion
	SS>>DISV.DISVLoc=SS
	SS>>DISV.ScreenBuf=ScreenBuffer
	SS>>DISV.nRegions=Parm>>PARM.nRegions
	SS>>DISV.YMax=YMax
	SS>>DISV.EscapeChar = -1

// BitBlt control block for drawing curves
	let bbc=Allocate(ChatZone, lBBC, 0, true)
	SS>>DISV.CurveBbc=bbc
	Zero(bbc, lBBC)
	bbc>>BBC.SBMR=1
	bbc>>BBC.DBCA=ScreenBuffer
	bbc>>BBC.DBMR=disWidth

//Get contexts for these guys to run in:
	disTypeInCtx=Allocate(ChatZone, 200)
	disTypeOutCtx=Allocate(ChatZone, 200)
	disDisplayCtx=Allocate(ChatZone, 200)
	disEventCtx=Allocate(ChatZone, 200)

	Enqueue(ctxQ, InitializeContext(disTypeInCtx, 200, DisTypeIn))
	Enqueue(ctxQ, InitializeContext(disTypeOutCtx, 200, DisTypeOut))
	Enqueue(ctxQ, InitializeContext(disDisplayCtx, 200, DisDisplay))
	Enqueue(ctxQ, InitializeContext(disEventCtx, 200, DisEvent))

//Read in the various fonts
	for i=0 to Parm>>PARM.nDisplayFonts-1 do
		[
		let c=DisReadFont(i, 0, (lv Parm>>PARM.DisplayFontFP)+i*lFP)
		if c eq 0 then CallSwat("Cannot read some font file")
		if c eq 1 then CallSwat("Cannot allocate storage for a font")
		]

// Calculate screen dimensions for TTY simulation.
// Assume average character width is 2/3 * font height.
	if Parm>>PARM.CalcScreenParms then
		[
		let f = (lv SS>>DISV.fonts)!0  // Default font
		let h = f>>STRIK.ascent + f>>STRIK.descent
		Parm>>PARM.ScreenLines = YMax/h
		Parm>>PARM.ScreenChars = (XMax*3)/(h*2)
		]

// How much storage left ?
	Allocate(ChatZone, #77777, lv ChatZoneSize)

	SmallStack()

	ChatDIS()				//Go do the work!
]