home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* COPYMAUS.PAS *)
- (* (c) 1989 E.v.Pappenheim & TOOLBOX *)
- (* ------------------------------------------------------ *)
- {$R-,S-,I-,D-,F-,V-,B-,N-,L+ }
- {$M 1024,0,0 }
- PROGRAM CopyMaus;
-
- USES Crt, DOS;
-
- CONST
- version = 'Copymaus Ver. 1.2';
- hotkey = $1E00;
- hotkeyname = '<Alt><A>';
- maxcol = 80;
- maxrow = 25;
-
- TYPE
- ScreenType = ARRAY [1..maxrow, 1..maxcol] OF WORD;
-
- VAR
- screen : ^ScreenType;
- saveint16 : POINTER;
- savess, savesp,
- progss, progsp,
- videosegment,
- ch : WORD;
- pageoffset : WORD ABSOLUTE $0040:$004e;
-
- CONST
- cursor = #219;
- num : WORD = 0;
- written : WORD = 0;
- cr = $1c0d;
- crtl_q = $1011;
- crtl_i = $1709;
- titel1 : STRING[41] =
- ' C O P Y M A U S Links => Blockanfang';
- titel2 : STRING[40] =
- ' Rechts => Blockende Ende => ░░░░░';
- indentstr : SET OF CHAR = ['I','n','d','e','n','t'];
- mouseint = $33;
- maxnum = 1024;
-
- VAR
- buffer : ScreenType;
- charbuffer : ARRAY[1..maxnum] OF WORD;
- y, xt,
- a, b,
- xa, ya,
- xe, ye : BYTE;
- xm, ym,
- n, m, x : WORD;
- indent,
- again,
- inverted : BOOLEAN;
- mregs : Registers;
-
- FUNCTION GetKey : WORD;
- INLINE($31/$c0/$9c/$ff/$1e/SaveInt16);
-
- PROCEDURE ReverseAttribut(col, row : BYTE);
- VAR
- VideoWord : RECORD CASE BYTE OF
- 1: (v : WORD);
- 2: (c, a : BYTE);
- END;
- BEGIN
- WITH VideoWord DO BEGIN
- v := screen^[row, col];
- a := (a MOD 16) * 16 + a SHR 4;
- screen^[row, col] := v;
- END;
- inverted := TRUE;
- END;
-
- PROCEDURE InitCopyMaus;
- VAR
- regs : Registers;
- BEGIN
- regs.ah := $0f;
- Intr($10, regs);
- IF regs.al = 7 THEN VideoSegment := $b000
- ELSE VideoSegment := $b800;
- screen := Ptr(VideoSegment + pageoffset shr 4, 0);
- again := FALSE;
- inverted := FALSE;
- indent := FALSE;
- END;
-
- FUNCTION TestMouse : INTEGER; (* Maus installiert ? *)
- BEGIN
- mregs.ax := 0;
- Intr(mouseint, mregs);
- IF (mregs.ax = $FFFF) THEN TestMouse := mregs.bx
- ELSE TestMouse := 0;
- END;
-
- PROCEDURE InitMouse; (* Maus-Reset *)
- BEGIN
- mregs.ax := 0; Intr(mouseint, mregs);
- END;
-
- PROCEDURE ShowMouse; (* Mauscursor initialisieren *)
- VAR
- attr : BYTE;
- BEGIN
- mregs.ax := 4; (* Position setzen *)
- mregs.cx := Pred(WhereX) * 8;
- mregs.dx := Pred(WhereY) * 8;
- Intr(mouseint, mregs);
- mregs.ax := 7; (* horizontaler Bewegungsbereich *)
- mregs.cx := 0;
- mregs.dx := 639;
- Intr(mouseint, mregs);
- mregs.ax := 8; (* vertikaler Bewegungsbereich *)
- mregs.cx := 0;
- mregs.dx := 399;
- Intr(mouseint, mregs);
- mregs.ax := 10; (* Mauscursor Form und Farbe *)
- mregs.bx := 0;
- attr := 112;
- mregs.cx := attr SHL 8;
- mregs.dx := mregs.cx + Ord(cursor);
- Intr(mouseint, mregs);
- mregs.ax := 1; (* Mauscursor sichtbar machen *)
- intr(mouseint, mregs);
- END;
-
- PROCEDURE HideMouse; (* Mauscursor unsichtbar machen *)
- BEGIN
- mregs.ax := 2; Intr(mouseint, mregs);
- END;
-
- PROCEDURE GetMouse(VAR x, y : WORD);
- BEGIN (* Mausposition ermitteln *)
- mregs.ax := 3;
- Intr(mouseint, mregs);
- x := mregs.cx; y := mregs.dx;
- x := Succ(x DIV 8); y := Succ(y DIV 8);
- END;
-
- FUNCTION WhichButton : WORD;
- BEGIN (* Welcher Knopf gedrückt ? *)
- mregs.ax := 3;
- Intr(mouseint, mregs);
- WhichButton := mregs.bx;
- END;
-
- FUNCTION MouseinXY(x1, x2, y1, y2 : WORD) : BOOLEAN;
- VAR
- x, y : WORD; (* Ist die Maus im angegebenen Feld ? *)
- BEGIN
- GetMouse(x,y);
- MouseinXY := (x >= x1) AND (x <= x2) AND
- ( y >= y1) AND (y <= y2);
- END;
-
- PROCEDURE Restore(x, y : BYTE);
- BEGIN (* Originalzeichen an x, y zurückschreiben *)
- Move(buffer[y,x], screen^[y,x], 2);
- inverted := FALSE;
- END;
-
- PROCEDURE InvertBlock(xa, ya, xe, ye : BYTE;
- invers : BOOLEAN);
- VAR
- xt, a, b, y, x : BYTE;
- BEGIN (* Invertiert einen Textblock bis zum Zeilenende *)
- IF (NOT inverted) = invers THEN BEGIN
- FOR y := ya TO ye DO BEGIN
- a := 1; b := 1;
- IF y <> ye THEN
- WHILE (b < 80) DO BEGIN
- a := b;
- WHILE (Lo(buffer[y,a]) <> Ord(' ')) AND
- (a < 80) DO Inc(a);
- b := a; xt := a;
- WHILE (Lo(buffer[y,b]) = Ord(' ')) AND
- (b < 80) DO Inc(b);
- END
- ELSE xt := xe;
- IF y <> ya THEN xa := 1;
- FOR x := xa TO xt DO
- IF invers THEN ReverseAttribut(x, y)
- ELSE Restore(x, y);
- END;
- END;
- END;
-
- PROCEDURE Store(c : WORD); (* Zeichen speichern *)
- BEGIN
- IF num <= maxnum THEN BEGIN
- Inc(num); charbuffer[num] := c;
- END;
- END;
-
- PROCEDURE MoveCopyMaus;
- BEGIN
- InitCopyMaus;
- FOR n := 1 TO 25 DO (* Bildschirm in den Puffer ...*)
- Move(screen^[n,1], buffer[n,1], 160);
- { Die folgenden Zeilen testen, ob in TP 3.0 oder 4.0 die }
- { automatische Tabulierung (Indent) eingeschaltet ist }
- n := 35;
- WHILE Chr(Lo(screen^[1,n])) IN indentstr DO Inc(n);
- m := 33;
- WHILE Chr(Lo(screen^[2,m])) IN indentstr DO Inc(m);
- x := 34;
- WHILE Chr(Lo(screen^[3,x])) IN indentstr DO Inc(x);
- IF (n > 38) OR (m > 35) OR (x > 36) THEN
- indent := TRUE
- ELSE indent := FALSE;
- FOR n := 1 TO 80 DO BEGIN (* Titelzeile schreiben *)
- IF n <= 41 THEN
- screen^[1,n] := 112 SHL 8 + Ord(titel1[n])
- ELSE
- screen^[1,n] := 112 SHL 8 + Ord(titel2[n - 41])
- END;
- ShowMouse;
- xa := 0; ya := 0; xe := 0; ye := 0;
- { Die Hauptschleife des Programms: Setzen von Anfangs- }
- { und Endkoordinate und markieren }
- REPEAT
- GetMouse(xm, ym);
- Move(buffer[ym, xm], screen^[ym, xm], 1);
- IF WhichButton = 2 THEN BEGIN (* Ende *)
- InvertBlock(xa, ya, xe, ye, FALSE);
- xe := xm; ye := ym;
- END;
- IF WhichButton = 1 THEN BEGIN (* Anfang *)
- InvertBlock(xa, ya, xe, ye, FALSE);
- xa := xm; ya := ym;
- END;
- IF (ye < ya) OR ((xe < xa) AND (ye = ya)) THEN BEGIN
- xe := xa; ye := ya;
- END;
- InvertBlock(xa, ya, xe, ye, TRUE);
- Hi(screen^[ya,xa]) := 112; (* Anfang und Ende *)
- Hi(screen^[ye,xe]) := 112; (* markieren *)
- UNTIL MouseInXY(75, 80, 1, 1);
- InvertBlock(xa, ya, xe, ye, FALSE); (* Markierung weg *)
- HideMouse; (* Maus weg *)
- Move(buffer[1,1], screen^[1,1], 160); (* Titel weg *)
- IF NOT ((xa = 0) (* Überhaupt etwas markiert ? *)
- AND (ya = 0) AND (xe = 0) AND (ye = 0)) THEN BEGIN
- IF indent THEN BEGIN (* Indent ausschalten *)
- Store(crtl_q);
- Store(crtl_i);
- END;
- { Markierten Block in den "Charbuffer" schreiben }
- FOR y := ya TO ye DO BEGIN
- a := 1; b := 1;
- IF y <> ye THEN
- WHILE (b < 80) DO BEGIN
- a := b;
- WHILE (Lo(buffer[y,a]) <> Ord(' ')) and
- (a < 80) DO Inc(a);
- b := a; xt := a;
- WHILE (Lo(buffer[y,b]) = Ord(' ')) and
- (b < 80) DO Inc(b);
- END
- ELSE xt := xe;
- IF y <> ya THEN xa := 1;
- FOR x := xa TO xt DO BEGIN
- Store(Lo(buffer[y,x]));
- IF (x = xt) AND (y <> ye) THEN Store(cr);
- END;
- END;
- if indent then begin (* Indent einschalten *)
- Store(crtl_q);
- Store(crtl_i);
- END;
- again := TRUE;
- END ELSE InitMouse;
- END;
-
- PROCEDURE PutChar(scancode : WORD);
- VAR
- KBDhead : WORD ABSOLUTE $0040:$001A;
- KBDtail : WORD ABSOLUTE $0040:$001C;
- KBDbuffer : ARRAY [$1E..$3C] OF BYTE
- ABSOLUTE $0040:$001E;
- BEGIN
- Move(scancode, KBDbuffer[KBDtail], 2);
- KBDtail := KBDtail + 2;
- IF KBDtail > $003C THEN KBDtail := $001E;
- END;
-
- PROCEDURE GetCopyMausChar(VAR key : WORD);
- BEGIN
- IF num > 0 THEN BEGIN
- Inc(written);
- key := (CharBuffer[written]);
- IF written = num THEN BEGIN
- written := 0;
- num := 0;
- InitMouse;
- again := FALSE;
- END ELSE PutChar(hotkey);
- END ELSE again := FALSE;
- END;
-
- {$F+}
- PROCEDURE Int16(flags, cs, ip, ax, bx, cx, dx, si, di,
- ds, es, bp : WORD); INTERRUPT;
- PROCEDURE SwitchStack;
- INLINE ($8C/$16/saveSS/$89/$26/saveSP/$FA/
- $8E/$16/progSS/$8B/$26/progSP/$FB);
-
- PROCEDURE SwitchBack;
- INLINE ($FA/$8E/$16/saveSS/$8B/$26/saveSP/$FB);
-
- PROCEDURE ChainInt(address : POINTER);
- INLINE ($5B/$58/$87/$5E/$0E/$87/$46/$10/$89/
- $EC/$5D/$07/$1F/$5F/$5E/$5A/$59/$CB);
- BEGIN
- IF (Hi(ax) = 0) THEN BEGIN
- ax := GetKey;
- IF ax = hotkey THEN BEGIN
- SwitchStack;
- IF again THEN BEGIN
- GetCopyMausChar(ch);
- SwitchBack;
- ax := ch;
- END ELSE BEGIN
- MoveCopyMaus;
- SwitchBack;
- IF again THEN PutChar(hotkey);
- END;
- END;
- END ELSE ChainInt(saveint16);
- END;
-
- BEGIN
- progSS := SSeg;
- progsp := SPtr;
- IF testmouse <> 0 THEN BEGIN
- WriteLn(^M^J,version,' ist installiert, ',
- ^M^J'aktivieren mit ',hotkeyname);
- GetIntVec($16, saveint16);
- SetIntVec($16, @int16);
- SetIntVec($1B, saveint1b);
- again := FALSE;
- Keep(0);
- END ELSE
- WriteLn('Keine Maus initialisiert ! ');
- END.
- (* ------------------------------------------------------ *)
- (* Ende von COPYMAUS.PAS *)