home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-10-27 | 55.7 KB | 1,731 lines |
- (*---------------------------------------------------------------------------
- :Program. MuchMore.mod
- :Author. Fridtjof Siebert
- :Address. Nobileweg 67, D-7000 Stuttgart 40
- :Shortcut. [fbs]
- :Copyright. PD
- :Language. OBERON
- :Translator. Amiga Oberon Compiler V2.03
- :History. V1.0 summer-88: First very slow internal version [fbs]
- :History. V1.1 24-Sep-88: First published version [fbs]
- :History. V1.2 26-Nov-88: Now displays Filelength & Percentage [fbs]
- :History. 27-Nov-88: Mouse can be used instead of Space / BackSpace[fbs]
- :History. V1.3 29-Apr-89: Strong increase in speed, removed WarpText [fbs]
- :History. 29-Apr-89: Now supports Numeric Keys (Home,PgUp etc.) [fbs]
- :History. 29-Apr-89: Now opens Screen as big as gfx.normalDisplay [fbs]
- :History. V1.4 29/30-Apr-89: Asynchronus loading / displaying. Very nice[fbs]
- :History. 30-Apr-89, 00:33: Removed bugs in Filelength & L-Command [fbs]
- :History. 30-Apr-89, 02:21: Added Find-Command [fbs]
- :History. 30-Apr-89, 10:30: Scrolling stops when window is inactive[fbs]
- :History. 01-May-89: Allocates no more unneeded memory for text [fbs]
- :History. 07-May-89: Allocates even less memory now [fbs]
- :History. 14-May-89: Removed deadlock-bug with Find-Window [fbs]
- :History. V1.5 25-May-89: Added print feature [fbs]
- :History. 25-May-89: Removed all imports (apart from Arts) [fbs]
- :History. 26-May-89: inspired by J. Kupfer, I added nk 5 to quit [fbs]
- :History. 26-May-89: Now handle BS correctly [fbs]
- :History. V1.6 02-Jul-89: Now supports several fontstyles and colors [fbs]
- :History. V1.7 03-Jul-89: Is again as fast as it was with 2 colors [fbs]
- :History. 03-Jul-89: Now no more crashes when quitting while print [fbs]
- :History. 07-Jul-89: removed bug with texts of length 0 [fbs]
- :History. V1.8 10-Jul-89: small bug in find-command removed [fbs]
- :History. 10-Jul-89: now found strings are highlighted [fbs]
- :History. 14-Jul-89: nk0 to display fileinfo [fbs]
- :History. V2.0 06-Aug-89: Ported this to OBERON [fbs]
- :History. 06-Aug-89: Added ARP-FileRequester [fbs]
- :History. 07-Aug-89: Added L - (load new file) Command [fbs]
- :History. V2.1 03-Sep-89: no more gurus if an r/w error occures [fbs]
- :History. 03-Sep-89: MM used to execute CSI-Codes backwards. fixed [fbs]
- :History. 03-Sep-89: ping / pong with Shift+Fn / Fn [fbs]
- :History. 03-Sep-89: new command: goto [fbs]
- :History. V2.2 05-Sep-89: will run with any keymapping now [fbs]
- :History. V2.3 17-Sep-89: New command: sleep & Pop-Up feature [fbs]
- :History. 17-Sep-89: "MuchMore -s" will go to sleep immediately [fbs]
- :History. 17-Sep-89: Interprets <CSI>m as <CSI>0m now [fbs]
- :History. V2.4 17-Sep-89: New command: write block "w" [fbs]
- :History. 17-Sep-89: rewritten argument parser to allow quotes [fbs]
- :History. V2.5 18-Sep-89: now uses the 8x8 font set with SetFont [fbs]
- :History. 19-Sep-89: no more scatters memory. Allocates 4K Chunks [fbs]
- :History. V2.6 26-Jun-90: Made MuchMore reentrant [fbs]
- :History. 26-Jun-90: Opens 1-Plane Screen if memory is rare [fbs]
- :History. 26-Jun-90: Asynchronus fast scrolling with Ctrl-Up/Down [fbs]
- :History. 26-Jun-90: Now supports interlaced screens [fbs]
- :History. 08-Aug-90: CLI-Option '-l' to toggle interlaced mode [fbs]
- :History. V2.7 09-Aug-90: no more RethinkDisplay()s,looks good with 2.0 [fbs]
- :History. 10-Aug-90: Supports Kick2.0 ASL-FileRequester [fbs]
- :History. V2.8 26-Dez-90: Leaves space between lines on interlaced scrns[fbs]
- :History. V3.0 04-Jul-91: Supports any non-proportional font now [fbs]
- :History. 04-Jul-91: no more supports '-s' (sleep), was rarely used[fbs]
- :History. 04-Jul-91: new Options -f<font> and -s<size> for font [fbs]
- :Contents. A Soft-Scrolling ASCII-File Printer.
- :Usage. MuchMore {-l|-f<font>|-s<size>} [Text]
- :Remark. Compile: 'Oberon -dm MuchMore'
- :Remark. Link: 'OLink -dm MuchMore OBJ MMQText.o'
- ---------------------------------------------------------------------------*)
-
- (* $StackChk- *)
-
- MODULE MuchMore;
-
- IMPORT ol: OberonLib,
- d: Dos,
- e: Exec,
- ie: InputEvent,
- I: Intuition,
- g: Graphics,
- sys:SYSTEM;
-
- (*-------------------------------------------------------------------------*)
-
- CONST
- empty = "";
- oom = "Out of memory!";
- cof = "Can't open file!";
- usage = "Usage: MuchMore {-l|-f<font>|-s<size>} [Text]";
- rwerr = "Read/Write Error";
- noarp = "Need arp for FileReq";
- conerr = "Console problem";
- MuchText = "MuchMore V3.0 © 1991 AMOK";
- nil = "NIL:";
- w = TRUE;
- f = FALSE;
- MaxLen = 256;
-
- (* Control codes for QText: *)
- plain = CHR(17);
- italic = CHR(18);
- bold = CHR(19);
- boldit = CHR(20);
- ulineon = CHR(21);
- ulineoff = CHR(22);
-
- Italic = 0;
- Bold = 1;
- Ulin = 2;
- Inv = 3;
-
-
- TYPE
- TextLinePtr = POINTER TO TextLine;
- TextLine = STRUCT
- next: TextLinePtr;
- prev: TextLinePtr;
- len: INTEGER;
- size: INTEGER;
- text: ARRAY MaxLen+1 OF CHAR;
- END;
- String = e.STRING;
- StringPtr = e.STRPTR;
- FontData = POINTER TO ARRAY 8, 192, 8 OF CHAR;
-
-
- CONST
- (* FileReqFlags *)
- listFunc = 0;
- gEventFunc = 1;
- addGadFunc = 2;
- newWindFunc = 3;
- newIDCMP = 4;
- doColor = 5;
- doMsgFunc = 6;
- doWildFunc = 7;
-
- TYPE
- STRPTR = POINTER TO CHAR;
-
- FileRequesterPtr = POINTER TO FileRequester;
- FileRequester = STRUCT
- hail: STRPTR; (* Hailing text *)
- ddef: StringPtr; (* Filename array (FCHARS+1) *)
- ddir: StringPtr; (* Directory array (DSIZE+1) *)
- wind: I.WindowPtr; (* Window requesting or NULL *)
- funcFlags: SHORTSET; (* Control. See above. *)
- reserved1: SHORTINT; (* Set this to 0 *)
- function: PROCEDURE; (* Your function, see btdef's *)
- reserved2: LONGINT; (* reserved *)
- END;
-
- WBStartupPtr = POINTER TO STRUCT (message : e.Message)
- process : d.ProcessId;
- segment : e.BPTR;
- numArgs : LONGINT;
- toolWindow : e.STRPTR;
- argList : POINTER TO ARRAY 256 OF STRUCT
- lock : d.FileLockPtr;
- name : e.STRPTR;
- END;
- END;
-
-
- VAR
- Screen: I.ScreenPtr; (* Screen that contains the Text *)
- BM: g.BitMapPtr; (* Screen's BitMap (external) *)
- Window: I.WindowPtr; (* My window *)
- MyFile: d.FileHandlePtr; (* For loading Textfile *)
- MyAttr: g.TextAttr; (* The selected Font attributes *)
- MyFont: g.TextFontPtr; (* The selected Font *)
- FontName: ARRAY 40 OF CHAR; (* My Font Name or "" *)
- FontSize: INTEGER; (* My Font Size *)
- FirstLine: TextLinePtr; (* Saved Text *)
- TopLine: TextLinePtr; (* Points to topmost Line *)
- BottomLine: TextLinePtr; (* Last Line displayed on Screen *)
- LoadLine: TextLinePtr; (* currently loaded Line *)
- LastLine: TextLinePtr; (* Last element of LineList *)
- Name: String; (* Text's Name *)
- lace: BOOLEAN; (* use interlaced screen? *)
- IStr,PStr: String; (* differently used *)
- Buffer: ARRAY 512 OF CHAR; (* Buffer for Reading *)
- RQPos: LONGINT; (* Position within ReadBuffer *)
- RQLen: LONGINT; (* Number of CHARs in Buffer *)
- NumLines: INTEGER; (* Number of Lines on Screen *)
- fontWidth,fontHeight: INTEGER; (* Font size *)
- fontBaseLine: INTEGER; (* Font base line *)
- NumColumns: INTEGER; (* Number of Columns on Screen *)
- PageSize: LONGINT; (* fontHeight*NumLines*NumColumns *)
- LineSize: LONGINT; (* fontHeight*NumColumns *)
- AnzLines: LONGINT; (* Length of Text in Lines *)
- fontdata: FontData; (* Fonts used by QText() *)
- MyLock,OldDir: d.FileLockPtr; (* To Examine and Load File *)
- FileInfo: d.FileInfoBlock; (* to get File's length *)
- FileLength,TextLength: LONGINT;(* Length of File and of Displayed Text *)
- ScreenPos: INTEGER; (* actual position within bitmap *)
- ShowTask: e.Task; (* the task that displays the text *)
- ShowStack: ARRAY 1000 OF LONGINT; (* it's stack *)
- ShowTaskRunning: BOOLEAN; (* is Showtask activated? *)
- mySigBit: INTEGER; (* My SignalBit *)
- mySig: LONGSET; (* My SignalSet = LONGSET{mySigBit} *)
- SignalNewData: BOOLEAN; (* Signal when new data is loaded *)
- SignalAllRead: BOOLEAN; (* send signal at end of text *)
- Done: BOOLEAN; (* Quit *)
- print: BOOLEAN; (* print text *)
- NewText: BOOLEAN; (* load new text *)
- Me: d.ProcessPtr; (* my main task *)
- Info: BOOLEAN; (* is info currently displayed ? *)
- MyMsgPtr: I.IntuiMessagePtr; (* for receiving Messages *)
- i,j: INTEGER; (* count *)
- Scroll: BOOLEAN; (* scrolling or waiting? *)
- Fast: BOOLEAN; (* scrollquick? *)
- Sync: BOOLEAN; (* scroll very quick? *)
- in,out: d.FileHandlePtr; (* i/o for TYPE xxx TO PRT: *)
- fg,bg: INTEGER; (* Text colors *)
- style: SHORTSET; (* Text style *)
- CommLine: POINTER TO CHAR; (* The CLI-commands *)
- ArgPtr: e.STRPTR; (* to get WBArg *)
- wbm: WBStartupPtr; (* WBenchMessage *)
- ri: g.RasInfoPtr; (* Screen's ViewPort's RasInfo *)
- NuScreen: I.NewScreen; (* to open screens *)
- NuWindow: I.NewWindow; (* to open window *)
- Prefs: I.Preferences; (* Preferences (need wbLace) *)
- StrGadget: I.Gadget; (* Gadget for Find-Command *)
- StrInfo: I.StringInfo; (* its special info *)
- arp: LONGINT; (* ArpBase *)
- asl: LONGINT; (* ASL-librarybase *)
- diskFontBase : e.LibraryPtr; (* DiskFont-LibraryBase *)
- body,text,ok: I.IntuiText; (* IntuiTexts for AutoRequest *)
- FR: FileRequester; (* The Requester *)
- Filename: String; (* The Filename (without path) *)
- Dirname: String; (* its path *)
- NewDisp: BOOLEAN; (* need to rebuild Display ? *)
- TextMarkers: ARRAY 10 OF TextLinePtr; (* Marked Positions in text *)
- FindLine: TextLinePtr; (* Last found line *)
- KeyMap: ARRAY 40H OF CHAR; (* console's KeyMap *)
- wreq: e.IOStdReq; (* Request to communicate with the console *)
- console: e.DevicePtr; (* the console.device *)
- ievent: ie.InputEvent; (* InputEvent to convert keycodes *)
-
- WriteName: String; (* File to write Block *)
- savefrom,savesize: LONGINT; (* How much to save? *)
- save: BOOLEAN; (* save block *)
- buffer: POINTER TO LONGINT; (* buffer to save file *)
-
- c: CHAR; (* \ used by GetTextLine(); *)
- le: INTEGER; (* / global for speed *)
-
- eightTimesEight: BOOLEAN; (* is Font-Size = 8x8? *)
- rp: g.RastPortPtr; (* Screen's RastPort *)
-
- (*------ Memory: ------*)
-
- CONST ChunkSize = 4096; (* size of allocated chunks *)
-
- TYPE
- MemChunkPtr = POINTER TO MemChunk; (* chunklist *)
- MemChunk = STRUCT
- prev: MemChunkPtr; (* link *)
- data: ARRAY ChunkSize OF BYTE; (* ChinkSize Bytes of memory *)
- END;
-
- VAR
- MemIndex: INTEGER; (* index in current Chunk *)
- CurChunk: MemChunkPtr; (* current chunk *)
-
- (*----------------- External Assembler Procedures: ----------------------*)
-
-
- (*------ The fastest textoutput-Procedure in the world (maybe): ------*)
-
- PROCEDURE QText{"QText"}(y{1}: INTEGER;
- str{8}: ARRAY OF CHAR;
- bm{9}: g.BitMapPtr;
- fd{10}: FontData);
-
- (*------ Get Font: ------*)
-
- PROCEDURE GetFontData{"GetFontData"}(from{8},to{9}: LONGINT; linelen{7}: INTEGER);
-
- (*-------------------------------------------------------------------------*)
-
- (*------ Console Procedure: ------*)
-
-
- PROCEDURE RawKeyConvert{console,-48}(events{8}:ie.InputEventPtr;
- buffer{9}:LONGINT;
- length{1}:LONGINT;
- keyMap{10}:LONGINT);
-
-
- (*-------------------------------------------------------------------------*)
-
- (*------ DiskFont Procedure: ------*)
-
- PROCEDURE OpenDiskFont*{diskFontBase,-30}(VAR textAttr{8}: g.TextAttr): g.TextFontPtr;
-
-
- (*-------------------------------------------------------------------------*)
-
-
- PROCEDURE Length(VAR s: String): INTEGER;
- VAR l: INTEGER;
- BEGIN l := -1; REPEAT INC(l) UNTIL (l>sys.SIZE(s)) OR (s[l]=0X); RETURN l;
- END Length;
-
-
- PROCEDURE Append(VAR s1: String; s2: StringPtr);
- (* appends s2 to s1 *)
- VAR p,q: INTEGER;
- BEGIN
- p := Length(s1); q := 0;
- WHILE (p<=sys.SIZE(s1)) AND (s2^[q]#0X) AND (p<NumColumns) DO
- s1[p] := s2^[q]; INC(p); INC(q)
- END;
- IF p<=sys.SIZE(s1) THEN s1[p] := 0X END;
- END Append;
-
-
- (*----------------------------- Requester: ------------------------------*)
-
-
- PROCEDURE Request(Text: StringPtr);
- (* wenn Text=NIL, Text = oom *)
-
- VAR
- out: d.FileHandlePtr;
- c: CHAR;
-
- BEGIN
- IF Text=NIL THEN Text := sys.ADR(oom) END;
- IF ol.wbStarted THEN
- body.frontPen := 0; body.backPen := 1; body.drawMode := g.jam2;
- body.leftEdge := 12; body.topEdge := 8;
- text := body; ok := body;
- body.iText := sys.ADR(MuchText);
- body.nextText := sys.ADR(text);
- text.iText := Text; text.topEdge := 22;
- ok.leftEdge := 6; ok.topEdge := 3; ok.iText := sys.ADR(" OK ");
- sys.SETREG(0,I.AutoRequest(NIL,body,NIL,ok,LONGSET{I.rawKey},LONGSET{},320,65));
- ELSE
- out := d.Output();
- sys.SETREG(0,d.Write(out,Text^,Length(Text^)));
- c := 0AX;
- sys.SETREG(0,d.Write(out,c,1));
- END;
- HALT(0);
- END Request;
-
-
- (*-------------------------------------------------------------------------*)
-
- PROCEDURE AllocLine(sz: INTEGER): TextLinePtr;
-
- VAR
- a: TextLinePtr;
- newchunk: MemChunkPtr;
-
- BEGIN
- INC(sz,sys.SIZE(TextLine)-MaxLen); IF ODD(sz) THEN INC(sz) END;
- IF MemIndex+sz<=ChunkSize THEN (* does mem fit into current chunk ? *)
- INC(MemIndex,sz); (* increment index in current chunk *)
- ELSE
- NEW(newchunk); (* allocate new chunk *)
- IF newchunk=NIL THEN Request(NIL) END;
- newchunk.prev := CurChunk; (* link chunk into list *)
- CurChunk := newchunk;
- MemIndex := sz;
- END;
- RETURN sys.ADR(CurChunk.data[MemIndex-sz]);
- END AllocLine;
-
-
- PROCEDURE DisposeLines();
-
- VAR chunk: MemChunkPtr;
-
- BEGIN
- WHILE CurChunk#NIL DO
- chunk := CurChunk.prev;
- DISPOSE(CurChunk);
- CurChunk := chunk;
- END;
- MemIndex := ChunkSize;
- END DisposeLines;
-
- (* $Debug- *)
-
- (*-------------------------------------------------------------------------*)
-
-
- PROCEDURE MakeThink(sync: BOOLEAN);
-
- BEGIN
- I.MakeScreen(Screen);
- g.MrgCop(I.ViewAddress());
- IF sync THEN g.WaitBOVP(sys.ADR(Screen.viewPort)) END;
- END MakeThink;
-
-
- (*------ Clear Display: ------*)
-
-
- PROCEDURE ClearBitMaps;
-
- BEGIN
- g.BltClear(BM.planes[0],2*PageSize,LONGSET{});
- g.BltClear(BM.planes[1],2*PageSize,LONGSET{});
- ScreenPos := 0;
- ri.ryOffset := 0;
- END ClearBitMaps;
-
- (*-------------------------------------------------------------------------*)
-
- (*------ Read one TextLine into a Variable: ------*)
-
-
- PROCEDURE GetTextLine(): TextLinePtr;
- (* returns NIL at EOF *)
-
- VAR
- l: TextLinePtr;
- sz,wd,i,j: INTEGER;
- txt: ARRAY MaxLen+1 OF CHAR;
- num: ARRAY 10 OF INTEGER;
- newcol: BOOLEAN;
- oldstyle: SHORTSET;
-
- PROCEDURE GetCh();
-
- BEGIN
- IF RQPos=RQLen THEN
- RQLen := d.Read(MyFile,Buffer,sys.SIZE(Buffer));
- IF RQLen<0 THEN Request(sys.ADR(rwerr)) END;
- RQPos := 0;
- END;
- IF RQLen=0 THEN c := 0X ELSE
- c := Buffer[RQPos]; IF c=0X THEN c:=1X END;
- INC(RQPos); INC(le);
- END;
- END GetCh;
-
- BEGIN
- IF RQLen=0 THEN RETURN NIL END;
- sz := 0; wd := 0; le := 0;
- IF Italic IN style THEN IF Bold IN style THEN txt[sz] := boldit ELSE txt[sz] := italic END; INC(sz)
- ELSE IF Bold IN style THEN txt[sz] := bold; INC(sz) END END;
- IF Ulin IN style THEN txt[sz] := ulineon; INC(sz) END;
- IF Inv IN style THEN txt[sz] := CHR(fg+4*bg+1); INC(sz)
- ELSIF (fg#1) OR (bg#0) THEN txt[sz] := CHR(bg+4*fg+1); INC(sz) END;
- LOOP
- LOOP
- GetCh;
- IF sys.VAL(CHAR,sys.VAL(SHORTSET,c)*SHORTSET{0..6})#1BX THEN EXIT END;
- i := -1;
- REPEAT
- GetCh;
- IF (c>=30X) AND (c<=39X) THEN
- INC(i); num[i] := 0;
- REPEAT
- num[i] := 10*num[i]+ORD(c)-ORD(30X); GetCh;
- UNTIL (c<30X) OR (c>39X);
- END;
- c := CAP(c);
- UNTIL (c>=3FX(*"?"*)) AND (c<=5AX) OR (c=0X) OR (i=9);
- IF c=4DX THEN
- newcol := f; oldstyle := style; j := 0;
- IF i=-1 THEN i:=0; num[0] := 0 END;
- WHILE (i>=j) AND (sz<MaxLen-1) DO
- CASE num[j] OF
- 0: style := SHORTSET{}; fg := 1; bg := 0; newcol := w |
- 1: INCL(style,Bold) |
- 2: fg := 2; newcol := w (* I hope this is correct *) |
- 3: INCL(style,Italic) |
- 4: INCL(style,Ulin) |
- 7: INCL(style,Inv); newcol := w |
- 30..37: fg := sys.VAL(INTEGER,sys.VAL(SET,num[j]-30) * {0,1}); newcol := w |
- 40..47: bg := sys.VAL(INTEGER,sys.VAL(SET,num[j]-40) * {0,1}); newcol := w |
- ELSE END;
- INC(j);
- END;
- IF (oldstyle#style) AND (sz<MaxLen) THEN
- IF Italic IN style THEN IF Bold IN style THEN txt[sz] := boldit ELSE txt[sz] := italic END;
- ELSE IF Bold IN style THEN txt[sz] := bold ELSE txt[sz] := plain END;
- END;
- INC(sz);
- IF (Ulin IN style) THEN
- IF NOT((Ulin IN oldstyle)) AND (sz<MaxLen) THEN
- txt[sz] := ulineon;
- INC(sz);
- END;
- ELSE
- IF (Ulin IN oldstyle) AND (sz<MaxLen) THEN
- txt[sz] := ulineoff;
- INC(sz);
- END;
- END;
- END;
- IF newcol AND (sz<MaxLen) THEN
- IF Inv IN style THEN txt[sz] := CHR(fg+4*bg+1)
- ELSE txt[sz] := CHR(bg+4*fg+1) END;
- INC(sz);
- END;
- END; (* IF c="m" THEN *)
- END; (* LOOP *)
- CASE c OF
- 20X.. 7FX: txt[sz] := c; INC(sz); INC(wd) |
- 0A1X..0FFX: IF eightTimesEight THEN DEC(c,32) END;
- txt[sz] := c; INC(sz); INC(wd) |
- 8X: (* BS *) IF wd>0 THEN DEC(sz); DEC(wd); END |
- 9X: (* TAB *)
- REPEAT
- txt[sz] := 20X; INC(sz); INC(wd)
- UNTIL (sz=MaxLen) OR (wd=NumColumns) OR (sys.VAL(SET,sz)*{0..2}={}) |
- 0A0X: txt[sz] := 20X; INC(sz); INC(wd) |
- 0AX,0X,0CX: EXIT |
- ELSE END;
- IF (wd>=NumColumns) OR (sz>=MaxLen) THEN EXIT END;
- END;
- l := AllocLine(sz);
- l.len := le; l.size:= sz;
- WHILE sz>0 DO DEC(sz); l.text[sz]:=txt[sz] END;
- RETURN l;
- END GetTextLine;
-
-
- (*------ Write Line to Screen: ------*)
-
-
- PROCEDURE Type(pos: INTEGER; line: TextLinePtr);
-
- VAR
- style: SHORTSET;
- front,back: SHORTINT;
- c: CHAR;
- last,i,x: INTEGER;
- strPtr: POINTER TO ARRAY 256 OF CHAR;
-
- BEGIN
- IF eightTimesEight THEN
- QText(fontHeight*pos,line.text,BM,fontdata);
- ELSE
- i := 1;
- REPEAT
- g.BltClear(sys.VAL(LONGINT,BM.planes[i])+pos*LineSize,LineSize,LONGSET{});
- DEC(i);
- UNTIL i<0;
- g.SetDrMd(rp,g.jam2);
- i := 0; x := 0; style := SHORTSET{}; front := 1; back := 0;
- LOOP
- WHILE line.text[i]<" " DO
- c := line.text[i];
- IF c=0X THEN EXIT END;
- CASE c OF
- plain : style := style - SHORTSET{g.bold,g.italic} |
- italic : EXCL(style,g.bold); INCL(style,g.italic) |
- bold : INCL(style,g.bold); EXCL(style,g.italic) |
- boldit : style := style + SHORTSET{g.bold,g.italic} |
- ulineon : INCL(style,g.underlined) |
- ulineoff: EXCL(style,g.underlined) |
- 1X..10X : DEC(c);
- front := SHORT(ORD(c)) DIV 4;
- back := SHORT(ORD(c)) MOD 4 |
- ELSE END;
- INC(i);
- END;
- strPtr := sys.ADR(line.text[i]); last := i;
- REPEAT INC(i) UNTIL line.text[i]<" ";
- sys.SETREG(0,g.SetSoftStyle(rp,style,-SHORTSET{}));
- g.SetAPen(rp,front);
- g.SetBPen(rp,back);
- g.Move(rp,fontWidth*x,fontHeight*pos+fontBaseLine);
- g.Text(rp,strPtr^,i-last);
- INC(x,i-last);
- END;
- END;
- END Type;
-
-
- (*------ Write Line at Bottom of Text: ------*)
-
-
- PROCEDURE AddBottomLine(Line: TextLinePtr; Fast: BOOLEAN);
-
- VAR
- i,j: INTEGER;
- trash: LONGINT;
- s1,d1,s2,d2: POINTER TO LONGINT;
- a: LONGINT;
-
- BEGIN
- Type(ScreenPos+NumLines,Line);
- a := LineSize*ScreenPos;
- d1 := sys.VAL(LONGINT,BM.planes[0]) + a; s1 := sys.VAL(LONGINT,d1) + PageSize;
- d2 := sys.VAL(LONGINT,BM.planes[1]) + a; s2 := sys.VAL(LONGINT,d2) + PageSize;
- IF Fast THEN
- INC(ri.ryOffset,fontHeight);
- MakeThink(Sync);
- e.CopyMem(s1^,d1^,LineSize);
- e.CopyMem(s2^,d2^,LineSize);
- ELSE
- i := fontHeight;
- REPEAT
- INC(ri.ryOffset);
- IF NOT lace OR ODD(i) THEN MakeThink(TRUE) END;
- j := Screen.width DIV 32;
- REPEAT
- d1^ := s1^; INC(d1,4); INC(s1,4);
- d2^ := s2^; INC(d2,4); INC(s2,4);
- DEC(j);
- UNTIL j=0;
- DEC(i);
- UNTIL i=0;
- END;
- INC(ScreenPos);
- IF ScreenPos=NumLines THEN
- ScreenPos := 0;
- ri.ryOffset := 0;
- END;
- END AddBottomLine;
-
-
- (*------ Write String to Screen: ------*)
-
-
- PROCEDURE Write(String: StringPtr; Fast: BOOLEAN);
-
- VAR text: TextLine;
-
- BEGIN
- text := FirstLine^;
- i := Length(String^);
- IF i>=NumColumns THEN i := NumColumns-1 END;
- text.text[i+1] := 0X;
- text.size := i;
- REPEAT
- text.text[i] := String^[i];
- IF eightTimesEight AND (text.text[i]>80X) THEN DEC(text.text[i],32) END;
- DEC(i)
- UNTIL i<0;
- AddBottomLine(sys.ADR(text),Fast);
- END Write;
-
-
- (*------ Check whether BottomLine.next is NIL or not: ------*)
-
-
- PROCEDURE TryBottomnext(): BOOLEAN;
- (* returns TRUE if BottomLine.next#NIL END; *)
-
- BEGIN
- IF (BottomLine.next=NIL) AND (MyFile#NIL) THEN
- SignalNewData := w;
- sys.SETREG(0,e.Wait(mySig));
- SignalNewData := f;
- END;
- RETURN BottomLine.next#NIL;
- END TryBottomnext;
-
-
- (*------ Scroll down one Line: ------*)
-
-
- PROCEDURE ScrollDown(Fast: BOOLEAN);
-
- BEGIN
- IF TryBottomnext() THEN
- BottomLine := BottomLine.next;
- INC(AnzLines);
- INC(TextLength,BottomLine.len);
- ELSE RETURN END;
- IF AnzLines>=NumLines THEN TopLine := TopLine.next END;
- AddBottomLine(BottomLine,Fast);
- END ScrollDown;
-
-
- (*------ Scroll Up one Line: ------*)
-
-
- PROCEDURE ScrollUp(Fast: BOOLEAN);
-
- VAR
- i,j: INTEGER;
- s1,d1,s2,d2: POINTER TO LONGINT;
- a: LONGINT;
-
- BEGIN
- IF (TopLine.prev#NIL) AND (TopLine.prev.prev#NIL) THEN
- TopLine := TopLine.prev;
- DEC(TextLength,BottomLine.len);
- DEC(AnzLines);
- BottomLine := BottomLine.prev;
- IF ScreenPos=0 THEN
- ri.ryOffset := NumLines*fontHeight;
- ScreenPos := NumLines-1;
- ELSE
- DEC(ScreenPos);
- END;
- Type(ScreenPos,TopLine.prev);
- a := LineSize*ScreenPos;
- s1 := sys.VAL(LONGINT,BM.planes[0]) + a; d1 := sys.VAL(LONGINT,s1) + PageSize;
- s2 := sys.VAL(LONGINT,BM.planes[1]) + a; d2 := sys.VAL(LONGINT,s2) + PageSize;
- IF Fast THEN
- DEC(ri.ryOffset,fontHeight);
- MakeThink(Sync);
- e.CopyMem(s1^,d1^,LineSize);
- e.CopyMem(s2^,d2^,LineSize);
- ELSE
- INC(s1,LineSize); INC(s2,LineSize);
- INC(d1,LineSize); INC(d2,LineSize);
- i := fontHeight;
- REPEAT
- DEC(ri.ryOffset);
- IF NOT lace OR ODD(i) THEN MakeThink(TRUE) END;
- j := Screen.width DIV 32;
- REPEAT
- DEC(d1,4); DEC(s1,4); d1^ := s1^;
- DEC(d2,4); DEC(s2,4); d2^ := s2^;
- DEC(j);
- UNTIL j=0;
- DEC(i);
- UNTIL i=0;
- END;
- END; (* IF TopLine#NIL ... *)
- END ScrollUp;
-
-
- (*------ Undo last Write(): ------*)
-
-
- PROCEDURE DelLine();
-
- VAR
- i,j: INTEGER;
- s1,d1,s2,d2: POINTER TO LONGINT;
- a: LONGINT;
- text: TextLine;
-
- BEGIN
- IF ScreenPos=0 THEN
- ri.ryOffset := NumLines*fontHeight;
- ScreenPos := NumLines;
- END;
- DEC(ScreenPos);
- IF TopLine.prev#NIL THEN
- Type(ScreenPos,TopLine.prev);
- ELSE
- Type(ScreenPos,FirstLine);
- END;
- a := (ScreenPos+1)*LineSize;
- s1 := sys.VAL(LONGINT,BM.planes[0]) + a; d1 := sys.VAL(LONGINT,s1) + PageSize;
- s2 := sys.VAL(LONGINT,BM.planes[1]) + a; d2 := sys.VAL(LONGINT,s2) + PageSize;
- i := fontHeight;
- REPEAT
- DEC(ri.ryOffset);
- IF NOT lace OR ODD(i) THEN MakeThink(TRUE) END;
- j := Screen.width DIV 32;
- REPEAT
- DEC(d1,4); DEC(s1,4); d1^ := s1^;
- DEC(d2,4); DEC(s2,4); d2^ := s2^;
- DEC(j);
- UNTIL j=0;
- DEC(i);
- UNTIL i=0;
- END DelLine;
-
-
- (*------ Convert Integer to String: ------*)
-
-
- PROCEDURE IntToStr(VAR String: String;
- At,Chars: INTEGER;
- int: LONGINT);
-
- VAR
- Cnt: INTEGER;
- Ziff: LONGINT;
-
- BEGIN
- INC(Chars,At);
- IF (Length(String)<Chars) AND (sys.SIZE(String)>=Chars) THEN
- String[Chars] := 0X
- END;
- REPEAT
- DEC(Chars);
- String[Chars] := CHR(int MOD 10 + ORD(30X)); int := int DIV 10;
- UNTIL (Chars=At) OR (int=0);
- WHILE Chars>At DO DEC(Chars); String[Chars] := 20X END;
- END IntToStr;
-
-
- (*-------------------------------------------------------------------------*)
-
-
- PROCEDURE GetLength(t: TextLinePtr);
-
- BEGIN
- TextLength := 0; AnzLines := 0;
- WHILE t#NIL DO INC(AnzLines); INC(TextLength,t.len); t := t.prev END;
- END GetLength;
-
-
- (*-------------------------------------------------------------------------*)
-
-
- PROCEDURE NewDisplay();
- (* Zeichnet ab BottomLine neu *)
-
- VAR
- i: INTEGER;
- l: TextLinePtr;
-
- BEGIN
- ClearBitMaps;
- i := 1;
- l := BottomLine;
- WHILE (i<NumLines) AND (BottomLine.next#NIL) DO
- BottomLine := BottomLine.next;
- INC(i);
- END;
- WHILE (i<NumLines) AND (l.prev#NIL) DO l := l.prev; INC(i) END;
- BottomLine := l;
- GetLength(l);
- Write(sys.ADR(empty),w);
- AddBottomLine(BottomLine,w);
- i := 1;
- WHILE i<NumLines DO
- TopLine := l;
- ScrollDown(w);
- INC(i);
- END;
- Scroll := f;
- END NewDisplay;
-
-
- (*-------------------------------------------------------------------------*)
-
-
- PROCEDURE * ShowProc;
-
- VAR
- l: TextLinePtr;
- Down: BOOLEAN; (* Scroll-Direction *)
- End: BOOLEAN; (* Quit next time Space is pressed ? *)
- i,j,k,m: INTEGER;
- MyMsg: I.IntuiMessage; (* contains Message *)
- Shift: BOOLEAN; (* Shifted Keystroke ? *)
- Alt: BOOLEAN; (* Altered Keystroke ? *)
- win: I.WindowPtr; (* window for Find & Goto *)
- Find,FindStr: ARRAY 80 OF CHAR; (* findstring / capitalized findstring *)
- Goto: ARRAY 10 OF CHAR; (* string containing goto line # *)
- li: LONGINT; (* longint value of line to go to *)
- flen: INTEGER; (* length of findstring *)
- HiText: TextLine; (* Highlited textline *)
- OldHiText: TextLinePtr; (* original, un-hilited text *)
- found: BOOLEAN; (* TRUE, if find was successful *)
- chr: CHAR; (* converted keycode *)
-
-
- PROCEDURE WaitAllRead();
-
- BEGIN
- IF MyFile#NIL THEN
- SignalAllRead := w;
- sys.SETREG(0,e.Wait(mySig));
- SignalAllRead := f;
- END;
- END WaitAllRead;
-
-
- PROCEDURE HiLite(at,len: INTEGER);
- (* Hilites len chars of BottomLine.text starting at position at *)
-
- VAR
- c: INTEGER;
- col: CHAR;
-
- BEGIN
- OldHiText := BottomLine; HiText := OldHiText^; BottomLine := sys.ADR(HiText);
- IF at+len+2<MaxLen THEN
- c := 0; col := 5X;
- WHILE c<at DO
- IF HiText.text[c]<CHR(17) THEN col := HiText.text[c] END;
- INC(c);
- END;
- HiText.text[at] := CHR(17-ORD(col));
- c := at; INC(len,at);
- WHILE c<len DO
- HiText.text[c+1] := OldHiText.text[c];
- INC(c);
- END;
- HiText.text[c+1] := col;
- REPEAT
- HiText.text[c+2] := OldHiText.text[c];
- INC(c);
- UNTIL HiText.text[c-1]=0X;
- END;
- IF HiText.next#NIL THEN HiText.next.prev := sys.ADR(HiText) END;
- IF HiText.prev#NIL THEN HiText.prev.next := sys.ADR(HiText) END;
- END HiLite;
-
-
- PROCEDURE UnHiLite();
-
- BEGIN
- IF HiText.next#NIL THEN HiText.next.prev := OldHiText END;
- IF HiText.prev#NIL THEN HiText.prev.next := OldHiText END;
- END UnHiLite;
-
-
- PROCEDURE ChkBotNewDisp;
-
- VAR
- c: INTEGER;
- t: TextLinePtr;
-
- BEGIN
- IF NOT found THEN
- I.DisplayBeep(NIL);
- IF TopLine.prev=NIL THEN BottomLine := TopLine
- ELSE BottomLine := TopLine.prev END;
- END;
- NewDisplay;
- IF found THEN UnHiLite END;
- END ChkBotNewDisp;
-
-
- PROCEDURE Search(): BOOLEAN;
- (* searches string and hilites it if found. result is TRUE if string found *)
-
- BEGIN
- i := 0;
- IF BottomLine.len<NumColumns THEN m := BottomLine.len ELSE m := NumColumns END;
- WHILE i<BottomLine.size DO
- j := 0; k := i;
- WHILE CAP(BottomLine.text[k])=FindStr[j] DO
- INC(j); INC(k);
- IF FindStr[j]=0X THEN
- sys.SETREG(0,TryBottomnext());
- FindLine := BottomLine;
- HiLite(k-flen,flen);
- found := w; RETURN w;
- END;
- END;
- INC(i);
- END;
- RETURN f;
- END Search;
-
-
- PROCEDURE DisplayInfo();
-
- BEGIN
- (* File: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xx % (xxxxxx of xxxxxx Bytes) xxxxxx Lines *)
- IStr := "XFile: "; IStr[0] := 7X;
- Append(IStr,sys.ADR(Name));
- Append(IStr,sys.ADR(" "));
- IStr[36] := 0X;
- Append(IStr,sys.ADR("xxx % (xxxxxx of xxxxxx Bytes) xxxxxx Lines"));
- IntToStr(IStr,36,3,TextLength * 100 DIV FileLength);
- IntToStr(IStr,43,6,TextLength);
- IntToStr(IStr,53,6,FileLength);
- IntToStr(IStr,67,6,AnzLines-1);
- i := 79;
- REPEAT IStr[i] := 20X; INC(i) UNTIL (i>=255) OR (i>=NumColumns+2);
- IStr[i] := 0X; Write(sys.ADR(IStr),f);
- Info := w;
- END DisplayInfo;
-
- PROCEDURE GetString(VAR str: ARRAY OF CHAR; int: BOOLEAN);
-
- BEGIN
- INC(Screen.height,Screen.height);
- I.MakeScreen(Screen);
- NuWindow.leftEdge := 100;
- NuWindow.topEdge := NumLines * fontHeight DIV 2 - 6 + ri.ryOffset;
- NuWindow.width := NuScreen.width-200;
- NuWindow.height := 12;
- NuWindow.blockPen := 1;
- NuWindow.idcmpFlags := LONGSET{I.inactiveWindow,I.gadgetUp};
- NuWindow.flags := LONGSET{I.rmbTrap,I.activate};
- NuWindow.firstGadget := sys.ADR(StrGadget);
- NuWindow.screen := Screen;
- NuWindow.type := I.customScreen;
- StrGadget.leftEdge := 2;
- StrGadget.topEdge := 2;
- StrGadget.width := NuWindow.width-4;
- StrGadget.height := 8;
- StrGadget.activation := {I.stringCenter,I.relVerify};
- IF int THEN INCL(StrGadget.activation,I.longint) END;
- StrGadget.gadgetType := I.strGadget;
- StrGadget.specialInfo:= sys.ADR(StrInfo);
- StrInfo.buffer := sys.ADR(str);
- StrInfo.maxChars := LEN(str)-1;
- win := I.OpenWindow(NuWindow);
- IF win=NIL THEN RETURN END;
- REPEAT
- sys.SETREG(0,I.ActivateGadget(StrGadget,win,NIL));
- UNTIL win.userPort.sigBit IN
- e.Wait(LONGSET{win.userPort.sigBit,
- Window.userPort.sigBit});
- I.CloseWindow(win);
- Screen.height := Screen.height DIV 2;
- END GetString;
-
-
- PROCEDURE Help; (* executed when HELP or H is pressed *)
-
- BEGIN
- ClearBitMaps();
- Write(sys.ADR(empty),w);
- Write(sys.ADR("\x13 \x15 MuchMore V3.0 Commands: "),w);
- Write(sys.ADR(empty),w);
- Write(sys.ADR(" \x0dSpace\x05,\x0d LMB\x05: Start / Stop scrolling. Quit at end of file."),w);
- Write(sys.ADR(" \x0dBackSpace\x05,\x0d RMB\x05: Start / Stop scrolling backwards."),w);
- Write(sys.ADR(" \x0dUp\x05/\x0dDown\x05: Move one line \x0dup\x05 or \x0ddown\x05."),w);
- Write(sys.ADR(" \x0dShift \x05+\x0d Up\x05/\x0dDn\x05: Start / Stop quick scrolling \x0dup\x05 or \x0ddown\x05."),w);
- Write(sys.ADR(" \x0dAlt\x05+\x0dUp\x05/\x0dDn\x05,\x0d PgUp\x05/\x0dDn\x05: Move one page \x0dup\x05 or \x0ddown\x05."),w);
- Write(sys.ADR(" \x0dT\x05,\x0d Home \x05/\x0d B\x05,\x0d End\x05: Goto \x0dt\x05op / \x0db\x05ottom of text."),w);
- Write(sys.ADR(" \x0dF\x05,\x0dN\x05,\x0dP\x05: \x0dF\x05ind string, \x0dN\x05ext, \x0dP\x05revious occurance"),w);
- Write(sys.ADR(" \x0dShift \x05+\x0d Fn\x05: Set textmarker #n to current position"),w);
- Write(sys.ADR(" \x0dFn\x05: Goto marker #n or set marker #n if it wasn't set yet"),w);
- Write(sys.ADR(" \x0dG\x05: \x0dG\x05oto line #n"),w);
- Write(sys.ADR(" \x0dNK 0\x05: Display Filelength etc."),w);
- Write(sys.ADR(" \x0dShift \x05+\x0d Alt \x05+\x0d O\x05: Create print\x0do\x05ut of the text"),w);
- Write(sys.ADR(" \x0dW\x05: \x0dW\x05rite block between Marker #1 and #2 to file or prt"),w);
- Write(sys.ADR(" \x0dL\x05: \x0dL\x05oad new text (arp necessary)"),w);
- Write(sys.ADR(" \x0dHELP\x05,\x0d H\x05: Show Commands."),w);
- Write(sys.ADR(" \x0dESC\x05,\x0d Q\x05,\x0d X\x05,\x0d NK 5\x05:\x0d Q\x05uit."),w);
- Write(sys.ADR(empty),w);
- Write(sys.ADR("© \x131991 Fridtjof Siebert, Nobileweg 67, D-7000 Stuttgart 40"),w);
- Write(sys.ADR(" \x13Please refer to MuchMore.ReadMe for a detailed copyright notice"),w);
- Write(sys.ADR(empty),w);
- Write(sys.ADR(" This is another product of the Amiga MODULA & OBERON Klub Stuttgart - \x0d\x13AMOK"),w);
- i := (NumLines-24) DIV 2;
- WHILE i>0 DO Write(sys.ADR(empty),w); DEC(i) END;
- LOOP
- e.WaitPort(Window.userPort);
- MyMsgPtr := sys.VAL(LONGINT,e.GetMsg(Window.userPort));
- IF (I.rawKey IN MyMsgPtr.class) AND (MyMsgPtr.code<128) THEN EXIT END;
- e.ReplyMsg(MyMsgPtr);
- END;
- e.ReplyMsg(MyMsgPtr);
- BottomLine := TopLine;
- NewDisplay
- END Help;
-
-
- PROCEDURE Bottom; (* executed when END or B is pressed *)
-
- BEGIN
- WaitAllRead;
- BottomLine := LastLine;
- i := NumLines;
- WHILE (i>1) AND (BottomLine.prev#NIL) DO
- BottomLine := BottomLine.prev;
- DEC(i);
- END;
- NewDisplay
- END Bottom;
-
-
- PROCEDURE Space(): BOOLEAN; (* executed if space or LMB is pressed *)
- (* IF result=w THEN EXIT END *)
-
- BEGIN
- Fast := Shift;
- IF (MyFile=NIL) AND (BottomLine.next=NIL) THEN
- IF End THEN RETURN w ELSE End:=w END;
- ELSE
- End := f;
- END;
- IF Down THEN
- IF Scroll OR End THEN DisplayInfo END;
- Scroll := NOT(Scroll);
- ELSE
- Down := w;
- Scroll := w;
- END;
- RETURN f;
- END Space;
-
-
- PROCEDURE BackSpace; (* executed if backspace or RMB is pressed *)
-
- BEGIN
- Fast := Shift;
- Scroll := Down OR NOT Scroll;
- Down := f
- END BackSpace;
-
-
- BEGIN
-
- sys.SETREG(13,e.exec.thisTask.userData);
- sys.SETREG(0,e.Wait(mySig));
-
- Down := w; End := f; Find[0] := 0X; Goto[0] := 0X;
-
- LOOP
-
- IF NewDisp THEN NewDisp := f; NewDisplay END;
-
- (*------ Type Text: ------*)
-
- LOOP
- IF Scroll THEN
- IF Down THEN
- ScrollDown(Fast);
- Scroll := (MyFile#NIL) OR (BottomLine.next#NIL);
- ELSE
- ScrollUp(Fast);
- Scroll := TopLine.prev#NIL;
- END;
- ELSE
- e.WaitPort(Window.userPort);
- END;
-
- MyMsgPtr := sys.VAL(LONGINT,e.GetMsg(Window.userPort));
-
- IF (MyMsgPtr#NIL) THEN
- IF NOT (I.inactiveWindow IN MyMsgPtr.class) THEN EXIT END;
- EXCL(Window.idcmpFlags,I.mouseButtons);
- e.ReplyMsg(MyMsgPtr);
- e.WaitPort(Window.userPort);
- INCL(Window.idcmpFlags,I.mouseButtons);
- END;
- END;
-
- MyMsg := MyMsgPtr^;
- e.ReplyMsg(MyMsgPtr);
-
- IF MyMsg.code<80H THEN
- IF Info THEN DelLine; Info := f;
- ELSIF MyMsg.code=0FH THEN DisplayInfo; Scroll := f END;
- END;
-
- Shift := {} # {ie.lShift,ie.rShift,ie.capsLock} * MyMsg.qualifier;
- Alt := {} # {ie.lAlt ,ie.rAlt} * MyMsg.qualifier;
- Sync := NOT ( ie.control IN MyMsg.qualifier);
- IF NOT(Sync OR Alt) THEN Shift := TRUE END;
-
- IF I.mouseButtons IN MyMsg.class THEN
-
- IF (ie.leftButton IN MyMsg.qualifier) AND Space() THEN EXIT
- ELSIF ie.rightButton IN MyMsg.qualifier THEN BackSpace END;
-
- ELSIF (I.rawKey IN MyMsg.class) AND (MyMsg.code<80H) THEN
-
- CASE MyMsg.code OF
-
- 40H: IF Space() THEN EXIT END | (* Space *)
-
- 41H: BackSpace | (* BackSpace *)
-
- 4DH,1EH,1FH: (* Down *)
- IF Shift THEN
- Scroll := NOT(Down AND Scroll) OR NOT Fast;
- Fast := w; Down := w;
- ELSE
- IF Alt OR (MyMsg.code=1FH) THEN i:=NumLines-1 ELSE i:=1 END;
- REPEAT
- ScrollDown(NOT Shift);
- DEC(i);
- UNTIL i=0;
- Scroll := f;
- END |
-
- 4CH,3EH,3FH: (* Up *)
- IF Shift THEN
- Scroll := Down OR NOT Scroll OR NOT Fast;
- Fast := w; Down := f;
- ELSE
- IF Alt OR (MyMsg.code=3FH) THEN i:=NumLines-1 ELSE i:=1 END;
- REPEAT
- ScrollUp(NOT Shift);
- Scroll := f;
- DEC(i);
- UNTIL i=0;
- END; |
-
- 44H,43H: (* CR *)
- ScrollDown(f);
- Scroll := f; |
-
- 3DH: BottomLine := FirstLine; NewDisplay | (* Home *)
-
- 1DH: Bottom | (* End *)
-
- 50H..59H: (* F1..F10 *)
- i := MyMsg.code-50H;
- IF NOT Shift AND (TextMarkers[i]#NIL) THEN
- BottomLine := TextMarkers[i];
- IF BottomLine.prev#NIL THEN BottomLine := BottomLine.prev END;
- NewDisplay;
- ELSE
- TextMarkers[i] := TopLine;
- END |
-
- 5FH: Help |
-
- 45H,2EH: IF NOT Alt THEN EXIT END | (* Quit *)
-
- ELSE
-
- IF MyMsg.code<40H THEN (* examine vanilla keycode: *)
-
- chr := KeyMap[MyMsg.code];
-
- CASE chr OF
-
- "t": BottomLine := FirstLine; NewDisplay | (* Home *)
-
- "b": Bottom | (* End *)
-
- "f","n","p": (* Find, Next, Previous *)
-
- IF chr="f" THEN
- GetString(Find,f); FindLine := NIL; flen := 0;
- LOOP
- FindStr[flen] := CAP(Find[flen]);
- IF FindStr[flen]>80X THEN DEC(FindStr[flen],32)
- ELSIF FindStr[flen]=0X THEN EXIT END;
- INC(flen);
- END;
- ClearBitMaps();
- END;
- found := f;
- IF FindStr[0]#0X THEN
- i := NumLines;
- IF FindLine#NIL THEN FindLine := FindLine.next END;
- WHILE (i>0) AND (BottomLine#NIL) AND (BottomLine#FindLine) DO
- BottomLine := BottomLine^.prev; DEC(i);
- END;
- IF (BottomLine#FindLine) OR (BottomLine=NIL) THEN BottomLine := TopLine END;
- IF chr#"p" THEN (* next *)
- WHILE (BottomLine#NIL) AND NOT Search() DO
- sys.SETREG(0,TryBottomnext());
- BottomLine := BottomLine.next;
- END;
- ELSE (* previous *)
- IF BottomLine.prev#NIL THEN BottomLine:=BottomLine.prev END;
- REPEAT
- BottomLine := BottomLine.prev
- UNTIL (BottomLine=NIL) OR Search();
- END;
- ELSE
- BottomLine := NIL
- END;
- ChkBotNewDisp |
-
- "w": (* write block *)
-
- IF (TextMarkers[0]#NIL) AND (TextMarkers[1]#NIL) AND NOT print AND NOT save THEN
- savefrom := 0; savesize := 0;
- l := TextMarkers[0].prev; WHILE l.prev#NIL DO l := l.prev; INC(savefrom,l.len) END;
- l := TextMarkers[1].prev; WHILE l#NIL DO INC(savesize,l.len); l := l.prev END;
- l := TextMarkers[1]; i := NumLines; WHILE (i>1) AND (l#NIL) DO DEC(i); INC(savesize,LONG(l.len)); l := l.next END;
- DEC(savesize,savefrom);
- IF savesize>0 THEN
- GetString(WriteName,f);
- WaitAllRead; save := w; e.Signal(sys.ADR(Me.task),mySig); NewDisplay;
- END
- END |
-
- "o": IF Shift AND Alt AND NOT print AND NOT save THEN (* Printout *)
- PStr := 'TYPE "'; Append(PStr,sys.ADR(Name)); Append(PStr,sys.ADR('" TO PRT:'));
- WaitAllRead; print := w; e.Signal(sys.ADR(Me.task),mySig);
- END |
-
- "l": ClearBitMaps; (* Load Text *)
- MakeThink(TRUE); NewText := w; e.Signal(sys.ADR(Me.task),mySig);
- REPEAT UNTIL (mySigBit IN e.Wait(mySig)) AND NOT NewText |
-
- "g": (* goto *)
- GetString(Goto,w);
- li := SHORT(StrInfo.longInt);
- BottomLine := FirstLine;
- WHILE (li>0) AND TryBottomnext() DO
- BottomLine := BottomLine.next;
- DEC(li)
- END;
- NewDisplay |
-
- "h": Help | (* Help *)
-
- "q","x": EXIT | (* Quit *)
-
- ELSE END;
-
- END; (* IF MyMsg.code<40H THEN *)
-
- END; (* CASE MyMsg.code OF *)
-
- END; (* IF I.rawKey IN MyMsg.class THEN *)
-
- END; (* LOOP *)
-
- Done := w;
- e.Signal(sys.ADR(Me.task),mySig);
- LOOP sys.SETREG(0,e.Wait(LONGSET{})) END;
-
- END ShowProc;
- (* $Debug= *)
-
- (*-------------------------- File Requester: ----------------------------*)
-
-
- PROCEDURE FileReq;
-
-
- TYPE
- TagItem = STRUCT
- typ: LONGINT;
- data: LONGINT;
- END;
-
- CONST
- tagDone = 0;
- tagIgnore = 1;
- tagUser = MIN(LONGINT);
- dummy = tagUser + 80000H;
- taghail = dummy + 1;
- leftEdge = dummy + 3; (* Initialize LeftEdge *)
- topEdge = dummy + 4; (* Initialize TopEdge *)
- width = dummy + 5;
- height = dummy + 6;
- hookFunc = dummy + 7; (* Hook function pointer *)
- file = dummy + 8; (* Initial name of file follows *)
- dir = dummy + 9; (* Initial string for filerequest dir *)
-
-
- TYPE
- NineTags = ARRAY 8 OF TagItem;
-
- VAR
- fr: FileRequesterPtr;
- res: BOOLEAN;
-
-
- PROCEDURE AllocAslRequest {asl,-48} (type{0}: LONGINT; tag{8}..: LONGINT): FileRequesterPtr;
- PROCEDURE FreeAslRequest {asl,-54} (fr{8}: FileRequesterPtr);
- PROCEDURE RequestFile {asl,-42} (fr{8}: FileRequesterPtr): e.ADDRESS;
-
- PROCEDURE FileRequest{arp,-294}(VAR filereq{8}: FileRequester): BOOLEAN;
-
-
- BEGIN
- LOOP
- j := Length(Name);
- WHILE (j>0) AND (Name[j]#":") AND (Name[j]#"/") DO DEC(j) END;
- IF j=0 THEN j := -1 END;
- i := 0;
- WHILE i<=j DO Dirname[i] := Name[i]; INC(i) END; Dirname[i] := 0X;
- j := 0;
- REPEAT Filename[j] := Name[i]; INC(j); INC(i) UNTIL Name[i-1]=0X;
- sys.SETREG(0,I.WBenchToFront());
- IF asl=NIL THEN asl := e.OpenLibrary("asl.library",36) END;
- IF asl#NIL THEN
- fr := AllocAslRequest(0,taghail, sys.ADR(MuchText),
- leftEdge,20,
- topEdge, 20,
- width, 300,
- height, 200,
- file, sys.ADR(Filename),
- dir, sys.ADR(Dirname),
- tagDone);
- IF fr=NIL THEN Request(NIL) END;
- res := RequestFile(fr)#NIL;
- IF res THEN
- Filename := fr.ddef^;
- Dirname := fr.ddir^;
- END;
- FreeAslRequest(fr);
- IF NOT res THEN EXIT END;
- ELSE
- IF arp=NIL THEN arp := e.OpenLibrary("arp.library",34) END;
- IF arp#NIL THEN
- FR.hail := sys.ADR(MuchText);
- FR.ddef := sys.ADR(Filename);
- FR.ddir := sys.ADR(Dirname);
- FR.wind := NIL;
- IF NOT FileRequest(FR) THEN EXIT END;
- ELSE
- Request(sys.ADR(noarp))
- END;
- END;
- Name := Dirname;
- i := Length(Name);
- IF (i>0) THEN
- CASE Name[i-1] OF "/",":": ELSE
- Name[i] := "/"; INC(i);
- END;
- END;
- j := 0;
- LOOP
- Name[i] := Filename[j];
- IF (Name[i]=0X) OR (i=255) THEN EXIT END;
- INC(i);
- INC(j);
- END;
- Name[i] := 0X;
- IF Screen#NIL THEN I.ScreenToFront(Screen) END;
- IF Window#NIL THEN IF I.ActivateWindow(Window) THEN END END;
- RETURN
- END;
- HALT(0);
- END FileReq;
-
-
- (*------------------------------ MAIN: ----------------------------------*)
-
-
- BEGIN
-
- (*------ Init: ------*)
-
- (* These variables are automatically set to zero:
- Screen := NIL; Window := NIL; FirstLine := NIL; TopLine := NIL;
- BottomLine := NIL; MyFile := NIL; AnzLines := 0; Info := f;
- MyLock := NIL; ScreenPos := 0; arp := NIL;
- ShowTaskRunning := f; SignalNewData := f; SignalAllRead := f;
- Done := f; print := f; OldDir := NIL;
- InputOpen := f; save := f; in := NIL; out := NIL;
- MyFont := NIL; diskFontBase := NIL; fontdata := NIL;
- *)
- mySigBit := -1; Me := sys.VAL(d.ProcessPtr,ol.Me);
- WriteName := "PRT:"; MemIndex := ChunkSize; OldDir := Me.currentDir;
- Sync := TRUE;
- FontSize := 8; FontName[0] := 0X;
-
- I.GetPrefs(Prefs,sys.SIZE(Prefs));
- lace := Prefs.laceWB#SHORTSET{};
-
- mySigBit := e.AllocSignal(-1);
- IF mySigBit<0 THEN HALT(0) END;
- mySig := LONGSET{mySigBit};
-
- (*------ Setup: ------*)
-
- NEW(FirstLine);
- (*FirstLine.size := 0;
- FirstLine.text[0] := 0X; *)
-
- (*------ Start: ------*)
-
- IF ol.wbStarted THEN
-
- wbm := ol.wbenchMsg;
-
- IF wbm.numArgs=2 THEN
- ArgPtr := wbm.argList^[1].name; Name := ArgPtr^;
- sys.SETREG(0,d.CurrentDir(wbm.argList^[1].lock));
- ELSE
- sys.SETREG(0,d.CurrentDir(wbm.argList^[0].lock));
- FileReq
- END
-
- ELSE
-
- IF ol.dosCmdLen<=1 THEN
- FileReq
- ELSE
- CommLine := ol.dosCmdBuf;
- LOOP
- i:=0;
- WHILE CommLine^=20X DO INC(CommLine) END;
- IF CommLine^=0AX THEN EXIT END;
- IF CommLine^='"' THEN
- INC(CommLine);
- LOOP
- CASE CommLine^ OF
- '"': INC(CommLine); EXIT |
- 0AX: EXIT |
- ELSE
- Name[i] := CommLine^; INC(i); INC(CommLine);
- END;
- END;
- ELSE
- WHILE (CommLine^#0AX) AND (CommLine^#20X) DO
- Name[i] := CommLine^; INC(i); INC(CommLine);
- END;
- END;
- Name[i]:= 0X;
- IF Name="?" THEN Request(sys.ADR(usage)) END;
- IF Name[0]="-" THEN
- Name[0] := 0X;
- CASE Name[1] OF
- "s": i := 2; FontSize := 0;
- WHILE (Name[i]<='9') AND (Name[i]>='0') AND (FontSize<100) DO
- FontSize := 10*FontSize + ORD(Name[i]) - ORD('0');
- INC(i)
- END;
- IF FontSize>100 THEN FontSize := 100 END |
- "f": i := -1;
- REPEAT
- INC(i);
- FontName[i] := Name[i+2];
- UNTIL (Name[i+2]=0X) OR (i=39);
- FontName[i] := 0X |
- "l": lace := NOT lace |
- END;
- END;
- END;
- END;
-
- END;
-
- LOOP
- MyFile := d.Open(Name,d.oldFile);
- IF MyFile#NIL THEN EXIT END;
- FileReq
- END;
-
-
- (*------------------------ Open Display: --------------------------------*)
-
- (*------ Open Screen: ------*)
-
- IF lace THEN
- NuScreen.viewModes := {g.hires,g.lace};
- NuScreen.height := g.gfx.normalDisplayRows*4
- ELSE
- NuScreen.viewModes := {g.hires};
- NuScreen.height := g.gfx.normalDisplayRows*2
- END;
- NuScreen.width := g.gfx.normalDisplayColumns DIV 32 * 32;
- NuScreen.depth := 2;
- NuScreen.type := I.customScreen+{I.screenQuiet};
- LOOP
- Screen := I.OpenScreen(NuScreen);
- IF Screen#NIL THEN EXIT END;
- DEC(NuScreen.depth);
- IF NuScreen.depth=0 THEN Request(NIL) END;
- END;
- rp := sys.ADR(Screen.rastPort);
- IF FontName[0]#0X THEN
- MyAttr.name := sys.ADR(FontName);
- MyAttr.ySize := FontSize;
- MyFont := g.OpenFont(MyAttr);
- IF MyFont=NIL THEN
- IF diskFontBase=NIL THEN diskFontBase := e.OpenLibrary("diskfont.library",33) END;
- IF diskFontBase#NIL THEN MyFont := OpenDiskFont(MyAttr) END;
- END;
- IF MyFont#NIL THEN g.SetFont(rp,MyFont) END;
- END;
- LOOP
- fontWidth := rp.font.xSize;
- fontHeight := rp.font.ySize;
- IF (fontWidth<=50) OR (fontHeight<=50) THEN EXIT END;
- MyAttr.name := sys.ADR("Topaz.font");
- MyAttr.ySize := 8;
- MyFont := g.OpenFont(MyAttr);
- IF MyFont=NIL THEN HALT(0) END;
- g.SetFont(rp,MyFont);
- END;
- fontBaseLine := rp.font.baseline;
- NumColumns := Screen.width DIV fontWidth;
- NumLines := Screen.height DIV 2 DIV fontHeight;
- LineSize := fontHeight*Screen.width DIV 8;
- PageSize := LineSize*NumLines;
-
- BM := rp.bitMap;
- IF NuScreen.depth=1 THEN BM.planes[1] := BM.planes[0] END;
- ri := Screen.viewPort.rasInfo;
- ClearBitMaps;
- ri.ryOffset := 32;
- Screen.height := fontHeight*NumLines;
- MakeThink(TRUE);
- I.RethinkDisplay;
-
- (*------ Get Font: ------*)
-
- eightTimesEight := FALSE;
- IF (fontHeight=8) AND (fontWidth=8) THEN
- NEW(fontdata);
- IF fontdata=NIL THEN Request(NIL) END;
- IStr[64] := 0X;
- j := 0; c := 20X;
- g.SetDrMd(rp,g.jam2);
- g.SetAPen(rp,1);
- WHILE j<32 DO
- i := 0; WHILE i<48 DO IStr[i] := c; INC(i); INC(c) END;
- IF c=80X THEN c := 0A0X END;
- g.Move(rp,0,fontBaseLine+j);
- g.Text(rp,IStr,48);
- INC(j,8);
- END;
- GetFontData(Screen.bitMap.planes[0],fontdata,NumColumns);
- eightTimesEight := TRUE;
- END;
-
- (*------ Open Window: ------*)
-
- NuWindow.flags := LONGSET{I.rmbTrap,I.activate,I.borderless,I.reportMouse};
- NuWindow.screen := Screen;
- NuWindow.type := I.customScreen;
- NuWindow.topEdge:= 10;
- NuWindow.width := NuScreen.width;
- NuWindow.height := Screen.height-10;
- NuWindow.idcmpFlags := LONGSET{I.inactiveWindow,I.activeWindow,I.rawKey,
- I.mouseButtons};
- Window := I.OpenWindow(NuWindow);
- IF Window=NIL THEN Request(NIL) END;
- ClearBitMaps;
-
- (*------ Get KeyMap: ------*)
-
-
- IF e.OpenDevice("console.device",-1,sys.ADR(wreq),LONGSET{})#0 THEN Request(sys.ADR(conerr)) END;
- console := wreq.device;
- (*ievent.nextEvent := NIL;
- ievent.qualifier := {};
- ievent.eventAddress := NIL; *)
- ievent.class := ie.rawkey;
- i := 0;
- WHILE i<40H DO
- ievent.code := i;
- RawKeyConvert(sys.ADR(ievent),sys.ADR(KeyMap[i]),32,NIL);
- INC(i);
- END;
-
- (*------ Init 2nd Task: ------*)
-
- ShowTask.spLower := sys.ADR(ShowStack);
- ShowTask.spUpper := sys.ADR(ShowStack[999]);
- ShowTask.spReg := ShowTask.spUpper;
- ShowTask.node.type := e.task;
- ShowTask.node.name := sys.ADR("Show.MM");
- ShowTask.node.pri := Me.task.node.pri+1;
- ShowTask.userData := sys.REG(13); (* VarBase *)
-
- e.Forbid;
- e.AddTask(sys.ADR(ShowTask),ShowProc,NIL);
- ShowTaskRunning := w;
- Window.userPort.sigTask := sys.ADR(ShowTask);
- e.Permit;
-
- (*------ Main Load / Display Loop: ------*)
-
- LOOP
-
- fg := 1; bg := 0; style := SHORTSET{};
- RQLen := -1; RQPos := -1;
- AnzLines := 1;
- LastLine := FirstLine;
- BottomLine := FirstLine;
- TopLine := FirstLine;
- TextLength := 0;
- FindLine := NIL;
- i := 0; REPEAT TextMarkers[i] := NIL; INC(i) UNTIL i=10;
-
- MyLock := d.Lock(Name,d.sharedLock);
- IF MyLock=NIL THEN Request(sys.ADR(cof)) END;
- IF NOT d.Examine(MyLock,FileInfo) THEN Request(sys.ADR(cof)) END;
- FileLength := FileInfo.size;
-
- d.UnLock(MyLock); MyLock := NIL;
- IF FileLength=0 THEN Request(sys.ADR("File empty")) END;
-
- (*------ Start displaying & Loading: ------*)
-
- NewDisp := TRUE;
-
- e.Signal(sys.ADR(ShowTask),mySig);
-
- REPEAT
- LoadLine := GetTextLine();
- IF LoadLine=NIL THEN
- d.OldClose(MyFile);
- MyFile := NIL;
- ELSE
- LoadLine.prev := LastLine;
- LastLine.next := LoadLine;
- LastLine := LoadLine;
- END;
- IF SignalNewData THEN e.Signal(sys.ADR(ShowTask),mySig) END;
- UNTIL (MyFile=NIL) OR Done OR NewText;
- IF SignalAllRead THEN e.Signal(sys.ADR(ShowTask),mySig) END;
- REPEAT
- sys.SETREG(0,e.Wait(mySig));
- IF print THEN
- in := d.Open(nil,d.oldFile); out := d.Open(nil,d.newFile);
- sys.SETREG(0,d.Execute(PStr,in,out));
- d.OldClose(in); in := NIL; d.OldClose(out); out := NIL; print := f;
- END;
- IF save THEN
- in := d.Open(Name,d.oldFile);
- IF in=NIL THEN I.DisplayBeep(NIL) ELSE
- ol.New(buffer,savesize);
- IF buffer=NIL THEN Request(NIL) END;
- sys.SETREG(0,d.Seek(in,savefrom,0));
- IF d.Read(in,buffer^,savesize)#savesize THEN
- I.DisplayBeep(NIL); d.OldClose(in); in := NIL;
- ELSE
- d.OldClose(in); in := NIL;
- out := d.Open(WriteName,d.newFile);
- IF out=NIL THEN I.DisplayBeep(NIL) ELSE
- IF d.Write(out,buffer^,savesize)#savesize THEN I.DisplayBeep(NIL) END;
- d.OldClose(out); out := NIL;
- END;
- END;
- DISPOSE(buffer);
- END;
- save := f;
- END;
- IF Done THEN EXIT END;
- UNTIL NewText;
- IF MyFile#NIL THEN d.OldClose(MyFile); MyFile := NIL END;
- DisposeLines();
- FirstLine^.next := NIL; NewText := f;
- REPEAT
- FileReq;
- MyFile := d.Open(Name,d.oldFile);
- UNTIL MyFile#NIL;
- END; (* LOOP *)
-
- CLOSE (* cleanup *)
-
- IF ShowTaskRunning THEN e.RemTask(sys.ADR(ShowTask)) END;
- IF Window#NIL THEN I.CloseWindow(Window) END;
- IF Screen#NIL THEN I.OldCloseScreen(Screen) END;
- IF MyFont#NIL THEN g.CloseFont(MyFont) END;
- IF MyFile#NIL THEN d.OldClose(MyFile) END;
- IF in#NIL THEN d.OldClose(in) END;
- IF out#NIL THEN d.OldClose(out) END;
- IF MyLock#NIL THEN d.UnLock(MyLock) END;
- IF OldDir#NIL THEN sys.SETREG(0,d.CurrentDir(OldDir)) END;
- IF mySigBit>=0 THEN e.FreeSignal(mySigBit) END;
- IF arp#NIL THEN e.CloseLibrary(arp) END;
- IF asl#NIL THEN e.CloseLibrary(asl) END;
- IF diskFontBase#NIL THEN e.CloseLibrary(diskFontBase) END;
-
- END MuchMore.
-
-