ScreenImpl.mesa
Copyright (C) 1983, 1984 Xerox Corporation. All rights reserved.
Author: John Maxwell
Last Edited by: Maxwell, November 22, 1983 10:52 am
Edited by Doug Wyatt, June 15, 1984 11:26:20 am PDT
 
DIRECTORY
CursorDefs, 
Directory USING [Error], 
DisplayDefs USING [DisplayOff], 
Graphics 
USING [
Box, CopyContext, DrawChar, 
Context, DrawRope, DrawBox, FontRef, GetBounds,  
MakeFont, Map, NewContext, PaintMode, RopeBox, RopeWidth, 
ClipBox, SetCP, SetDefaultFont, SetFat, SetPaintMode, SetStipple,  
Translate, WorldToUser], 
Heap USING [MakeMDSString, FreeMDSString], 
MusicDefs 
USING [AnyBug, black, BlueBug, Control, grey, RedBug, Shift, ScorePTR, 
white, YellowBug], 
MusicProcess, 
Piece USING [Free, Overflow],
Real USING [FixI], 
Score USING [InitializeSynthesizer, StopListening, StopPlaying, Test], 
Screen USING [commands, CommandProcs], 
String USING [AppendChar, AppendString, InvalidNumber], 
TerminalMultiplex USING [RegisterNotifier, TerminalSwapNotifier], 
TTY USING [CharsAvailable, Create, GetChar, Handle, Rubout, SetEcho], 
UserTerminal USING [mouse, GetCursorPattern, SetCursorPattern, WaitForScanLine];
 
ScreenImpl: 
CEDAR 
MONITOR 
IMPORTS 
Directory, Graphics, Heap, MusicDefs, -- Music: MusicProcess, -- 
Piece, Real, Screen, String, TerminalMultiplex, TTY, UserTerminal 
 
EXPORTS Screen = 
BEGIN 
OPEN Graphics, CursorDefs, MusicDefs, Screen, UserTerminal;
keyboard: TTY.Handle;
font: Graphics.FontRef;
******************************************************************
Multiplexing code
******************************************************************
running: BOOL ← TRUE;
WaitRunning: 
ENTRY 
PROC = 
INLINE
{WHILE ~running DO UserTerminal.WaitForScanLine[0]; ENDLOOP};
 
Notifier: TerminalMultiplex.TerminalSwapNotifier = {
SELECT action 
FROM
coming => running ← TRUE;
going => running ← FALSE;
ENDCASE;
 
};
******************************************************************
User Commands
******************************************************************
main: PROCESS ← NIL;
Initialize: 
PROC = {
TerminalMultiplex.RegisterNotifier[Notifier];
DisplayDefs.DisplayOff[white];
DisplayDefs.SetSystemDisplaySize[0, 0];
[] ← TTY.SetEcho[keyboard, FALSE];
keyboard ← TTY.Create[NIL];
screen ← NewContext[NIL];
[] ← SetFat[screen, TRUE];
windows[0] ← [screen, , , command, @commandProcs, 800, 740];
DefaultWindow[1, 740, 0];
font ← MakeFont["TimesRoman12"];
SetDefaultFont[screen, font];
commandProcs.display ← DisplayCommandWindow;
FrameDefs.MakeCodeResident[FrameDefs.GlobalFrame[Music]];
Score.InitializeSynthesizer[];
DrawScreen[];
ReadCommandLine[];
SetCursorPattern[textCursor];
main ← FORK Main[];
};
 
ForkMain: PROC = {main ← FORK Main[]};
Main: 
PROC = {
ENABLE {
Piece.Overflow => {DisplayMessage["Piece.Overflow"]; RESUME};
ANY => DisplayMessage["UNCAUGHT SIGNAL"]};
 
DisplayMessage["Mockingbird of November 22, 1983"];
DO 
IF badCommand 
THEN {
WHILE TTY.GetChar[keyboard] # 177C DO NULL; ENDLOOP;
EraseMessage[]; badCommand ← FALSE; };
badCommand ← FALSE;
WaitRunning[];
SELECT TRUE FROM
RedBug[] => HandleRed[];
BlueBug[] => HandleBlue[FindWindow[ScreenPY]];
YellowBug[] => HandleYellow[];
TTY.CharsAvailable[keyboard] # 0 => ReadKeyboard[];
ENDCASE => ChangeCursor[];
FOR w: 
CARDINAL 
IN [1..noWindows) 
DO 
IF windows[w].command.count > 50 THEN BackUp[w];
ENDLOOP;
 
 
ENDLOOP;
 
};
 
badCommand: BOOL ← FALSE;
Command: 
PROC 
RETURNS[
BOOL] = {
image: Image;
EraseMessage[];
MousePoint[];
[ScreenPX, ScreenPY] ← WorldToUser[screen, MousePX, 808 - MousePY];
image ← FindCommand[ScreenPX, ScreenPY];
IF image.command # NullProc 
THEN {
image.command[image.rect]; 
WHILE AnyBug[] DO NULL; ENDLOOP;
RETURN[TRUE]};
 
RETURN[FALSE];
};
 
HandleRed: 
PROC = {
w: CARDINAL;
top: REAL;
IF Command[] THEN RETURN;
w ← FindWindow[ScreenPY];
IF w = 0 THEN RETURN;
Select[w];
top ← windows[w].top-header-40;
IF ScreenPX > 606 THEN RETURN;
SELECT 
TRUE 
FROM
Control[] => windows[w].command.redbug[windows[w].score];
Shift[] => windows[w].command.redbug[windows[w].score];
ScreenPX < leftMargin => Scroll[w, Real.FixI[top-ScreenPY]];
ScreenPX > rightMargin => NULL; -- MoveWindow[ScreenPY];
ENDCASE => windows[w].command.redbug[windows[w].score];
 
};
 
HandleBlue: 
PROC[w: 
CARDINAL] = {
ENABLE Piece.Overflow => IF windows[w].score = old THEN windows[w].score ← new;
top: REAL;
IF Command[] THEN RETURN;
IF w = 0 THEN RETURN;
Select[w];
IF ScreenPX > 606 THEN RETURN;
top ← windows[w].top-header-40;
SELECT 
TRUE 
FROM
Control[] => windows[w].command.bluebug[windows[w].score];
Shift[] => windows[w].command.bluebug[windows[w].score];
ScreenPX < leftMargin => Scroll[w, Real.FixI[ScreenPY-top]];
ScreenPX > rightMargin => NULL; -- NewWindow[w, ScreenPY];
ENDCASE => windows[w].command.bluebug[windows[w].score];
 
};
 
HandleYellow: 
PROC = {
w: CARDINAL;
IF Command[] THEN RETURN;
w ← FindWindow[ScreenPY];
IF w = 0 THEN RETURN;
Select[w];
IF ScreenPX > 606 THEN RETURN;
SELECT 
TRUE 
FROM
Control[] => windows[w].command.yellowbug[windows[w].score];
Shift[] => windows[w].command.yellowbug[windows[w].score];
ScreenPX < leftMargin => windows[w].command.thumb[windows[w].score];
ScreenPX > rightMargin => NULL; -- SubWindow[w, ScreenPY];
ENDCASE => windows[w].command.yellowbug[windows[w].score];
 
};
 
ReadKeyboard: 
PROC = {
ENABLE {
String.InvalidNumber => { 
DisplayMessage["illegal number- type DEL to continue"];
badCommand ← TRUE; 
CONTINUE; };
TTY.Rubout => { 
DisplayMessage["command terminated"];
CONTINUE; };
 
Piece.Overflow => 
IF windows[selectedWindow].score = old 
THEN windows[selectedWindow].score ← new;
};
 
EraseMessage[];
windows[selectedWindow].command.keyboard[windows[selectedWindow].score];
};
 
ChangeCursor: 
PROC = {
newState: CursorState;
MousePoint[];
[ScreenPX, ScreenPY] ← WorldToUser[screen, MousePX, 808 - MousePY];
IF ScreenPX > 606 THEN RETURN;
SELECT 
TRUE 
FROM 
FindCommand[ScreenPX, ScreenPY].command # NullProc => newState ← command;
ScreenPY > windows[0].bottom => newState ← commandwindow;
ScreenPX > rightMargin => newState ← window;
ScreenPX < leftMargin => newState ← scroll;
ENDCASE => newState ← screen;
 
IF newState = currentState THEN RETURN;
IF currentState = screen THEN oldCursor ← GetCursorPattern[];
SELECT newState 
FROM 
window => SetCursorPattern[windowCursor];
command => SetCursorPattern[bullseyeCursor];
scroll => SetCursorPattern[scrollUpDownCursor];
commandwindow => SetCursorPattern[textCursor];
ENDCASE => SetCursorPattern[oldCursor];
 
currentState ← newState;
};
 
oldCursor: Cursor ← textCursor;
CursorState: TYPE = {window, scroll, command, screen, commandwindow};
currentState: CursorState ← screen;
Scroll: 
PROC[w: 
CARDINAL, y: 
INTEGER] = {
IF y > 0 THEN SetCursorPattern[scrollUpCursor];
IF y < 0 THEN SetCursorPattern[scrollDownCursor];
windows[w].command.scroll[windows[w].score, y];
SetCursorPattern[scrollUpDownCursor];
};
 
MousePoint: 
PROC = {
x, y: REAL = 1;
MousePX ← x*mouse.x;
MousePY ← y*mouse.y;
};
 
MousePX, MousePY: REAL;
ScreenPX, ScreenPY: REAL;
******************************************************************
Window & Subwindow procedures
******************************************************************
DrawScreen: 
PROC = {
i: CARDINAL;
FOR i IN [0..noWindows) DO windows[i].command.display[windows[i].score, TRUE] ENDLOOP;
};
 
MoveWindow: 
PROC[y: 
REAL] = {
i, a, w: CARDINAL ← 0;
dist, last: REAL ← 1000;
SetCursorPattern[moveWindowCursor];
FOR i 
IN [1..noWindows) 
DO 
IF (windows[i].top-y < dist 
OR y-windows[i].top < dist)
AND FindWindow[windows[i].top +1] # 0
THEN { dist ← ABS[windows[i].top-y]; w ← i; };
 
ENDLOOP;
 
IF w = 0 THEN RETURN;
a ← FindWindow[windows[w].top +1];
DisplayHeader[white, w];
WHILE RedBug[] DO NULL; ENDLOOP;
MousePoint[];
[ScreenPX, ScreenPY] ← WorldToUser[screen, MousePX, 808 - MousePY];
y ← ScreenPY;
last ← windows[w].top;
IF y > windows[a].top - 16 THEN y ← windows[a].top - 16;
IF y < windows[w].bottom + 16 THEN y ← windows[w].bottom + 16;
MoveContext[w, y];
windows[a].bottom ← y;
windows[w].top ← y;
SetClipper[a];
SetClipper[w];
DisplayHeader[black, w];
IF last > windows[w].top THEN windows[a].command.display[windows[a].score, TRUE];
windows[w].command.display[windows[w].score, TRUE];
Select[w];
};
 
NewWindow: 
PROC[w: 
CARDINAL, y: 
REAL] = {
called by bluebug in the righthand margin
SetCursorPattern[newWindowCursor];
WHILE BlueBug[] AND NOT YellowBug[] DO NULL; ENDLOOP;
IF YellowBug[] THEN { DeleteWindow[w]; RETURN; };
DefaultWindow[noWindows, y, windows[w].bottom];
windows[w].bottom ← y;
Select[noWindows];
DisplayHeader[black, noWindows];
SetClipper[w];
SetClipper[noWindows];
noWindows ← noWindows + 1;
};
 
SubWindow: 
PROC[w: 
CARDINAL, y: 
REAL] = {
yellowbug in the righthand margin
SetCursorPattern[subWindowCursor];
WHILE NOT BlueBug[] AND YellowBug[] DO NULL; ENDLOOP;
IF BlueBug[] THEN { DeleteWindow[w]; RETURN; };
Flash[NIL];
};
 
FindWindow: 
PROC[y: 
REAL] 
RETURNS[
CARDINAL] = {
i: CARDINAL;
FOR i 
IN [0..noWindows) 
DO 
IF y < windows[i].top AND y > windows[i].bottom THEN RETURN[i];
ENDLOOP;
 
RETURN[0];
};
 
DeleteWindow: 
PROC[w: 
CARDINAL] = {
neighbor: CARDINAL;
SetCursorPattern[windowCursor];
Invert[windows[w].context];
WHILE BlueBug[] AND YellowBug[] DO NULL; ENDLOOP;
Wait[1];
Invert[windows[w].context];
IF BlueBug[] OR YellowBug[] THEN RETURN;
neighbor ← FindWindow[windows[w].top + 1];
IF neighbor # 0 
THEN {
windows[neighbor].bottom ← windows[w].bottom;
DisplayHeader[white, w];
}
 
ELSE {
neighbor ← FindWindow[windows[w].bottom - 1];
IF neighbor # 0 
THEN {
MoveContext[neighbor, windows[w].top];
DisplayHeader[white, neighbor];
windows[neighbor].top ← windows[w].top;
DisplayHeader[black, neighbor];
};
 
};
 
 
IF neighbor = 0 
THEN {
DisplayMessage["cannot delete that window"];
RETURN;
};
 
 
noWindows ← noWindows - 1;
Heap.FreeMDSString[, windows[w].file];
windows[w] ← windows[noWindows];
SetClipper[neighbor];
Select[neighbor];
windows[neighbor].command.display[windows[neighbor].score, TRUE];
};
 
Invert: 
PROC[dc: Context] = {
SetStipple[dc, black];
[] ← SetPaintMode[dc, invert];
DrawBox[dc, [0, 0, 1024, 808]];
[] ← SetPaintMode[dc, opaque];
};
 
MoveContext: 
PROC[w: 
CARDINAL, y: 
REAL] = {
siy, soy, tiy, toy: REAL;
siy ← y;
tiy ← windows[w].top;
[, soy] ← Map[screen, windows[w].context, 0, siy];
[, toy] ← Map[screen, windows[w].context, 0, tiy];
Translate[windows[w].context, 0, soy- toy];
};
 
Select: 
PROC[w: 
CARDINAL] = {
SetBrush[black, transparent];
DrawBox[screen, [20, windows[selectedWindow].top- header- 10, 
28, windows[selectedWindow].top- header]];
SetBrush[grey, opaque];
DrawBox[screen, [20, windows[w].top- header- 10, 28, windows[w].top- header]];
selectedWindow ← w;
};
 
selectedWindow: CARDINAL ← 1;
listenWindow: CARDINAL ← 1;
DefaultWindow: 
PROC[w: 
CARDINAL, top, bottom: 
REAL] = {
windows[w] ← [, , , unknown, @unknownProcs, top, bottom];
windows[w].context ← CopyContext[screen];
windows[w].file ← Heap.MakeMDSString[, 40];
Translate[windows[w].context, 30, top - header - 40]; -- 30 regular, 45 for videotaping
SetClipper[w];
SetStipple[windows[w].context, black];
[] ← SetPaintMode[windows[w].context, opaque];
DrawBox[windows[w].context, GetBounds[windows[w].context]];
windows[w].type ← logical;
windows[w].command ← @Screen.commands;
windows[w].score ← windows[w].command.initialize[windows[w].context];
};
 
******************************************************************
Command Window procedures
******************************************************************
DisplayCommandWindow: 
PROC[score: ScorePTR, erase: 
BOOL] = {
i: CARDINAL;
Erase[NIL, TRUE];
SetBrush[black, opaque];
ClearManager[];
DisplayCommand["FileIn", 30, 750, FileIn];
DisplayCommand["PlayBack", 110, 750, Play];
DisplayCommand["Print", 215, 750, Hardcopy];
DisplayCommand["Quit", 300, 750, Quit];
DisplayCommand["Record", 385, 750, Listen];
DisplayCommand["FileOut", 480, 750, FileOut];
FOR i IN [1..noWindows) DO DisplayHeader[black, i] ENDLOOP;
Select[1];
};
 
DisplayCommand: 
PROC[s: 
LONG 
STRING, x, y: 
REAL, proc: 
PROC[r: Box]] = {
box: Box;
SetCP[screen, x, y];
SetBrush[black, invert];
DrawRope[screen, LOOPHOLE[s]];
[box.xmin, box.ymin, box.xmax, box.ymax] ← RopeBox[font, LOOPHOLE[s]];
box.xmin ← box.xmin + x;
box.ymin ← box.ymin + y;
box.xmax ← box.xmax + x;
box.ymax ← box.ymax + y;
IF box.xmax - box.xmin < 30 THEN box.xmax ← box.xmin + 30;
IF box.ymax - box.ymin < 10 THEN box.ymax ← box.ymin + 10;
AddCommand[box, proc];
};
 
DisplayHeader: 
PROC[color: 
CARDINAL, w: 
CARDINAL] = {
top: REAL ← windows[w].top;
px, py: REAL;
px ← 30;
py ← windows[w].top - 16;
SetBrush[color, opaque];
DrawBox[screen, [0, top-header, 620, top]];
DeleteCommand[px, py];
IF color = grey  THEN SetBrush[grey, invert];
IF color = black THEN SetBrush[black, invert];
IF color = white THEN RETURN;
DisplayCommand[windows[w].file, 30, top-12, EditFileName];
};
 
EraseMessage: 
PROC = {
SetBrush[white, opaque];
DrawBox[screen, [0, 763, 620, 780]];
SetBrush[black, invert];
};
 
DisplayMessage: 
PUBLIC 
PROC[s: 
STRING] = {
ls: LONG STRING ← s;
IF s = NIL THEN {EraseMessage[]; RETURN};
SetBrush[black, opaque];
DrawBox[screen, [0, 765, 620, 780]];
SetBrush[black, invert];
SetCP[screen, 300 - RopeWidth[font, LOOPHOLE[ls]].xw/2, 767];
DrawRope[screen, LOOPHOLE[ls]];
};
 
AddCommand: 
PROC[r: Box, proc: 
PROC[r: Box]] = {
FOR i: 
CARDINAL 
IN [0..mIndex) 
DO
IF manager[i].command = proc THEN RETURN;
ENDLOOP;
 
manager[mIndex] ← [r, proc];
IF proc = Play THEN playIndex ← mIndex;
IF proc = Listen THEN listenIndex ← mIndex;
mIndex ← mIndex + 1;
};
 
DeleteCommand: 
PROC[x, y: 
REAL] = {
i: CARDINAL;
FOR i 
IN [0..mIndex) 
DO
IF manager[i].rect.xmin = x 
THEN
{
mIndex ← mIndex - 1;
manager[i] ← manager[mIndex];
}; ENDLOOP;
 
 
};
 
FindCommand: 
PROC[x, y: 
REAL] 
RETURNS[m: Image] = {
i: CARDINAL;
FOR i 
IN [0..mIndex) 
DO
{
m ← manager[i];
IF x > m.rect.xmin 
AND x < m.rect.xmax 
AND
y > m.rect.ymin AND y < m.rect.ymax  
THEN RETURN[m];
 
}; ENDLOOP;
 
m.command ← NullProc;
RETURN[m];
};
 
Flash: 
PROC[score: ScorePTR] = {
Invert[windows[selectedWindow].context];
Invert[windows[selectedWindow].context];
};
 
Erase: 
PROC[score: ScorePTR, erase: 
BOOL] = {
SetStipple[screen, white];
[] ← SetPaintMode[screen, opaque];
DrawBox[screen, GetBounds[screen]];
SetStipple[screen, black];
[] ← SetPaintMode[screen, transparent];
};
 
******************************************************************
Commands
******************************************************************
Confirm: 
PROC[w: 
CARDINAL, s: 
STRING] 
RETURNS[
BOOL] = {
confirm: BOOL;
IF windows[w].command.count = 0 THEN RETURN[TRUE];
DisplayMessage[s];
confirm ← TTY.GetChar[keyboard] = CR;
EraseMessage[];
RETURN[confirm];
};
 
FileIn: 
PROC[r: Box] = {
ENABLE Directory.Error => { 
DisplayMessage["no such file"]; 
DrawBox[screen, r]; 
CONTINUE; };
 
s: CARDINAL ← selectedWindow;
SetBrush[black, invert];
DrawBox[screen, r];
IF Confirm[s, "the current file has not been filed out-- type CR to confirm"] 
THEN
{
IF windows[s].score # NIL THEN Piece.Free[windows[s].score];
windows[s].score ← windows[s].command.fileIn[windows[s].file];
EraseMessage[];
windows[s].command.display[windows[s].score, TRUE];
windows[s].command.count ← 0;
};
 
DrawBox[screen, r];
};
 
FileOut: 
PROC[r: Box] = {
ENABLE Directory.Error => { 
DisplayMessage["illegal file name"]; 
DrawBox[screen, r];
CONTINUE; };
 
s: CARDINAL ← selectedWindow;
SetBrush[black, invert];
DrawBox[screen, r];
windows[s].command.fileOut[windows[s].score, windows[s].file];
windows[s].command.count ← 0;
DrawBox[screen, r];
};
 
BackUp: 
PROC[w: 
CARDINAL] = {
DisplayMessage["Please wait... storing file on backup.music"];
windows[w].command.fileOut[windows[w].score, "backup.music"];
windows[w].command.count ← 1; -- so it will look dirty
EraseMessage[];
};
 
Play: 
PROC[r: Box] = {
ENABLE Piece.Overflow => 
IF windows[selectedWindow].score = old 
THEN windows[selectedWindow].score ← new;
 
windows[selectedWindow].command.play[windows[selectedWindow].score];
};
 
InvertPlay: 
PUBLIC 
PROC = {
r: Box = manager[playIndex].rect;
SetBrush[black, invert];
DrawBox[screen, r];
};
 
Listen: 
PROC[r: Box] = {
ENABLE Piece.Overflow => 
IF windows[listenWindow].score = old 
THEN windows[listenWindow].score ← new;
 
windows[listenWindow].command.listen[windows[listenWindow].score];
listenWindow ← selectedWindow;
};
 
InvertListen: 
PUBLIC 
PROC = {
r: Box = manager[listenIndex].rect;
SetBrush[black, invert];
DrawBox[screen, r];
};
 
playIndex: CARDINAL ← 0;
listenIndex: CARDINAL ← 0;
Hardcopy: 
PROC[r: Box] = {
SetBrush[black, invert];
DrawBox[screen, r];
DisplayMessage["Please wait... printing screen on music.press"];
windows[selectedWindow].command.hardcopy[windows[selectedWindow].score, "music.press"];
DrawBox[screen, r];
EraseMessage[];
};
 
EditFileName: 
PROC[r: Box] = {
w: CARDINAL ← FindWindow[ScreenPY];
c, last: CHARACTER ← 040C;
CR: CHARACTER ← 015C;
IF w = 0 THEN RETURN;
windows[w].file.length ← 0;
DisplayMessage["Please enter filename."];
DisplayHeader[white, w];
DisplayHeader[black, w];
DO {
c ← TTY.GetChar[keyboard];
IF c = 177C 
OR c = 010C 
THEN 
{
IF windows[w].file.length = 0 THEN LOOP;
windows[w].file.length ← windows[w].file.length- 1; 
DisplayHeader[black, w];
LOOP; };
 
IF c = ' 
THEN { 
windows[w].file.length ← 0; 
DisplayHeader[black, w];
LOOP; };
 
IF c # 
CR 
AND c # '. 
AND c # 033C 
THEN { 
String.AppendChar[windows[w].file, c];
DrawChar[screen, c]; LOOP;
};
 
String.AppendString[windows[w].file, ".music"];
windows[w].type ← logical;
EXIT; }; 
ENDLOOP;
 
DisplayHeader[black, w];
EraseMessage[];
Select[w];
};
 
Quit: 
PROC[r: Box] = {
IF NOT Confirm[1, "type CR to confirm Quit"] THEN RETURN;
Score.StopPlaying[]; 
Score.StopListening[]; 
};
 
ClearManager: 
PROC = {
mIndex ← 0;
};   
 
manager: ARRAY [0..20) OF Image;
Image: TYPE = RECORD[rect: Box, command: PROC[r: Box]];
mIndex: CARDINAL ← 0;
mMax: CARDINAL = 20;
******************************************************************
Assorted
******************************************************************
SetBrush: 
PROC[tex: 
CARDINAL, pnt: Graphics.PaintMode] = 
INLINE
{Graphics.SetStipple[screen, tex]; [] ← Graphics.SetPaintMode[screen, pnt]};
 
SetClipper: 
PROC[w: 
CARDINAL] = {
box: Box;
[box.xmin, box.ymin] ← Map[screen, windows[w].context, 0, windows[w].bottom];
[box.xmax, box.ymax] ← Map[screen, windows[w].context, 650, windows[w].top - header];
ClipBox[windows[w].context, box];
};
 
Wait: 
PROC[t: 
CARDINAL] = {
now: LONG CARDINAL ← MiscDefs.CurrentTime[];
WHILE MiscDefs.CurrentTime[] < now + t DO NULL; ENDLOOP;
};
 
screen: PUBLIC Context;
leftMargin: CARDINAL = 5;
rightMargin: CARDINAL = 585;
header: CARDINAL = 15;
CR: CHARACTER = 015C;
windows: ARRAY [0..10) OF Window;
noWindows: CARDINAL ← 2;
Window: 
TYPE = 
RECORD[
context: Context, file: STRING, 
score: ScorePTR ← NIL,
type: WType, command: POINTER TO CommandProcs, 
top, bottom: REAL
];
WType: TYPE = {physical, graphical, logical, command, unknown};
commandProcs: CommandProcs;
unknownProcs: CommandProcs ← [
Flash, Flash, Flash, Flash, Flash, Flash, , Flash, Erase, , , , , 0];
NullProc: PROC[r: Box] = { };
Initialize[];
END.
ReadCommandLine: 
PROC =  {
ENABLE Directory.Error => { 
DisplayMessage["no such file"]; 
CONTINUE; };
 
char: CHARACTER;
CR: CHARACTER = 015C;
filename: STRING ← [40];
ending: STRING ← [12];
test, error: BOOL ← FALSE;
hardcopy: BOOL ← FALSE;
command, second, period: BOOL ← FALSE;
inputStream: DiskHandle;
inputStream ← NewByteStream["com.cm", Read];
inputStream.reset[inputStream];
DO 
IF inputStream.endof[inputStream] 
THEN 
EXIT;
char ← inputStream.get[inputStream];
command processing
IF command 
THEN 
SELECT char 
FROM
'/ => EXIT;
'n => NULL;
't => test ← TRUE;
'h => hardcopy ← TRUE;
'  => command ← FALSE;
ENDCASE => NULL;
 
IF char = '/ THEN command ← TRUE;
IF command THEN LOOP;
filename processing
SELECT 
TRUE 
FROM
char = CR OR char = ' => NULL;
inputStream.endof[inputStream] => NULL;
char = '. => IF period THEN EXIT ELSE {period ← TRUE; LOOP};
period => {AppendChar[ending, char]; LOOP};
ENDCASE => {AppendChar[filename, char]; LOOP};
 
we have a complete filename 
IF filename.length # 0 
AND ~EqualString[ending, "image"] 
AND ~EqualString[ending, "bcd"] 
THEN {
AppendString[filename, ".music"];
windows[1].file.length ← 0;
AppendString[windows[1].file, filename];
DisplayHeader[black, 1];
DisplayMessage["Please wait-- retrieving file"];
IODefs.WriteLine[filename];
windows[1].command.fileIn[filename, second];
EraseMessage[];
windows[1].command.display[windows[1].score, TRUE];
command line switches (per file)
IF test AND Score.Test[] THEN {error ← TRUE; EXIT};
IF hardcopy THEN Hardcopy[[[215, 747], [249, 761]]];
second ← TRUE};
 
filename.length ← 0;
ending.length ← 0;
period ← FALSE;
ENDLOOP;
 
inputStream.destroy[inputStream];
command line switches (at completion)
IF test AND ~error THEN Quit[[[0, 0], [0, 0]]]; 
IF hardcopy THEN Quit[[[0, 0], [0, 0]]]; 
};