DIRECTORY BluejayTool, ChoiceButtons USING [BuildEnumTypeSelection, BuildTextPrompt, EnumTypeRef, PromptDataRef, SelectionNotifierProc], Containers USING [ChildXBound, ChildYBound, Container, Create], Convert USING [IntFromRope], IO, Jukebox, Labels USING [Create], Menus USING [AppendMenuEntry, CreateEntry, CreateMenu, Menu, MenuProc], Rope USING [Cat, Equal, ROPE, Size], TypeScript USING [Create], VFonts USING [FontHeight], ViewerClasses USING [Viewer], ViewerEvents USING [EventProc, RegisterEventProc], ViewerOps USING [OpenIcon, PaintViewer], ViewerIO USING [CreateViewerStreams], ViewerTools USING [GetContents, SetContents], VoiceStream USING [StartMonitor, StartServer]; BluejayToolImpl: CEDAR PROGRAM IMPORTS ChoiceButtons, Containers, Convert, IO, Jukebox, Labels, Menus, Rope, TypeScript, VFonts, ViewerEvents, ViewerOps, ViewerIO, ViewerTools, VoiceStream EXPORTS BluejayTool SHARES BluejayTool = BEGIN container: Containers.Container _ NIL; jukeboxNameViewer: ChoiceButtons.PromptDataRef; jukeboxSizeViewer: ChoiceButtons.PromptDataRef; nTunesViewer: ChoiceButtons.PromptDataRef; tunesInUse: ViewerClasses.Viewer _ NIL; chirpsInUse: ViewerClasses.Viewer _ NIL; chirpViewer: ViewerClasses.Viewer _ NIL; jukebox: Jukebox.Handle _ NIL; TrueFalseRecord: TYPE = RECORD [ value: BOOL, trueRope: Rope.ROPE, falseRope: Rope.ROPE, button: ChoiceButtons.EnumTypeRef ]; TrueFalse: TYPE = REF TrueFalseRecord; gcFixup: TrueFalse _ NEW[TrueFalseRecord _ [FALSE, "Correct inconsistencies during garbage collection", "Don't correct inconsistencies during garbage collection", NIL]]; btDebug: TrueFalse _ NEW[TrueFalseRecord _ [FALSE, "Enter Bugbane on uncaught signals", "Unwind after uncaught signals", NIL]]; jukeboxSize: LONG INTEGER; nTunes: LONG INTEGER; stream: IO.STREAM _ NIL; Command: TYPE = {create, open, close, scavenge, delete}; SetTrueFalse: ChoiceButtons.SelectionNotifierProc = { tf: TrueFalse _ NARROW[clientdata]; tf.value _ Rope.Equal[name, tf.trueRope]; }; Init: PROC = { streamViewer: ViewerClasses.Viewer _ NIL; lineHeight: INT _ VFonts.FontHeight[] + 3; data: Rope.ROPE _ NIL; myMenu: Menus.Menu _ Menus.CreateMenu[]; x: INTEGER _ 1; y: INTEGER _ 0; newline: BOOL _ FALSE; child: ViewerClasses.Viewer; LabelText: PROC[name, data: Rope.ROPE] RETURNS [p: ChoiceButtons.PromptDataRef] = { child: ViewerClasses.Viewer; p _ ChoiceButtons.BuildTextPrompt[viewer: container, x: x+1, y: y, title: name, default: data]; child _ p.promptButton; x _ 1; y _ child.wy + child.wh + 1; RETURN[p] }; Label: PROC[name: Rope.ROPE, newline: BOOL] RETURNS [ViewerClasses.Viewer] = { child _ Labels.Create[ info: [name: name, parent: container, border: FALSE, wy: y, wx: x+1], paint: TRUE ]; x _ IF newline THEN 1 ELSE child.wx + child.ww - 1; y _ IF newline THEN child.wy + child.wh - 1 ELSE child.wy; RETURN[child]; }; Menus.AppendMenuEntry[menu: myMenu, entry: Menus.CreateEntry[name: "Create", proc: command, clientData: NEW[Command _ create]]]; Menus.AppendMenuEntry[menu: myMenu, entry: Menus.CreateEntry[name: "Open", proc: command, clientData: NEW[Command _ open]]]; Menus.AppendMenuEntry[menu: myMenu, entry: Menus.CreateEntry[name: "Close", proc: command, clientData: NEW[Command _ close]]]; Menus.AppendMenuEntry[menu: myMenu, entry: Menus.CreateEntry[name: "Scavenge", proc: command, clientData: NEW[Command _ scavenge]]]; Menus.AppendMenuEntry[menu: myMenu, entry: Menus.CreateEntry[name: "Delete", proc: command, clientData: NEW[Command _ delete]]]; container _ Containers.Create[[name: "Bluejay", iconic: TRUE, openHeight: 300, menu: myMenu, scrollable: FALSE]]; jukeboxNameViewer _ LabelText[name: "Jukebox name:", data: "test"]; jukeboxSizeViewer _ LabelText[name: "Size:", data: "5000"]; nTunesViewer _ LabelText[name: "# Tunes:", data: "20"]; tunesInUse _ Label[name: "Tunes In Use: unknown ", newline: FALSE]; chirpsInUse _ Label[name: "Chirps In Use: unknown ", newline: TRUE]; gcFixup.button _ ChoiceButtons.BuildEnumTypeSelection[viewer: container, x: 0, y: y, buttonNames: LIST[gcFixup.trueRope, gcFixup.falseRope], default: gcFixup.falseRope, notifyClientProc: SetTrueFalse, clientdata: gcFixup, style: flipThru]; y _ y+lineHeight+3; btDebug.button _ ChoiceButtons.BuildEnumTypeSelection[viewer: container, x: 0, y: y, buttonNames: LIST[btDebug.trueRope, btDebug.falseRope], default: btDebug.falseRope, notifyClientProc: SetTrueFalse, clientdata: btDebug, style: flipThru]; y _ y+lineHeight+3; TRUSTED { y _ VoiceStream.StartMonitor[container: container, y: y]; }; streamViewer _ TypeScript.Create[info: [parent: container, wx: 0, wy: y, ww: 500, wh: 800, border: FALSE]]; Containers.ChildXBound[container, streamViewer]; Containers.ChildYBound[container, streamViewer]; [out: stream] _ ViewerIO.CreateViewerStreams[viewer: streamViewer, name: "Bluejay output"]; ViewerOps.OpenIcon[container]; [] _ ViewerEvents.RegisterEventProc[proc: destroyProc, event: destroy]; }; checkParms: PROC = { r: Rope.ROPE; r _ ViewerTools.GetContents[jukeboxSizeViewer.textViewer]; IF Rope.Size[r] = 0 THEN jukeboxSize _ 0 ELSE jukeboxSize _ Convert.IntFromRope[r]; r _ ViewerTools.GetContents[nTunesViewer.textViewer]; IF Rope.Size[r] = 0 THEN nTunes _ 0 ELSE nTunes _ Convert.IntFromRope[r]; }; GetBluejayLogStream: PUBLIC PROC RETURNS [IO.STREAM] = { RETURN[stream]; }; UpdateViewer: PUBLIC PROC = { name: Rope.ROPE _ NIL; nPages, nTunes: INT _ 0; TRUSTED { IF jukebox # NIL THEN [name: name, nPages: nPages, nTunes: nTunes] _ Jukebox.Info[jukebox]; }; IF name = NIL THEN { container.name _ "Bluejay (no jukebox open)"; } ELSE { container.name _ Rope.Cat["Bluejay: jukebox is ", name]; ViewerTools.SetContents[viewer: nTunesViewer.textViewer, contents: IO.PutFR["%d", IO.int[nTunes]], paint: TRUE]; ViewerTools.SetContents[viewer: jukeboxSizeViewer.textViewer, contents: IO.PutFR["%d", IO.int[nPages]], paint: TRUE]; }; ViewerOps.PaintViewer[container, caption]; }; command: Menus.MenuProc = TRUSTED { command: REF Command _ NARROW[clientData]; checkParms[]; SELECT command^ FROM create => { name: Rope.ROPE _ ViewerTools.GetContents[jukeboxNameViewer.textViewer]; Jukebox.CreateJukebox[nPages: jukeboxSize, nTunes: nTunes, name: name]; UpdateViewer[]; }; open => { name: Rope.ROPE _ ViewerTools.GetContents[jukeboxNameViewer.textViewer]; jukebox _ Jukebox.OpenJukebox[name: name]; UpdateViewer[]; }; close => { jukebox _ Jukebox.CloseJukebox[jukebox]; UpdateViewer[]; }; scavenge => { i, j: LONG INTEGER; [nFree: i, recovered: j] _ Jukebox.Scavenge[jukebox, stream, gcFixup.value]; IO.PutF[stream, "Recovered %d chirps, free list size now %d.\n", IO.int[j], IO.int[i]]; }; delete => { name: Rope.ROPE _ ViewerTools.GetContents[jukeboxNameViewer.textViewer]; Jukebox.DeleteJukebox[name: name]; }; ENDCASE; }; destroyProc: ViewerEvents.EventProc = TRUSTED { IF viewer # container OR event # destroy THEN RETURN; IF jukebox # NIL THEN jukebox _ Jukebox.CloseJukebox[jukebox ! ANY => CONTINUE]; }; Init[]; TRUSTED { VoiceStream.StartServer[stream]; }; END. Last Edited by: Swinehart, March 1, 1983 3:11 pm Last Edited by: Stewart, May 22, 1983 6:37 pm Stewart, June 4, 1983 6:28 pm, cleanup, add tunes and chirps in use stuff Stewart, December 27, 1983 10:30 am, Cedar 5 ~File: BluejayToolImpl.mesa This file contains routines to initialize the Bluejay window and top-level command processing routines. Last edited by: John Ousterhout July 28, 1982 5:09 pm Last Edited by: Stewart, December 30, 1983 11:17 am Viewers for outer container and parameters: Variables for parameters: Typescript handle: Enumerated type for different commands (so we can have one central command processing routine and thereby only have to declare signal handlers once). Create menu entries. Create the container that will hold all this stuff. Add parameter labels and buttons. Create information area for voice streams. Create a stream for the log. Make sure we get notified if the viewer is destroyed. This procedure reads in the strings from parameter viewers and updates the integers that they correspond to. ViewerTools.SetContents[viewer: tunesInUse, contents: IO.PutFR["Tunes In Use: %d", IO.int[0]], paint: TRUE]; ViewerTools.SetContents[viewer: chirpsInUse, contents: IO.PutFR["Chirps In Use: %d", IO.int[0]], paint: TRUE]; ENABLE { VoiceStream.Error => { MessageWindow.Append[rope, TRUE]; MessageWindow.Blink[]; IF btDebug.value THEN REJECT; CONTINUE; }; Jukebox.Error => { MessageWindow.Append[rope, TRUE]; MessageWindow.Blink[]; IF btDebug.value THEN REJECT; CONTINUE; }; Jukebox.MissingChirp => { MessageWindow.Append["Missing chirp.", TRUE]; MessageWindow.Blink[]; IF btDebug.value THEN REJECT; CONTINUE; }; Jukebox.EOF => { MessageWindow.Append["End of jukebox file.", TRUE]; MessageWindow.Blink[]; IF btDebug.value THEN REJECT; CONTINUE; }; AMEvents.Debugging, AMEvents.Debugged => REJECT; ABORTED => CONTINUE; ANY => { MessageWindow.Append["Unknown error signal.", TRUE]; MessageWindow.Blink[]; IF btDebug.value THEN REJECT; CONTINUE; }; }; Create jukebox. Open jukebox. Close jukebox. Scavenge. The following procedure is called when the viewer is destroyed. It cleans up the jukebox. Ê n˜Jšœ™Jšœ@™@Jšœ&™&Jšœ™Jšœ&™&Jšœ3™3J™šÏk ˜ J˜ Jšœœ^˜qJšœ œ/˜?Jšœœ˜Jšœ˜J˜Jšœœ ˜Jšœœ<˜GJšœœœ˜$Jšœ œ ˜Jšœœ˜Jšœœ ˜Jšœ œ ˜2Jšœ œ˜(Jšœ œ˜%Jšœ œ˜-Jšœ œ˜.J˜—Jšœœ˜Jšœ%œo˜Jšœ ˜Jšœ˜Jš˜J˜Jšœ+™+J˜Jšœ"œ˜&Jšœ/˜/Jšœ/˜/Jšœ*˜*Jšœ#œ˜'Jšœ$œ˜(Jšœ$œ˜(J˜J˜šœœœ˜ Jšœœ˜ Jšœœ˜Jšœœ˜Jšœ!˜!J˜—J˜Jšœ œœ˜&Jšœœœrœ˜©JšœœœHœ˜J˜Jšœ™J˜Jšœ œœ˜Jšœœœ˜J˜Jšœ™J˜Jšœœœœ˜J˜JšœJ™JJšœJ™JJ˜Jšœ œ+˜8J˜šœ5˜5Jšœœ ˜#Jšœ)˜)J˜—J˜šÏnœœ˜Jšœ%œ˜)Jšœ œ˜*Jšœ œœ˜J˜(Jšœ™Jšœœ˜Jšœœ˜Jšœ œœ˜Jšœ˜šž œœœ˜&Jšœ#˜*J˜Jšœ˜Jšœ_˜_Jšœ˜J˜J˜Jšœ˜ J˜—š žœœ œ œœ˜LJ˜šœ˜šœ.œ˜4J˜—Jšœœ˜—Jšœœ œœ˜3Jšœœ œœ ˜:Jšœ˜J˜—J˜˜#˜(J˜Jšœ œ˜$——˜#˜&J˜Jšœ œ˜"——˜#˜'J˜Jšœ œ˜#——˜#˜*J˜Jšœ œ˜&——˜#˜(J˜Jšœ œ˜$J˜——Jšœ3™3J˜šœ8œ˜>Jšœ+œ˜3J˜—Jšœ!™!J˜JšœC˜CJšœ;˜;Jšœ7˜7Jšœ>œ˜EJšœ@œ˜FJ˜Jšœbœ‰˜ïJ˜Jšœ˜J˜Jšœbœ‰˜ïJ˜Jšœ˜J˜Jšœ*™*J˜Jšœ?˜FJ˜Jšœ™J˜˜:Jšœ(œ˜0—J˜0J˜0˜BJ˜—J˜J˜J˜Jšœ5™5J˜J˜GJšœ˜J˜—šœ œ˜JšœF™FJšœ%™%Jšœœ˜ J˜:Jšœœ˜(Jšœ&˜*J˜5Jšœœ ˜#Jšœ!˜%Jšœ˜—J˜šžœœœœœœœ ˜KJ˜—šž œœœ˜Jšœ œ˜Jšœœ˜šœ˜ J˜[J˜—šœœœ˜J˜-Jšœ˜—šœ˜J˜8˜8Jšœ œ œ˜)Jšœœ˜ —˜=Jšœ œ œ˜)Jšœœ˜ —šœ+™+Jšœ œœ ™2Jšœœ™ —šœ,™,Jšœ œœ ™3Jšœœ™ —Jšœ˜—J˜*Jšœ˜J˜J˜—šœœ˜#š™šœ™Jšœœ™!J™Jšœœœ™Jšœ™ Jšœ™—šœ™Jšœœ™!J™Jšœœœ™Jšœ™ Jšœ™—šœ™Jšœ'œ™-J™Jšœœœ™Jšœ™ Jšœ™—šœœ™Jšœ-œ™3J™Jšœœœ™Jšœ™ Jšœ™—Jšœ)œ™0Jšœœ™šœ™Jšœ.œ™4J™Jšœœœ™Jšœ™ Jšœ™—Jšœ™J™—Jšœ œ œ ˜*J˜ J˜Jšœ ˜˜Jšœ™J˜˜ Jšœ œ9˜HJ˜GJ˜J˜J˜—Jšœ ™ J˜˜ Jšœ œ9˜HJ˜*J˜J˜J˜—Jšœ™J˜šœ ˜ J˜(J˜Jšœ˜J˜—Jšœ ™ J˜šœ ˜ Jšœœœ˜JšœL˜Lšœ>˜@Jšœ œ ˜—Jšœ˜—˜ Jšœ œ9˜HJ˜"J˜J˜—Jšœ˜—Jšœ˜J˜—Jšœ?™?Jšœ™J˜šœ&œ˜/Jšœœœœ˜5Jšœ?œœ˜PJšœ˜J˜—J˜Jšœ&˜-J˜Jšœ˜Jšœ0˜0Jšœ-˜-JšœI˜IJšœ,˜,J˜—…—D-0