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