home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / progm / tptools.zip / FIRSTED.ZIP / EDSCRN2.PAS < prev    next >
Pascal/Delphi Source File  |  1987-12-21  |  14KB  |  456 lines

  1. {                          EDSCRN2.PAS
  2.                              ED 4.0
  3.              Copyright (c) 1985, 87 by Borland International, Inc.            }
  4.  
  5. {$I eddirect.inc}
  6.  
  7. unit EdScrn2;
  8.   {-Screen updating routines specific to FirstEd}
  9.  
  10. interface
  11.  
  12. uses
  13.   crt,                       {Basic video operations - standard unit}
  14.   Dos,                       {DOS calls - standard unit}
  15.   Errors,                    {Runtime error handler}
  16.   EdVars,                    {Global types and declarations}
  17.   EdScrn1,                   {Fast screen writing routines}
  18.   EdString,                  {String primitives}
  19.   EdPtrOp,                   {Primitive pointer operations}
  20.   EdCmds,                    {Maps keystrokes to commands}
  21.   int24,                     {DOS critical error handler}
  22.   Message,                   {Message system}
  23.   EdUser;                    {User keyboard input, line editing and error reporting}
  24.  
  25. procedure EdUpdateStatusLine(W : PwinDesc);
  26.   {-Update window status line for specified window}
  27.  
  28. procedure EdUpdateLine(P : PlineDesc; Row, LeftEdge, LeftCol : Integer; Attribs : Boolean);
  29.   {-Update one row of the screen}
  30.  
  31. procedure EdBiosScroll;
  32.   {-Use the IBM BIOS to scroll up or down one line rapidly}
  33.  
  34. procedure EdUpdateScreen;
  35.   {-Update physical screen}
  36.  
  37. procedure EdHighlightScreen(Col1, Col2 : Integer; Attr : Byte; WaitForKey : Boolean);
  38.   {-Change attribute of a screen string and wait for keystroke}
  39.  
  40. procedure EdInterruptibleDelay(Time : Integer);
  41.   {-Generate a delay which can be interrupted by a keystroke}
  42.  
  43.   {==========================================================================}
  44.  
  45. implementation
  46.  
  47. const
  48.   {Positions on Window status line}
  49.   NameCol = 4;               {Uses columns 04-16}
  50.   LineTitleCol = 22;         {22-26}
  51.   LineNumCol = 27;           {27-32}
  52.   ColTitleCol = 33;          {33-36}
  53.   ColNumCol = 37;            {37-40}
  54.   ByteTitleCol = 41;         {41-45}
  55.   ByteNumCol = 46;           {46-49}
  56.   InsertFlagCol = 55;        {55-60, or Overwrite}
  57.   IndentFlagCol = 64;        {64-69}
  58.   ModifiedFlagCol = 75;      {75-78}
  59.  
  60.   {Strings for Window status line}
  61.   StLine : string[4] = 'Line';
  62.   StCol : string[3] = 'Col';
  63.   StByte : string[4] = 'Byte';
  64.   StAi : string[6] = 'Indent';
  65.   StIns : string[6] = 'Insert';
  66.   StOvr : string[6] = 'Over';
  67.   StSave : string[4] = 'Save';
  68.  
  69.   {***}
  70.   procedure EdUpdateStatusLine(W : PwinDesc);
  71.     {-Update window status line for specified window}
  72.   var
  73.     St : VarString;
  74.  
  75.   begin                      {EdUpdateStatusLine}
  76.  
  77.     if EdKeyInterrupt then
  78.       Exit;
  79.  
  80.     with W^ do begin
  81.  
  82.       {Initialize the screen attribute of the status line}
  83.       FillChar(Aline, PhyScrCols, ScreenAttr[BordColor]);
  84.       {Fill status line with blanks}
  85.       FillChar(Tline[0], PhyScrCols, Blank);
  86.  
  87.       {Print the file name}
  88.       St := EdEndOfPath(Filename);
  89.       Move(St[1], Tline[NameCol], Length(St));
  90.  
  91.       {Line number}
  92.       Move(StLine[1], Tline[LineTitleCol], Ord(StLine[0]));
  93.       Str(Clineno:1, St);
  94.       Move(St[1], Tline[LineNumCol], Length(St));
  95.  
  96.       {Column number}
  97.       Move(StCol[1], Tline[ColTitleCol], Ord(StCol[0]));
  98.       Str(ColNo:1, St);
  99.       Move(St[1], Tline[ColNumCol], Length(St));
  100.  
  101.       {Byte number}
  102.       Move(StByte[1], Tline[ByteTitleCol], Ord(StByte[0]));
  103.       Str(TcharNo, St);
  104.       Move(St[1], Tline[ByteNumCol], Length(St));
  105.  
  106.       {Insert/overtype symbol}
  107.       if InsertFlag then
  108.         Move(StIns[1], Tline[InsertFlagCol], Ord(StIns[0]))
  109.       else
  110.         Move(StOvr[1], Tline[InsertFlagCol], Ord(StOvr[0]));
  111.  
  112.       {Autoindent mode symbol}
  113.       if AI then
  114.         Move(StAi[1], Tline[IndentFlagCol], Ord(StAi[0]));
  115.  
  116.       {File modified symbol}
  117.       if Modified then
  118.         Move(StSave[1], Tline[ModifiedFlagCol], Ord(StSave[0]));
  119.  
  120.       {Write it to the screen}
  121.       EdWrline(FirstLineNo);
  122.  
  123.     end;
  124.   end;                       {EdUpdateStatusLine}
  125.  
  126.   {***}
  127.   procedure EdUpdateLine(P : PlineDesc; Row, LeftEdge, LeftCol : Integer; Attribs : Boolean);
  128.     {-Update one row of the screen}
  129.   var
  130.     Fl, ScrCols : Integer;
  131.  
  132.     procedure EdBuildLineNoAttribs(P : PlineDesc; LeftEdge, LeftCol, ScrCols : Integer; Attr : Byte);
  133.       {-Build TLINE and ALINE without text attribute display}
  134.     var
  135.       Len : Integer;
  136.  
  137.     begin                    {EdBuildLineNoAttribs}
  138.  
  139.       {Get the displayed part of the text}
  140.       Len := Succ(EdTextLength(P)-LeftEdge);
  141.       if Len > 0 then begin
  142.         if Len >= ScrCols then begin
  143.           {Line covers full width of screen}
  144.           Move(P^.Txt^[LeftEdge], Tline[LeftCol], ScrCols);
  145.           FillChar(Aline[LeftCol], ScrCols, Attr);
  146.         end else begin
  147.           {Line covers part of screen, right fill with blanks}
  148.           Move(P^.Txt^[LeftEdge], Tline[LeftCol], Len);
  149.           FillChar(Tline[LeftCol+Len], ScrCols-Len, Blank);
  150.           FillChar(Aline[LeftCol], Len, Attr);
  151.           FillChar(Aline[LeftCol+Len], ScrCols-Len, ScreenAttr[TxtColor]);
  152.         end;
  153.       end else begin
  154.         {Text scrolled off left edge of screen}
  155.         FillChar(Tline[LeftCol], ScrCols, Blank);
  156.         FillChar(Aline[LeftCol], ScrCols, ScreenAttr[TxtColor]);
  157.       end;
  158.     end;                     {EdBuildLineNoAttribs}
  159.  
  160.     procedure EdShowBlockMarkers(P : PlineDesc; LeftEdge, LeftCol, ScrCols : Integer);
  161.       {-Set up attributes for block marked lines}
  162.     var
  163.       M, N : Integer;
  164.       Attr : Byte;
  165.  
  166.     begin                    {EdShowBlockMarkers}
  167.  
  168.       Attr := ScreenAttr[BlockColor];
  169.  
  170.       {Special cases for partially marked lines}
  171.       if P = Blockfrom.Line then begin
  172.  
  173.         M := Blockfrom.Col-LeftEdge;
  174.  
  175.         if (P = Blockto.Line) then begin
  176.  
  177.           {Block is totally within one line}
  178.           if M <= ScrCols then begin
  179.             {Block shows on screen}
  180.             if M <= 0 then
  181.               M := 0;
  182.             N := Blockto.Col-LeftEdge;
  183.             if N > ScrCols then
  184.               {Right edge of block off of screen}
  185.               FillChar(Aline[M+LeftCol], ScrCols-M, Attr)
  186.             else begin
  187.               if N < 0 then
  188.                 N := 0;
  189.               FillChar(Aline[M+LeftCol], N-M, Attr);
  190.             end;
  191.           end;
  192.  
  193.         end else begin
  194.  
  195.           {First line of block}
  196.           if M <= ScrCols then begin
  197.             {Block shows on screen}
  198.             if M <= 0 then
  199.               M := 0;
  200.             FillChar(Aline[M+LeftCol], ScrCols-M, Attr);
  201.           end;
  202.  
  203.         end;
  204.  
  205.       end else if P = Blockto.Line then begin
  206.  
  207.         {Last line of block}
  208.         N := Blockto.Col-LeftEdge;
  209.         if N > ScrCols then
  210.           {Whole visible line in block}
  211.           FillChar(Aline[LeftCol], ScrCols, Attr)
  212.         else if N > 0 then
  213.           FillChar(Aline[LeftCol], N, Attr);
  214.  
  215.       end else
  216.  
  217.         {Line fully in block}
  218.         FillChar(Aline[LeftCol], ScrCols, Attr);
  219.  
  220.     end;                     {EdShowBlockMarkers}
  221.  
  222.     procedure EdShowTextMarkers(P : PlineDesc; LeftEdge, LeftCol, ScrCols : Integer);
  223.       {-Display the text markers}
  224.     var
  225.       M, N : Integer;
  226.  
  227.     begin                    {EdShowTextMarkers}
  228.       for M := 0 to MaxMarker do
  229.         with Marker[M] do
  230.           if P = Line then begin
  231.             {Change the marked position to the mark number in border color}
  232.             N := Col-LeftEdge;
  233.             if (N >= 0) and (N < ScrCols) then begin
  234.               {Change the displayed character}
  235.               Tline[N+LeftCol] := Chr(M+Ord('0'));
  236.               {Change the attribute}
  237.               Aline[N+LeftCol] := Chr(ScreenAttr[BordColor]);
  238.             end;
  239.           end;
  240.     end;                     {EdShowTextMarkers}
  241.  
  242.   begin                      {EdUpdateLine}
  243.  
  244.     {Screen columns available for text display}
  245.     ScrCols := PhyScrCols-LeftCol;
  246.  
  247.     if EdPtrIsNil(P) then begin
  248.  
  249.       {Blank line at end of file}
  250.       FillChar(Tline[LeftCol], ScrCols, Blank);
  251.       FillChar(Aline[LeftCol], ScrCols, ScreenAttr[TxtColor]);
  252.       Fl := 0;
  253.  
  254.     end else begin
  255.  
  256.       Fl := P^.Flags;
  257.  
  258.       EdBuildLineNoAttribs(P, LeftEdge, LeftCol, ScrCols, ScreenAttr[TxtColor]);
  259.  
  260.       {Show block markers}
  261.       if (Fl and InBlock) <> 0 then
  262.         EdShowBlockMarkers(P, LeftEdge, LeftCol, ScrCols);
  263.  
  264.       {Display text markers}
  265.       if (Fl and InMark) <> 0 then
  266.         EdShowTextMarkers(P, LeftEdge, LeftCol, ScrCols);
  267.  
  268.     end;
  269.  
  270.     {Write the line to screen after translating control characters}
  271.     EdWrlineCtrl(Row);
  272.  
  273.   end;                       {EdUpdateLine}
  274.  
  275.   procedure EdUpdatewindow(W : PwinDesc);
  276.     {-Update a single window on the screen}
  277.   var
  278.     P : PlineDesc;
  279.     I, R, Le, Lc : Integer;
  280.     Attribs : Boolean;
  281.  
  282.   begin                      {EdUpdateWindow}
  283.     with W^ do begin
  284.       Le := LeftEdge;
  285.       Lc := LeftCol;
  286.       Attribs := AT;
  287.       I := 0;
  288.  
  289.       {Update from one past the current line to bottom of window}
  290.       P := CurLine^.FwdLink;
  291.       for R := (FirstTextNo+LineNo) to LastLineNo do begin
  292.         EdUpdateLine(P, R, Le, Lc, Attribs);
  293.         Inc(I);
  294.         {Check every 4th line for a keyboard interrupt}
  295.         if I and 3 = 0 then
  296.           if EdKeyInterrupt then
  297.             Exit;
  298.         if EdPtrNotNil(P) then
  299.           EdFwdPtr(P);
  300.       end;
  301.  
  302.       {Now update from top of window to current line}
  303.       P := TopLine;
  304.       for R := FirstTextNo to Pred(FirstTextNo+LineNo) do begin
  305.         EdUpdateLine(P, R, Le, Lc, Attribs);
  306.         Inc(I);
  307.         if I and 3 = 0 then
  308.           if EdKeyInterrupt then
  309.             Exit;
  310.         if EdPtrNotNil(P) then
  311.           EdFwdPtr(P);
  312.       end;
  313.  
  314.     end;
  315.   end;                       {EdUpdateWindow}
  316.  
  317.   procedure EdBiosScroll;
  318.     {-use the IBM BIOS to scroll up or down one line rapidly}
  319.   var
  320.     P : PlineDesc;
  321.     R : Integer;
  322.     Delta : Integer;
  323.     regs : registers;
  324.  
  325.   begin                      {EdBiosScroll}
  326.     with CurWin^ do begin
  327.  
  328.       {Scroll the current window up or down via BIOS call}
  329.       with regs do begin
  330.         Al := 1;
  331.         if FullScroll < 0 then begin
  332.           Ah := 6;
  333.           Delta := 1;
  334.         end else begin
  335.           Ah := 7;
  336.           Delta := -1;
  337.         end;
  338.         Ch := Pred(FirstTextNo);
  339.         Cl := 0;
  340.         Dh := Pred(LastLineNo);
  341.         dl := 79;
  342.         Bh := lo(ScreenAttr[TxtColor]);
  343.       end;
  344.       intr($10, regs);
  345.  
  346.       {Write the newly scrolled line}
  347.       if FullScroll > 0 then
  348.         EdUpdateLine(TopLine, FirstTextNo, LeftEdge, LeftCol, AT)
  349.       else begin
  350.         {Get pointer to last line on screen}
  351.         P := TopLine;
  352.         for R := FirstTextNo to Pred(LastLineNo) do
  353.           if EdPtrNotNil(P) then
  354.             EdFwdPtr(P);
  355.         EdUpdateLine(P, LastLineNo, LeftEdge, LeftCol, AT);
  356.       end;
  357.  
  358.     end;
  359.     if UpdateCursor then
  360.       EdUpdateCursor;
  361.     FullScroll := FullScroll+Delta;
  362.   end;                       {EdBiosScroll}
  363.  
  364.   procedure EdUpdateScreen;
  365.     {-Update physical screen}
  366.   var
  367.     W : PwinDesc;
  368.  
  369.   begin                      {EdUpdateScreen}
  370.  
  371.     {Update the current line}
  372.     with CurWin^ do
  373.       EdUpdateLine(CurLine, Pred(FirstTextNo+LineNo), LeftEdge, LeftCol, AT);
  374.  
  375.     {Get out if keys are waiting}
  376.     if EdKeyInterrupt then
  377.       Exit;
  378.  
  379.     {Update the rest of the screen window by window, starting with current}
  380.     W := CurWin;
  381.     repeat
  382.       EdUpdatewindow(W);
  383.       if EdKeyInterrupt then
  384.         Exit;
  385.       EdUpdateStatusLine(W);
  386.       EdFwdPtr(W);
  387.     until W = CurWin;
  388.  
  389.     {Update the command line}
  390.     EdUpdateCmdLine;
  391.  
  392.     {Indicate that the screen has been fully updated}
  393.     UpdateScreen := False;
  394.     FullScroll := 0;
  395.     IntrFlag := Interr;
  396.  
  397.   end;                       {EdUpdateScreen}
  398.  
  399.   {***}
  400.   procedure EdHighlightScreen(Col1, Col2 : Integer; Attr : Byte; WaitForKey : Boolean);
  401.     {-Change attribute of a screen string and wait for keystroke}
  402.   var
  403.     Dis, Len : Integer;
  404.  
  405.   begin                      {EdHighLightScreen}
  406.  
  407.     with CurWin^ do begin
  408.  
  409.       {Horizontal scroll to display both ends of highlighted range}
  410.       if Col1 <= LeftEdge then begin
  411.         if Col1 > 1 then
  412.           LeftEdge := Pred(Col1)
  413.         else
  414.           LeftEdge := Col1;
  415.       end else if Col2 >= (LeftEdge+PhyScrCols-2-LeftCol) then
  416.         LeftEdge := Col2-PhyScrCols+LeftCol+2;
  417.  
  418.       {Update the screen}
  419.       EdUpdateCursor;
  420.       EdZapPromptLine;
  421.       EdUpdateScreen;
  422.  
  423.       {Change attribute of selected string}
  424.       Dis := Succ(Col1-LeftEdge+LeftCol);
  425.       Len := Succ(Col2-Col1);
  426.       if Pred(Dis+Len) > DefNoCols then
  427.         {Avoid overwriting edge of screen}
  428.         Len := Succ(DefNoCols-Dis);
  429.       EdChangeAttribute(Len, Pred(FirstTextNo+LineNo), Dis, Attr);
  430.  
  431.     end;
  432.  
  433.     if WaitForKey then
  434.       {Wait for a keystroke}
  435.       repeat
  436.       until Abortcmd or EdKeyPressed;
  437.   end;                       {EdHighLightScreen}
  438.  
  439.   procedure EdInterruptibleDelay(Time : Integer);
  440.     {-Generate a delay which can be interrupted by a keystroke}
  441.   var
  442.     Total : Integer;
  443.  
  444.   begin                      {EdInterruptibleDelay}
  445.     EdUpdateScreen;
  446.     Total := 0;
  447.     while (Total < Time) do begin
  448.       if EdKeyPressed or Abortcmd then
  449.         Exit;
  450.       Delay(5);
  451.       Total := Total+5;
  452.     end;
  453.   end;                       {EdInterruptibleDelay}
  454.  
  455. end.
  456.