-- file: IntDM.mesa -- edited by Brotz, March 27, 1981 4:14 PM -- edited by Levin, January 16, 1980 10:14 AM DIRECTORY Ascii, displayCommon: FROM "DisplayCommon", dsD: FROM "DisplayDefs", Editor, inD: FROM "InteractorDefs", InlineDefs, intCommon: FROM "IntCommon", ovD: FROM "OverviewDefs", vmD: FROM "VirtualMgrDefs"; IntDM: PROGRAM IMPORTS disC: displayCommon, dsD, Editor, InlineDefs, intC: intCommon, vmD EXPORTS inD SHARES inD, vmD = PUBLIC BEGIN OPEN inD; -- Purpose: handles user interactions including the display, keyboard and mouse. This -- division gathers together commands and their arguments and is responsible for the -- display of all error messages. -- Global variables -- lineBuffer: STRING _ [160]; -- used by FillLineBuffer to avoid slow frame allocation. -- 158 is length of widest string (all '|') that fits without folding. DisplayDMTail: PROCEDURE [mnp: MessageTextNbrPtr, line: LinePtr, startIndex: ovD.CharIndex] = -- Fills out as much of the displayed message as possible starting in line with startIndex. BEGIN nextIndex, firstFreeIndex: ovD.CharIndex; IF ~mnp.haveMessage THEN RETURN; firstFreeIndex _ vmD.GetMessageSize[mnp.message]; UNTIL (line = mnp.firstLineOffScreen) OR (startIndex >= firstFreeIndex) DO nextIndex _ PutLineInBitMap[mnp.message, startIndex, line]; line.firstCharIndex _ startIndex; line.state _ normalText; line _ line.nextLine; startIndex _ nextIndex; ENDLOOP; IF line = mnp.firstLineOffScreen THEN BEGIN line.firstCharIndex _ startIndex; line.state _ IF startIndex >= firstFreeIndex THEN endOfMessage ELSE normalText; RETURN; END; [] _ dsD.PutStringInBitMap[leftMargin, line.y, mnp.endString, italicFace]; line.state _ endOfMessage; line.firstCharIndex _ firstFreeIndex; FOR line _ line.nextLine, line.nextLine UNTIL line = NIL DO line.state _ trailingBlankLine; line.firstCharIndex _ firstFreeIndex; ENDLOOP; END; -- of DisplayDMTail -- FillLineBuffer: PROCEDURE [vs: vmD.VirtualMessagePtr, startIndex: ovD.CharIndex] RETURNS [ovD.CharIndex] = -- Fills lineBuffer with a line of characters, starting by placing at the left margin -- the character at the startIndex position, and terminating the line at a line separator. -- Returns index of first character not put into line. BEGIN firstFreeIndex, curIndex, breakIndex: ovD.CharIndex; rightX: ScreenXCoord _ inD.leftMargin; i: CARDINAL _ 0; char: CHARACTER _ 0C; get: POINTER TO vmD.CharCache _ @vs.get; prevCharBreakProp, charBreakProp, lineBreakProp: dsD.CharProperty _ alphaNumeric; firstFreeIndex _ vmD.GetMessageSize[vs]; FOR curIndex _ startIndex, curIndex + 1 UNTIL (curIndex >= firstFreeIndex) OR (char = Ascii.CR) DO lineBuffer[i] _ char _ InlineDefs.BITAND [IF curIndex IN [get.first .. get.free) THEN get.string[curIndex + get.floor - get.first] ELSE vmD.GetMessageChar[vs, curIndex], ovD.CharMask]; i _ i + 1; charBreakProp _ dsD.GetCharBreakProp[char]; IF lineBreakProp = white THEN {IF prevCharBreakProp = white AND charBreakProp # white THEN breakIndex _ curIndex} ELSE BEGIN IF lineBreakProp = alphaNumeric OR prevCharBreakProp # alphaNumeric THEN BEGIN breakIndex _ curIndex; IF prevCharBreakProp # white OR charBreakProp # white THEN lineBreakProp _ prevCharBreakProp; END; END; prevCharBreakProp _ charBreakProp; IF (rightX _ dsD.GetCharRightX[char, rightX]) > inD.rightMargin THEN {curIndex _ breakIndex; EXIT} ENDLOOP; lineBuffer.length _ curIndex - startIndex; RETURN[curIndex]; END; -- of FillLineBuffer -- PutLineInBitMap: PROCEDURE [vs: vmD.VirtualMessagePtr, startIndex: ovD.CharIndex, line: LinePtr] RETURNS [ovD.CharIndex] = -- Fills the bitmap with a line of characters, starting by placing at inD.leftMargin, line.y -- the character at the startIndex position, and terminating the line at a line separator. -- Returns index of first character not put into line. BEGIN curIndex: ovD.CharIndex _ FillLineBuffer[vs, startIndex]; line.rightX _ dsD.PutStringInBitMap[inD.leftMargin, line.y, lineBuffer, plainFace]; RETURN[curIndex]; END; -- of PutLineInBitMap -- ScrollUpDM: PROCEDURE [y: ScreenYCoord, mnp: MessageTextNbrPtr] = -- Scrolls message line containing y or End of Message line to top of neighborhood. BEGIN lineY: ScreenYCoord; line, newTopLine, newLastLine, oldLastLine: LinePtr; FOR newTopLine _ mnp.lines, newTopLine.nextLine UNTIL (newTopLine.state = endOfMessage) OR (y < newTopLine.y + dsD.lineHeight) OR (newTopLine.nextLine = mnp.firstLineOffScreen) DO ENDLOOP; IF newTopLine = mnp.lines THEN IF newTopLine.state = endOfMessage THEN RETURN ELSE newTopLine _ newTopLine.nextLine; IF intC.source.mnp = mnp THEN Editor.DeUnderlineSelection[@intC.source, source]; dsD.SlideFullWidthRectangleVertically[newTopLine.y, mnp.bottomY, mnp.topY]; FOR newLastLine _ mnp.lines, newLastLine.nextLine UNTIL newLastLine.nextLine = newTopLine DO ENDLOOP; oldLastLine _ mnp.firstLineOffScreen; mnp.firstLineOffScreen.nextLine _ mnp.lines; mnp.lines _ newTopLine; newLastLine.nextLine _ NIL; mnp.firstLineOffScreen _ newLastLine; lineY _ mnp.topY; FOR line _ newTopLine, line.nextLine UNTIL line = NIL DO line.y _ lineY; lineY _ lineY + dsD.lineHeight; ENDLOOP; IF oldLastLine.state # trailingBlankLine THEN DisplayDMTail[mnp, oldLastLine, oldLastLine.firstCharIndex] ELSE FOR line _ oldLastLine.nextLine, line.nextLine UNTIL line = NIL DO line.state _ trailingBlankLine; line.firstCharIndex _ oldLastLine.firstCharIndex; ENDLOOP; IF intC.source.mnp = mnp THEN Editor.UnderlineSelection[@intC.source, source]; END; -- of ScrollUpDM -- ScrollDownDM: PROCEDURE [y: ScreenYCoord, mnp: MessageTextNbrPtr] = -- Scrolls top message line of neighborhood down to line containing y. Will not scroll first -- line of message below top line however. BEGIN shiftNum, realShiftNum: CARDINAL; startCharIndex, charIndex: ovD.CharIndex; char: CHARACTER; lineY: ScreenYCoord; line, newTopLine, newLastLine, oldLastLine: LinePtr; shiftNum _ MAX[(y - mnp.topY) / dsD.lineHeight, 1]; IF (charIndex _ mnp.lines.firstCharIndex) = 0 THEN RETURN; IF intC.source.mnp = mnp THEN Editor.DeUnderlineSelection[@intC.source, source]; FOR realShiftNum _ 0, realShiftNum + 1 UNTIL (charIndex = 0) OR (realShiftNum = shiftNum) DO charIndex _ charIndex - 1; char _ 0C; UNTIL (char = Ascii.CR) OR (charIndex = 0) DO charIndex _ charIndex - 1; char _ vmD.GetMessageChar[mnp.message, charIndex]; ENDLOOP; IF charIndex # 0 THEN charIndex _ charIndex + 1; ENDLOOP; startCharIndex _ charIndex; THROUGH [1 .. realShiftNum] DO charIndex _ FillLineBuffer[mnp.message, charIndex]; ENDLOOP; UNTIL realShiftNum = shiftNum OR charIndex = mnp.lines.firstCharIndex DO charIndex _ FillLineBuffer[mnp.message, charIndex]; realShiftNum _ realShiftNum + 1; ENDLOOP; UNTIL charIndex = mnp.lines.firstCharIndex DO charIndex _ FillLineBuffer[mnp.message, charIndex]; startCharIndex _ FillLineBuffer[mnp.message, startCharIndex]; ENDLOOP; dsD.SlideFullWidthRectangleVertically [mnp.topY, mnp.bottomY - realShiftNum * dsD.lineHeight, mnp.topY + realShiftNum * dsD.lineHeight]; newLastLine _ mnp.lines; THROUGH [0 .. (mnp.bottomY - mnp.topY) / dsD.lineHeight - realShiftNum) DO newLastLine _ newLastLine.nextLine; ENDLOOP; newTopLine _ newLastLine.nextLine; oldLastLine _ mnp.firstLineOffScreen; newLastLine.nextLine _ NIL; mnp.firstLineOffScreen _ newLastLine; oldLastLine.nextLine _ mnp.lines; mnp.lines _ newTopLine; lineY _ mnp.topY; FOR line _ newTopLine, line.nextLine UNTIL line = NIL DO line.y _ lineY; lineY _ lineY + dsD.lineHeight; ENDLOOP; line _ mnp.lines; THROUGH [1 .. realShiftNum] DO line.firstCharIndex _ startCharIndex; line.state _ normalText; startCharIndex _ PutLineInBitMap[mnp.message, startCharIndex, line]; line _ line.nextLine; ENDLOOP; IF intC.source.mnp = mnp THEN Editor.UnderlineSelection[@intC.source, source]; END; -- of ScrollDownDM -- ThumbDM: PROCEDURE [tlnp: ThumbLineNbrPtr, x: ScreenXCoord] = -- Displays the portion of the DM that begins at the same relative position in the DM as x is -- in the thumb line. BEGIN xRange: CARDINAL _ tlnp.rightX - tlnp.leftX; messageLength, indexOfCharOnFirstLine, newFirstCharIndex: ovD.CharIndex; savedCursor: dsD.CursorShape; mnp: MessageTextNbrPtr = intC.dmTextNbr; message: vmD.VirtualMessagePtr = mnp.message; IF ~mnp.haveMessage THEN RETURN; messageLength _ vmD.GetMessageSize[message]; IF messageLength = 0 THEN RETURN; [savedCursor, , ] _ dsD.GetCursor[]; dsD.ChangeCursor[hourGlass]; indexOfCharOnFirstLine _ InlineDefs.LongDiv[InlineDefs.LongMult[messageLength, x - tlnp.leftX], xRange]; IF indexOfCharOnFirstLine = messageLength THEN indexOfCharOnFirstLine _ indexOfCharOnFirstLine - 1; newFirstCharIndex _ indexOfCharOnFirstLine; UNTIL newFirstCharIndex = 0 DO IF vmD.GetMessageChar[message, newFirstCharIndex] = Ascii.CR THEN GOTO FoundCR; newFirstCharIndex _ newFirstCharIndex - 1; REPEAT FoundCR => newFirstCharIndex _ newFirstCharIndex + 1; ENDLOOP; DO nextIndex: ovD.CharIndex _ FillLineBuffer[message, newFirstCharIndex]; IF nextIndex > indexOfCharOnFirstLine THEN EXIT; newFirstCharIndex _ nextIndex; ENDLOOP; IF intC.source.mnp = mnp THEN Editor.DeUnderlineSelection[@intC.source, source]; dsD.ClearRectangle[leftMargin, rightMargin, mnp.topY, mnp.bottomY]; DisplayDMTail[mnp, mnp.lines, newFirstCharIndex]; IF intC.source.mnp = mnp THEN Editor.UnderlineSelection[@intC.source, source]; dsD.ChangeCursor[savedCursor]; END; -- of ThumbDM -- END. -- of IntDM --z20461(529)\f1