PSyntax10.Scn.FntzStampElemsAlloc24 Aug 96B`_VersionElemsAllocBeg#Syntax10.Scn.FntPowerMac WindowsPowerMacPowerMac Windows#Syntax10.Scn.FntFFDELR = 0A1X; PageUp = 0C5X; PageDown = 0C6X; Home = 0C8X; BRK = 0ACX;F`_VersionElemsAllocEndSyntax10i.Scn.FntPSyntax10b.Scn.Fnt>+k9>`_#Syntax10.Scn.FntWindows PowerMacPowerMacWindows#Syntax10.Scn.FntJJCBtext: Texts.Text; (* global variable for callback procedure MakeEntry *)PowerMac `_8FoldElemsNew#Syntax10.Scn.FntNNPROCEDURE ^ NoNotify (t: Texts.Text; op: INTEGER; beg, end: LONGINT); PROCEDURE ^ Notify (t: Texts.Text; op: INTEGER; beg, end: LONGINT); PROCEDURE ^ NotifyDir* (op: INTEGER; path, name: ARRAY OF CHAR); PROCEDURE ^ HandleElem* (e: Texts.Elem; VAR m: Texts.ElemMsg); PROCEDURE ^ HandleFrame*(f: Display.Frame; VAR m: Display.FrameMsg);8MarkElemsAlloc!-8#Syntax10.Scn.Fnt VAR m: TextFrames.UpdateMsg; BEGIN m.id := TextFrames.replace; m.text := Texts.ElemBase(e); m.beg := Texts.ElemPos(e); m.end := m.beg + 1; Viewers.Broadcast(m) END Update; 8# 8#Syntax10.Scn.FntUU VAR r: Texts.Reader; t: Texts.Text; pos1, pos2: LONGINT; BEGIN t := Texts.ElemBase(e); pos1 := Texts.ElemPos(e) + 1; Texts.OpenReader(r, t, pos1); Texts.ReadElem(r); IF r.eot THEN pos2 := t.len -1 ELSE pos2 := Texts.Pos(r) - 2 END; Texts.Delete(t, pos1, pos2); Texts.WriteString(w, e.name); Texts.Insert(t, pos1, w.buf) END Restore; 8$8#Syntax10.Scn.Fnt22 VAR s: Texts.Scanner; t: Texts.Text; old, new: ARRAY 256 OF CHAR; res: INTEGER; BEGIN t := Texts.ElemBase(e); Texts.OpenScanner(s, t, Texts.ElemPos(e) + 1); Texts.Scan(s); IF (s.class = Texts.Name) & (s.line = 0) & (s.nextCh = CR) THEN IF e.name # s.s THEN COPY(t(Text).path, old); Strings.Append(delimiter, old); COPY(old, new); Strings.Append(e.name, old); Strings.Append(s.s, new); Files.Rename(old, new, res); IF res > 1 THEN Out.String("-- failed$"); e.Restore END END ELSE Out.String("-- failed$"); e.Restore END END Check; 8 9)8#Syntax10.Scn.Fnt VAR i, d: INTEGER; BEGIN i := 0; LOOP IF CAP(a[i]) = CAP(b[i]) THEN IF a[i] = 0X THEN d := 0; EXIT END ELSIF CAP(a[i]) < CAP(b[i]) THEN d := -1; EXIT ELSE d := 1; EXIT END; INC(i) END; RETURN d END Diff; 8 S58#Syntax10.Scn.FntBB VAR e: Elem; BEGIN NEW(e); e.W := 15 * pixel; e.H := 13 * pixel; e.handle := HandleElem; COPY(name, e.name); e.sel := FALSE; IF isDir THEN e.icon := dirIcon; e.iconSel := dirIconSel; e.iconCopy := dirIconCopy ELSE e.icon := fileIcon; e.iconSel := fileIconSel; e.iconCopy := fileIconCopy END; RETURN e END NewElem; 8 ".8#Syntax10.Scn.Fnt VAR r: Texts.Reader; ch: CHAR; BEGIN Texts.OpenReader(r, t, pos); Texts.Read(r, ch); IF ch # Texts.ElemChar THEN Texts.ReadPrevElem(r) END; IF r.eot THEN RETURN NIL ELSE RETURN r.elem(Elem) END END ThisElem; 8 #^m8QSyntax10.Scn.FntSyntax10b.Scn.Fnt3C VAR r: Texts.Reader; BEGIN Texts.OpenReader(r, t, 0); Texts.ReadElem(r); LOOP IF r.eot THEN e := NIL; d := 1; pos := t.len; RETURN END; IF r.elem IS Elem THEN d := Diff(r.elem(Elem).name, name); IF d >= 0 THEN e := r.elem(Elem); pos := Texts.ElemPos(e); EXIT END END; Texts.ReadElem(r) END END FindElem; 8 f:#8#Syntax10.Scn.Fnt CONST bufSize = 4096; VAR sn, dn: ARRAY 128 OF CHAR; sf, df: Files.File; sr, dr: Files.Rider; len: LONGINT; buf: ARRAY bufSize OF CHAR; BEGIN COPY(src.path, sn); Strings.Append(delimiter, sn); Strings.Append(e.name, sn); COPY(dst.path, dn); Strings.Append(delimiter, dn); Strings.Append(e.name, dn); sf := Files.Old(sn); Files.Set(sr, sf, 0); df := Files.New(dn); Files.Set(dr, df, 0); REPEAT Files.ReadBytes(sr, buf, bufSize); Files.WriteBytes(dr, buf, bufSize - sr.res) UNTIL sr.res # 0; Files.Register(df) END CopyFile; 8 4;#8#Syntax10.Scn.Fnt VAR sn, dn: ARRAY 256 OF CHAR; res: INTEGER; BEGIN COPY(src.path, sn); Strings.Append(delimiter, sn); Strings.Append(e.name, sn); COPY(dst.path, dn); Strings.Append(delimiter, dn); Strings.Append(e.name, dn); Files.Rename(sn, dn, res) END MoveFile; 8 %a8Syntax10.Scn.Fnt]`_VersionElemsAllocBeg#Syntax10.Scn.FntWindows PowerMacPowerMacWindows#Syntax10.Scn.Fnt++ VAR e: Elem; pos: LONGINT; found: INTEGER;PowerMac `_VersionElemsAllocEnd`@`_#Syntax10.Scn.FntWindows PowerMacPowerMacWindows#Syntax10.Scn.FntHH;FindElem(CBtext, name, e, pos, found); Texts.Insert(CBtext, pos, w.buf)PowerMac `_u  BEGIN Texts.WriteElem(w, NewElem(name, isDir)); Texts.WriteString(w, name); Texts.WriteLn(w)  END MakeEntry; 8 &$8NSyntax10.Scn.Fnt~/`_VersionElemsAllocBeg#Syntax10.Scn.FntPowerMac WindowsPowerMacPowerMac Windows#Syntax10.Scn.FntYY t.notify := NoNotify; CBtext := t; Directories.Enumerate(d, MakeEntry); CBtext := NIL;T`_VersionElemsAllocEnd VAR t: Text; f: TextFrames.Frame; x, y: INTEGER; v: Viewers.Viewer; BEGIN NEW(t); Texts.Open(t, ""); COPY(d.path, t.path);  Directories.Enumerate(d, MakeEntry); t.notify := NoNotify; Texts.Append(t, w.buf); t.notify := Notify; NEW(f); TextFrames.Open(f, t, 0); f.handle := HandleFrame; Oberon.AllocateSystemViewer(0, x, y); v := MenuViewers.New( TextFrames.NewMenu(d.path, "^Dir.Menu.Text"), f, TextFrames.menuH, x, y) END OpenDir; 8 [؈-8#Syntax10.Scn.Fnt VAR r: Texts.Reader; beg, end: LONGINT; f: TextFrames.Frame; e: Elem; path: ARRAY 256 OF CHAR; res: INTEGER; BEGIN IF src = NIL THEN RETURN END; end := src.len; Texts.OpenReader(r, src, end); LOOP Texts.ReadPrevElem(r); IF r.eot THEN EXIT END; IF r.elem IS Elem THEN e := r.elem(Elem); beg := Texts.Pos(r); IF e.sel THEN IF op = delete THEN COPY(src.path, path); Strings.Append(delimiter, path); Strings.Append(e.name, path); Files.Delete(path, res); IF res # 0 THEN Out.String("-- failed$") END ELSIF op = copy THEN IF e.icon # dirIcon THEN CopyFile(e, src, dst) ELSE Out.String("--- directories cannot be copied$") END; e.sel := FALSE; e.Update ELSIF op = move THEN MoveFile(e, src, dst); ELSIF op = unselect THEN e.sel := FALSE; e.Update END; Texts.OpenReader(r, src, beg) ELSIF (op = select) & Strings.Match(e.name, mask) THEN e.sel := TRUE; e.Update END; end := beg END END END ForAllElemsDo; 8 ~_8#Syntax10.Scn.FntYY BEGIN Display.CopyPattern(Display.white, copyHull, x, y, Display.invert) END DrawCopy; 8 ~_8#Syntax10.Scn.FntYY BEGIN Display.CopyPattern(Display.white, moveHull, x, y, Display.invert) END DrawMove; 8 V-8#Syntax10.Scn.Fnt** VAR v: Viewers.Viewer; f: Display.Frame; BEGIN v := Viewers.This(x, y); f := v.dsc; WHILE (f # NIL) & ((x < f.X) OR (x > f.X+f.W) OR (y < f.Y) OR (y > f.Y+f.H)) DO f := f.next END; IF (f # NIL) & (f IS TextFrames.Frame) THEN RETURN f(TextFrames.Frame) ELSE RETURN NIL END END ThisFrame; 8 P8#Syntax10.Scn.Fnt VAR f: TextFrames.Frame; BEGIN IF Oberon.Par.frame = Oberon.Par.vwr.dsc THEN f := Oberon.Par.frame.next(TextFrames.Frame) ELSE f := ThisFrame(Oberon.Pointer.X, Oberon.Pointer.Y); END; IF f.text IS Text THEN RETURN f.text(Text) ELSE RETURN NIL END END TargetText; 8 +8#Syntax10.Scn.Fnt# # VAR line: ARRAY 14 OF SET; s: Texts.Scanner; x: Opener; BEGIN line[1] := {}; line[2] := {1..8}; line[3] := {1, 8}; line[4] := {1, 8}; line[5] := {1, 8}; line[6] := {1, 8}; line[7] := {1, 8}; line[8] := {1, 8}; line[9] := {1, 5..8}; line[10] := {1, 5, 7}; line[11] := {1, 5, 6}; line[12] := {1..5}; line[13] := {}; fileIcon := Display.NewPattern(line, 15, 13); line[1] := {}; line[2] := {1..8}; line[3] := {1, 4, 8}; line[4] := {1, 4, 8}; line[5] := {1, 2..6, 8}; line[6] := {1, 4, 8}; line[7] := {1, 4, 8}; line[8] := {1, 8}; line[9] := {1, 5..8}; line[10] := {1, 5, 7}; line[11] := {1, 5, 6}; line[12] := {1..5}; line[13] := {}; fileIconCopy := Display.NewPattern(line, 15, 13); line[1] := {}; line[2] := {1..8}; line[3] := {1..8}; line[4] := {1..8}; line[5] := {1..8}; line[6] := {1..8}; line[7] := {1..8}; line[8] := {1..8}; line[9] := {1..8}; line[10] := {1..5, 7}; line[11] := {1..6}; line[12] := {1..5}; line[13] := {}; fileIconSel := Display.NewPattern(line, 15, 13); line[1] := {}; line[2] := {}; line[3] := {1..10}; line[4] := {1, 10}; line[5] := {1, 10}; line[6] := {1, 10}; line[7] := {1, 10}; line[8] := {1, 10}; line[9] := {1, 10}; line[10] := {1..10}; line[11] := {1, 5}; line[12] := {1..4}; line[13] := {}; dirIcon := Display.NewPattern(line, 15, 13); line[1] := {}; line[2] := {}; line[3] := {1..10}; line[4] := {1, 6, 10}; line[5] := {1, 6, 10}; line[6] := {1, 4..8, 10}; line[7] := {1, 6, 10}; line[8] := {1, 6, 10}; line[9] := {1, 10}; line[10] := {1..10}; line[11] := {1, 5}; line[12] := {1..4}; line[13] := {}; dirIconCopy := Display.NewPattern(line, 15, 13); line[1] := {}; line[2] := {}; line[3] := {1..10}; line[4] := {1..10}; line[5] := {1..10}; line[6] := {1..10}; line[7] := {1..10}; line[8] := {1..10}; line[9] := {1..10}; line[10] := {1..10}; line[11] := {1, 5}; line[12] := {1..4}; line[13] := {}; dirIconSel := Display.NewPattern(line, 15, 13); copyMarker.Draw := DrawCopy; copyMarker.Fade := DrawCopy; moveMarker.Draw := DrawMove; moveMarker.Fade := DrawMove; Texts.OpenWriter(w); ignoreNeutralize := FALSE; oldNotifier := Directories.notify; Directories.notify := NotifyDir; NEW(scratch); Texts.Open(scratch, "Dir.Menu.Text"); scratch.notify := NoNotify; Texts.OpenScanner(s, scratch, 0); openers := NIL; REPEAT Texts.Scan(s) UNTIL s.eot OR (s.line # 0); WHILE s.class = Texts.String DO NEW(x); COPY(s.s, x.pattern); Texts.Scan(s); IF s.class IN {Texts.Name, Texts.String} THEN COPY(s.s, x.cmd); Texts.Scan(s); x.next := openers; openers := x END END END Init; 8 ':8#Syntax10.Scn.Fnt END NoNotify; 8 (88#Syntax10.Scn.Fnt VAR b: Texts.Buffer; r: Texts.Reader; ch: CHAR; pos: LONGINT; BEGIN IF op = TextFrames.delete THEN pos := scratch.len; Texts.Recall(b); Texts.Append(scratch, b); Texts.OpenReader(r, scratch, pos); REPEAT Texts.Read(r, ch) UNTIL r.eot OR (ch = CR) OR (ch = Texts.ElemChar) & (r.elem IS Elem); IF ~r.eot THEN invalidOp := TRUE; t.notify := NoNotify; Texts.Save(scratch, pos, t.len, b); Texts.Insert(t, beg, b); t.notify := Notify; op := TextFrames.replace; end := beg END ELSIF op = TextFrames.insert THEN Texts.OpenReader(r, t, beg); pos := beg; REPEAT Texts.Read(r, ch); INC(pos) UNTIL (pos > end) OR (ch = CR) OR (ch = Texts.ElemChar) & (r.elem IS Elem); IF pos <= end THEN invalidOp := TRUE; t.notify := NoNotify; Texts.Delete(t, beg, end); t.notify := Notify; op := TextFrames.replace; end := beg END END; ignoreNeutralize := TRUE; TextFrames.NotifyDisplay(t, op, beg, end); ignoreNeutralize := FALSE END Notify; 8   ,L8#Syntax10.Scn.Fnt VAR m: UpdateMsg; BEGIN m.op := op; COPY(path, m.path); COPY(name, m.name); Viewers.Broadcast(m); oldNotifier(op, path, name) END NotifyDir; 8 ) )8Syntax10.Scn.FntG8FoldElemsNew#Syntax10.Scn.FntInput.Mouse(keys, x0, y0); marker := Oberon.Arrow; copyHull := e.iconCopy; moveHull := e.icon; REPEAT Input.Mouse(keys, x, y); m.keys := m.keys + keys; IF (ABS(x-x0) > 10) OR (ABS(y-y0) > 10) THEN x0 := moved; IF m.keys = {middle, left} THEN marker := copyMarker ELSE marker := moveMarker END END; Oberon.DrawCursor(Oberon.Mouse, marker, x, y) UNTIL keys = {};Syntax10i.Scn.Fnt 8M@8#Syntax10.Scn.Fntt := Texts.ElemBase(e); COPY(t(Text).path, path); Strings.Append(delimiter, path); Strings.Append(e.name, path); OpenDir(Directories.This(path))88$Syntax10i.Scn.Fnt open filepVersionElemsAllocBeg#Syntax10.Scn.FntPowerMac WindowsPowerMacPowerMac Windows#Syntax10.Scn.Fnti := 0; string := FALSE; ch := name[i]; WHILE ch # 0X DO IF ~((i > 0) & (ch >= "0") & (ch <= "9") OR (CAP(ch) >= "A") & (CAP(ch) <= "Z") OR (ch = delimiter) OR (ch = ".") OR (ch = "$") OR (ch = "&")) THEN string := TRUE END; INC(i); ch := name[i] END; IF string THEN Texts.Write(w, '"') END; Texts.WriteString(w, name); IF string THEN Texts.Write(w, '"') END;pVersionElemsAllocEndW8D CONST moved = -1000; VAR e1: Elem; x, y, x0, y0, dsr, res: INTEGER; keys: SET; t: Texts.Text; path: ARRAY 128 OF CHAR; marker: Oberon.Marker; f: TextFrames.Frame; src, dst: Text; d: Directories.Directory; name: ARRAY 256 OF CHAR; o: Opener; i: INTEGER; string: BOOLEAN; ch: CHAR; BEGIN WITH e: Elem DO WITH m: Texts.CopyMsg DO IF m.e = NIL THEN NEW(e1); m.e := e1 ELSE e1 := m.e(Elem) END; Texts.CopyElem(e, e1); COPY(e.name, e1.name); e1.sel := e.sel; e1.icon := e.icon; e1.iconSel := e.iconSel; e1.iconCopy := e.iconCopy | m: TextFrames.DisplayMsg DO IF ~m.prepare THEN IF e.sel THEN Display.CopyPattern(Display.white, e.iconSel, m.X0, m.Y0+1, Display.replace) ELSE Display.CopyPattern(Display.white, e.icon, m.X0, m.Y0+1, Display.replace) END END | m: TextFrames.TrackMsg DO IF middle IN m.keys THEN e.sel := ~e.sel; e.Update; src := m.frame(TextFrames.Frame).text(Text); track mouse IF m.keys = {middle, right} THEN IF e.icon = dirIcon THEN open subdirectory ELSE d := Directories.Current(); name := ""; IF src.path # d.path THEN Strings.Append(src.path, name); Strings.Append(delimiter, name) END; Strings.Append(e.name, name); o := openers; WHILE (o # NIL) & ~Strings.Match(e.name, o.pattern) DO o := o.next END; IF o = NIL THEN NEW(o); o.cmd := "Edit.Open" END; Oberon.Par.vwr := Viewers.This(m.X, m.Y); Oberon.Par.frame := m.frame; Oberon.Par.pos := scratch.len; Oberon.Par.text := scratch; Texts.WriteString(w, name); Texts.Append(scratch, w.buf); Oberon.Call(o.cmd, Oberon.Par, FALSE, res) END; e.sel := FALSE; e.Update ELSIF (x0 = moved) & e.sel THEN f := ThisFrame(x, y); IF (f # NIL) & (f # m.frame) & (f.text IS Text) THEN dst := f.text(Text); IF m.keys = {middle} THEN ForAllElemsDo(move, src, dst) ELSIF m.keys = {middle, left} THEN ForAllElemsDo(copy, src, dst) END END END END ELSE END END END HandleElem; 8 * -8Syntax10.Scn.Fnte`_VersionElemsAllocBeg#Syntax10.Scn.FntPowerMac WindowsPowerMacPowerMac Windows#Syntax10.Scn.Fnt##Diff(f.text(Text).path, m.path) = 0`_VersionElemsAllocEnd VAR ready: BOOLEAN; e: Elem; keys: SET; x, y, d: INTEGER; t: Texts.Text; pos, pos2: LONGINT; r: Texts.Reader; ch: CHAR; path: ARRAY 256 OF CHAR; dir: Directories.Directory; BEGIN ready := FALSE; WITH f: TextFrames.Frame DO WITH m: Oberon.InputMsg DO IF m.id = Oberon.consume THEN pos := f.carloc.pos; e := ThisElem(f.text, pos); IF (m.ch = CR) OR (m.ch = PageUp) OR (m.ch = PageDown) OR (m.ch = Home) OR (m.ch = BRK) THEN e.Check; TextFrames.RemoveCaret(f); ready := TRUE ELSIF (m.ch = CRSU) OR (m.ch = CRSD) THEN e.Check ELSIF m.ch = DEL THEN invalidOp := FALSE; TextFrames.Handle(f, m); ready := TRUE; IF invalidOp THEN e := ThisElem(f.text, pos); e.Check; TextFrames.RemoveCaret(f) END ELSE Texts.OpenReader(r, f.text, f.carloc.pos); Texts.Read(r, ch); ready := (ch = Texts.ElemChar) & (r.elem IS Elem) END ELSIF (m.id = Oberon.track) & f.hasCar & (m.keys * {middle, right} # {}) THEN e := ThisElem(f.text, f.carloc.pos); IF (e # NIL) & (ThisElem(f.text, TextFrames.Pos(f, x, y)) # e) THEN e.Check END END | m: Oberon.ControlMsg DO IF m.id = Oberon.defocus THEN e := ThisElem(f.text, f.carloc.pos); Input.Mouse(keys, x, y); IF (e # NIL) & ((f # ThisFrame(x, y)) OR (ThisElem(f.text, TextFrames.Pos(f, x, y)) # e)) THEN e.Check END ELSIF (m.id = Oberon.neutralize) & ~ignoreNeutralize & f.hasCar THEN e := ThisElem(f.text, f.carloc.pos); IF e # NIL THEN e.Check END END | m: UpdateMsg DO IF f.text(Text).path = m.path THEN t := f.text; FindElem(t, m.name, e, pos, d); t.notify := TextFrames.NotifyDisplay; CASE m.op OF Directories.insert: IF d # 0 THEN COPY(m.path, path); Strings.Append(delimiter, path); Strings.Append(m.name, path); dir := Directories.This(path); Texts.WriteElem(w, NewElem(m.name, dir # NIL)); Texts.WriteString(w, m.name); Texts.WriteLn(w); Texts.Insert(t, pos, w.buf) END | Directories.delete: IF d = 0 THEN Texts.OpenReader(r, t, pos+1); Texts.ReadElem(r); IF r.eot THEN pos2 := t.len ELSE pos2 := Texts.Pos(r) - 1 END; Texts.Delete(t, pos, pos2) END END; t.notify := Notify END ELSE END END; IF ~ready THEN TextFrames.Handle(f, m) END END HandleFrame; 8 ,8#Syntax10.Scn.Fnt11 BEGIN OpenDir(Directories.Current()) END Open; 8 (?%8#Syntax10.Scn.Fnt VAR name: ARRAY 256 OF CHAR; i: INTEGER; BEGIN In.Open; IF In.Next() = In.string THEN In.String(name) ELSE In.Name(name) END; IF In.Done THEN Directories.Create(name) END END New; 8 -8#Syntax10.Scn.Fnt== BEGIN ForAllElemsDo(delete, TargetText(), NIL) END Delete; 8 5/8#Syntax10.Scn.Fnt VAR ch: CHAR; i: INTEGER; BEGIN In.Open; i := 0; REPEAT In.Char(ch) UNTIL ch >= " "; REPEAT mask[i] := ch; INC(i); In.Char(ch) UNTIL (ch <= " ") OR (ch > 7FX); mask[i] := 0X; ForAllElemsDo(select, TargetText(), NIL) END Select; 8 ?8#Syntax10.Scn.FntAA BEGIN ForAllElemsDo(unselect, TargetText(), NIL) END Deselect; 8E3 MODULE Dir; (** HM  *) IMPORT Files, Fonts, Display, Input, Viewers, Texts, TextFrames, MenuViewers, Oberon, Directories, Strings, In, Out; CONST DELR = 008X; PageUp = 0ACX; PageDown = 0ADX; Home = 091X; BRK = 0B9X; delimiter = Directories.delimiter; left =2; middle = 1; right = 0; delete = 0; copy = 1; move = 2; select = 3; unselect = 4; (*opcodes for ForAllElemsDo*) pixel = LONG(10000); CR = 0DX; DEL = 7FX; CRSU = 0C1X; CRSD = 0C2X; TYPE Elem* = POINTER TO ElemDesc; ElemDesc* = RECORD (Texts.ElemDesc) name*: ARRAY 32 OF CHAR; sel*: BOOLEAN; icon, iconSel, iconCopy: Display.Pattern END; Text* = POINTER TO TextDesc; TextDesc* = RECORD (Texts.TextDesc) path*: ARRAY 128 OF CHAR END; UpdateMsg = RECORD (Display.FrameMsg) op: INTEGER; path, name: ARRAY 128 OF CHAR END; Opener = POINTER TO OpenerDesc; (*list of commands to open files*) OpenerDesc = RECORD pattern, cmd: ARRAY 32 OF CHAR; next: Opener END; VAR scratch: Texts.Text; invalidOp: BOOLEAN; (*TRUE if text operation suppressed in Notify*) ignoreNeutralize: BOOLEAN; w: Texts.Writer; fileIcon, fileIconSel, fileIconCopy: Display.Pattern; (*x=0, y=0, w=15, h=13*) dirIcon, dirIconSel, dirIconCopy: Display.Pattern; (*x=0, y=0, w=15, h=13*) copyHull, moveHull: Display.Pattern; copyMarker, moveMarker: Oberon.Marker; mask: ARRAY 32 OF CHAR; openers: Opener; oldNotifier: Directories.Notifier;  forward declarations PROCEDURE (e: Elem) Update;  PROCEDURE (e: Elem) Restore;  PROCEDURE (e: Elem) Check;  PROCEDURE Diff (VAR a, b: ARRAY OF CHAR): INTEGER;  PROCEDURE NewElem (name: ARRAY OF CHAR; isDir: BOOLEAN): Elem;  PROCEDURE ThisElem (t: Texts.Text; pos: LONGINT): Elem;  PROCEDURE FindElem (t: Texts.Text; name: ARRAY OF CHAR; VAR e: Elem; VAR pos: LONGINT; VAR d: INTEGER);  PROCEDURE CopyFile (e:Elem; src, dst: Text);  PROCEDURE MoveFile (e:Elem; src, dst: Text);  PROCEDURE MakeEntry(d: Directories.Directory; name: ARRAY OF CHAR; isDir: BOOLEAN; VAR continue: BOOLEAN);  PROCEDURE OpenDir (d: Directories.Directory);  PROCEDURE ForAllElemsDo (op: INTEGER; src, dst: Text);  PROCEDURE DrawCopy (x, y: INTEGER);  PROCEDURE DrawMove (x, y: INTEGER);  PROCEDURE ThisFrame (x, y: INTEGER): TextFrames.Frame;  PROCEDURE TargetText(): Text;  PROCEDURE Init;  PROCEDURE NoNotify (t: Texts.Text; op: INTEGER; beg, end: LONGINT);  PROCEDURE Notify (t: Texts.Text; op: INTEGER; beg, end: LONGINT);  PROCEDURE NotifyDir* (op: INTEGER; path, name: ARRAY OF CHAR);  PROCEDURE HandleElem* (e: Texts.Elem; VAR m: Texts.ElemMsg);  PROCEDURE HandleFrame* (f: Display.Frame; VAR m: Display.FrameMsg);  PROCEDURE Open*;  PROCEDURE New*;  PROCEDURE Delete*;  PROCEDURE Select*;  PROCEDURE Deselect*;  BEGIN Init END Dir. System.CopyFiles Dir.Obj => $System:Dir.Obj~