DIRECTORY Commander, IO, PFS, Rope, SystemNames, UnixSpawnTCP, Xl, XTk, XTkWidgets; ScannerTool: CEDAR PROGRAM IMPORTS Commander, IO, PFS, Rope, SystemNames, UnixSpawnTCP, Xl, XTk, XTkWidgets ~ BEGIN InstanceRec: TYPE = RECORD [ lock: Xl.TQ, filenameWidget: XTk.Widget ¬ NIL, log: IO.STREAM ¬ NIL, s: REF UnixSpawnTCP.SpawnData ¬ NIL, resolution: INT ¬ 300 ]; Scan: <> XTkWidgets.ButtonHitProcType = { i: REF InstanceRec ~ NARROW[registerData]; fileName: Rope.ROPE ¬ XTkWidgets.GetText[i.filenameWidget]; command: Rope.ROPE; IF i.s#NIL THEN { IO.PutRope[i.log, "\nwait..."]; RETURN; }; command ¬ IO.PutFR["/tmp/ScannerTool-scan-page -r %g %g", IO.int[i.resolution], IO.int[i.resolution]]; command ¬ Rope.Concat[command, " | /tmp/ScannerTool-rotate90 -90"]; command ¬ Rope.Cat[command, " | /tmp/ScannerTool-writeip > ", fileName, "\n"]; BEGIN --debugging IO.PutRope[i.log, "\n"]; IO.PutRope[i.log, command]; END; IO.PutRope[i.log, "\nSTART "]; i.s ¬ UnixSpawnTCP.Spawn[command: command, out: i.log, clientData: i, finish: Finish]; IF i.s = NIL THEN { IO.PutRope[i.log, "can't connect to streams"]; GOTO Oops; }; UnixSpawnTCP.Close[i.s]; EXITS Oops => {}; }; Stop: <> XTkWidgets.ButtonHitProcType = { i: REF InstanceRec ~ NARROW[registerData]; s: REF UnixSpawnTCP.SpawnData ¬ i.s; IF s#NIL THEN { UnixSpawnTCP.Kill[s]; IO.PutRope[i.log, "\nSTOPPED"]; i.s ¬ NIL; } ELSE { IO.PutRope[i.log, "\nnothing to stop..."]; }; }; Finish: UnixSpawnTCP.FinishProc = { i: REF InstanceRec ~ NARROW[clientData]; Protected: PROC = { IO.PutRope[i.log, " END "]; i.s ¬ NIL; }; Xl.CallWithLock[i.lock, Protected]; }; ResolutionHit: XTkWidgets.ButtonHitProcType = { i: REF InstanceRec ~ NARROW[registerData]; i.resolution ¬ NARROW[callData, REF INT]­; }; X11ScannerWidgetCommand: Commander.CommandProc ~ { Ruler: PROC [w, h: INT ¬ -1] RETURNS [ruler: XTk.Widget] = { RETURN [ XTkWidgets.CreateRuler[widgetSpec: [geometry: [size: [w, h]]]] ]; }; lock: Xl.TQ ¬ Xl.CreateTQ[]; i: REF InstanceRec ¬ NEW[InstanceRec ¬ [lock: lock]]; resolutionWidget: XTk.Widget ~ XTkWidgets.CreateChoices[ choices: LIST [ ["300", NEW[INT ¬ 300]], ["200", NEW[INT ¬ 200]], ["150", NEW[INT ¬ 150]], ["100", NEW[INT ¬ 100]], ["75", NEW[INT ¬ 75]] ], hitProc: ResolutionHit, registerData: i ]; label: XTk.Widget ~ XTkWidgets.CreateLabel[[], " resolution:"]; doitWidget: XTk.Widget ~ XTkWidgets.CreateButton[[], "DOIT", [], Scan, i, i, lock]; killWidget: XTk.Widget ~ XTkWidgets.CreateButton[[], "STOP ", [], Stop, i, i, lock]; topControlsContainer: XTk.Widget ~ XTkWidgets.CreateXStack[[], LIST[doitWidget, killWidget, label, resolutionWidget]]; filenameWidget: XTk.Widget ¬ i.filenameWidget ¬ XTkWidgets.CreateLabeledField[label: "filename>", init: "/tmp/slate.ip"]; logWidget: XTk.Widget ~ XTkWidgets.CreateStreamWidget[widgetSpec: [geometry: XTk.G[-1, 50]]]; yContainer: XTk.Widget ~ XTkWidgets.CreateYStack[[], LIST[topControlsContainer, filenameWidget, Ruler[h: 1], logWidget]]; shell: XTkWidgets.Widget ¬ XTkWidgets.CreateShell[child: yContainer, windowHeader: Rope.Concat["Scanner on ", SystemNames.MachineName[]], standardMigration: TRUE]; i.log ¬ XTkWidgets.CreateStream[logWidget]; XTkWidgets.RealizeShell[shell]; }; MakeLocalCopies: PROC[] = { Copy: PROC [from, to: Rope.ROPE] = { Confirm: PFS.NameConfirmProc = {RETURN [TRUE]}; PFS.Copy[from: PFS.PathFromRope[from], to: PFS.PathFromRope[to], confirmProc: Confirm]; }; Copy["/Cedar/ScannerTool/sun4/scan-page", "/tmp/ScannerTool-scan-page"]; Copy["/Cedar/ScannerTool/sun4/writeip", "/tmp/ScannerTool-writeip"]; Copy["/Cedar/ScannerTool/sun4/rotate90", "/tmp/ScannerTool-rotate90"]; }; MakeLocalCopies[]; Commander.Register["ScannerTool", X11ScannerWidgetCommand, "Create a scanner widget"]; END. ScannerTool.mesa Copyright Σ 1992 by Xerox Corporation. All rights reserved. Christian Jacobi, February 6, 1992 10:44 am PST Christian Jacobi, July 14, 1992 11:58 am PDT Jules Bloomenthal July 19, 1992 10:42 pm PDT Make copies for the benefit of shrink wrapping process which does not otherwise understand UnixSpawn Manually made copyies of these files to the Cedar release directory using the real files at /import/system33/bin/scan-page /import/sandpiper-dover/bin/rotate90 /import/sandpiper-dover/bin/writeip Κl–(cedarcode) style•NewlineDelimiter ˜codešœ™Kšœ Οeœ1™˜S—šž˜K˜—šœ žœžœ˜Kšœ žœ˜ Kšœžœ˜!Kšœžœžœžœ˜Kšœžœžœ˜$Kšœ žœ˜Kšœ˜—K˜šŸœ-˜1Kšœžœžœ˜*Kšœžœ(˜;Kšœžœ˜šžœžœžœ˜Kšžœ˜Kšžœ˜K˜—Kšœ žœ.žœžœ˜fK˜CK˜NšžœΟc ˜Kšžœ˜Kšžœ˜Kšžœ˜—Kšžœ˜K˜Všžœžœžœ˜Kšžœ,˜.Kšžœ˜ K˜—K˜Kšžœ ˜Kšœ˜K˜—šŸœ-˜1Kšœžœžœ˜*Kšœžœ˜$šžœžœ˜ šžœ˜K˜Kšžœ˜Kšœžœ˜ Kšœ˜—šžœ˜Kšžœ(˜*Kšœ˜——Kšœ˜—K˜šŸœ˜#Kšœžœžœ ˜(šŸ œžœ˜Kšžœ˜Kšœžœ˜ K˜—Kšœ#˜#K˜—K˜šŸ œ"˜/Kšœžœžœ˜*Kšœžœ žœžœ˜*Kšœ˜K˜—šŸœ˜2šŸœžœžœžœ˜