home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / telecomm / terms / term-4.1-source.lha / Extras / Source / term-Source.lha / termReviewBuffer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-04  |  33.7 KB  |  1,760 lines

  1. /*
  2. **    termReviewBuffer.c
  3. **
  4. **    Support routines for the review buffer
  5. **
  6. **    Copyright © 1990-1994 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* Handy signal masks. */
  13.  
  14. #define SIG_REVIEWPORT        (1L << ReviewPort -> mp_SigBit)
  15. #define SIG_REVIEWWINDOW    (1L << ReviewWindow -> UserPort -> mp_SigBit)
  16.  
  17.     /* Menu item codes. */
  18.  
  19. enum    {    MEN_SEARCH,MEN_REPEAT,MEN_CLEARBUF,MEN_QUITBUF };
  20.  
  21.     /* Gadget ID codes. */
  22.  
  23. enum    {    GAD_SCROLLER, GAD_UP, GAD_DOWN };
  24.  
  25.     /* The arrow image height. */
  26.  
  27. #define ARROW_HEIGHT    11
  28.  
  29. STATIC struct NewMenu ReviewMenu[] =
  30. {
  31.     { NM_TITLE, NULL,         0 , 0, 0, (APTR)0},
  32.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_SEARCH},
  33.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_REPEAT},
  34.     {  NM_ITEM, NM_BARLABEL,     0 , 0, 0, (APTR)0},
  35.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_CLEARBUF},
  36.     {  NM_ITEM, NM_BARLABEL,     0 , 0, 0, (APTR)0},
  37.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_QUITBUF},
  38.  
  39.     { NM_END, 0,             0 , 0, 0, (APTR)0}
  40. };
  41.  
  42.     /* Local routines. */
  43.  
  44. STATIC VOID        ReviewUpdatePot(VOID);
  45. STATIC VOID __stdargs    ReviewWrites(STRPTR String,...);
  46. STATIC VOID __regargs     PrintReviewLine(STRPTR Buffer,LONG Line);
  47. STATIC VOID __regargs     RefreshReview(LONG Top);
  48. STATIC VOID __regargs    ScrollReview(LONG Top);
  49. STATIC BYTE        ReviewQuery(VOID);
  50. STATIC UBYTE __regargs    GetReviewChar(BYTE WaitForIt);
  51.  
  52.     /* Local variables. */
  53.  
  54. STATIC struct Menu        *ReviewMenuStrip;
  55.  
  56. STATIC struct IBox         ReviewBox = { -1 };
  57. STATIC struct IOStdReq        *ReviewWriteRequest,
  58.                 *ReviewReadRequest;
  59.  
  60. STATIC struct MsgPort        *ReviewPort,
  61.                 *ReviewWritePort;
  62.  
  63. STATIC struct Gadget        *Scroller,
  64.                 *UpArrow,
  65.                 *DownArrow;
  66.  
  67. STATIC UWORD             RightBorderWidth;
  68.  
  69. STATIC struct Image        *UpImage,
  70.                 *DownImage;
  71.  
  72. STATIC UBYTE             ReviewChar;
  73. STATIC LONG             ReviewColumns,ReviewLines,
  74.                  ReviewTop = -1,ReviewGlobalLines;
  75.  
  76. STATIC BYTE             SearchForward    = TRUE,
  77.                  IgnoreCase    = TRUE,
  78.                  WholeWords    = FALSE;
  79.  
  80. STATIC UBYTE            *ReviewLineWidths;
  81. STATIC LONG             ReviewMaxLines;
  82.  
  83. STATIC struct MsgQueue        *ReviewQueue;
  84. STATIC struct Task        *ReviewTask;
  85.  
  86. STATIC WORD             ReviewPen;
  87. STATIC BYTE             ReviewSignal;
  88.  
  89.     /* ReviewDeleteScroller(VOID):
  90.      *
  91.      *    Delete scroller and arrow buttons.
  92.      */
  93.  
  94. STATIC VOID
  95. ReviewDeleteScroller(VOID)
  96. {
  97.     if(Scroller)
  98.     {
  99.         DisposeObject(Scroller);
  100.  
  101.         Scroller = NULL;
  102.     }
  103.  
  104.     if(UpArrow)
  105.     {
  106.         DisposeObject(UpArrow);
  107.  
  108.         UpArrow = NULL;
  109.     }
  110.  
  111.     if(DownArrow)
  112.     {
  113.         DisposeObject(DownArrow);
  114.  
  115.         DownArrow = NULL;
  116.     }
  117.  
  118.     if(UpImage)
  119.     {
  120.         DisposeObject(UpImage);
  121.  
  122.         UpImage = NULL;
  123.     }
  124.  
  125.     if(DownImage)
  126.     {
  127.         DisposeObject(DownImage);
  128.  
  129.         DownImage = NULL;
  130.     }
  131. }
  132.  
  133.     /* ReviewCreateScroller(struct Screen *Screen):
  134.      *
  135.      *    Create scroller and arrow buttons.
  136.      */
  137.  
  138. STATIC BYTE __regargs
  139. ReviewCreateScroller(struct Screen *Screen)
  140. {
  141.     struct DrawInfo    *DrawInfo;
  142.     BYTE         Result = FALSE;
  143.  
  144.     if(DrawInfo = GetScreenDrawInfo(Screen))
  145.     {
  146.         struct Image    *SizeImage;
  147.         ULONG         SizeWidth,
  148.                  SizeHeight,
  149.                  ArrowHeight;
  150.         UWORD         SizeType;
  151.  
  152.         if(Screen -> Flags & SCREENHIRES)
  153.         {
  154.             SizeWidth    = 18;
  155.             SizeHeight    = 10;
  156.  
  157.             SizeType    = SYSISIZE_MEDRES;
  158.         }
  159.         else
  160.         {
  161.             SizeWidth    = 13;
  162.             SizeHeight    = 11;
  163.  
  164.             SizeType    = SYSISIZE_LOWRES;
  165.         }
  166.  
  167.         if(SizeImage = (struct Image *)NewObject(NULL,"sysiclass",
  168.             SYSIA_Size,    SizeType,
  169.             SYSIA_Which,    SIZEIMAGE,
  170.             SYSIA_DrawInfo,    DrawInfo,
  171.         TAG_DONE))
  172.         {
  173.             GetAttr(IA_Width,    SizeImage,&SizeWidth);
  174.             GetAttr(IA_Height,    SizeImage,&SizeHeight);
  175.  
  176.             DisposeObject(SizeImage);
  177.  
  178.             RightBorderWidth = SizeWidth;
  179.  
  180.             if(UpImage = (struct Image *)NewObject(NULL,"sysiclass",
  181.                 SYSIA_Size,    SizeType,
  182.                 SYSIA_Which,    UPIMAGE,
  183.                 SYSIA_DrawInfo,    DrawInfo,
  184.             TAG_DONE))
  185.             {
  186.                 GetAttr(IA_Height,UpImage,&ArrowHeight);
  187.  
  188.                 if(DownImage = (struct Image *)NewObject(NULL,"sysiclass",
  189.                     SYSIA_Size,    SizeType,
  190.                     SYSIA_Which,    DOWNIMAGE,
  191.                     SYSIA_DrawInfo,    DrawInfo,
  192.                 TAG_DONE))
  193.                 {
  194.                     if(Scroller = NewObject(NULL,"propgclass",
  195.                         GA_ID,        GAD_SCROLLER,
  196.  
  197.                         GA_Top,        Screen -> WBorTop + Screen -> Font -> ta_YSize + 2,
  198.                         GA_RelHeight,    -(Screen -> WBorTop + Screen -> Font -> ta_YSize + 2 + SizeHeight + 1 + 2 * ArrowHeight),
  199.                         GA_Width,    SizeWidth - 8,
  200.                         GA_RelRight,    -(SizeWidth - 5),
  201.  
  202.                         GA_Immediate,    TRUE,
  203.                         GA_FollowMouse,    TRUE,
  204.                         GA_RelVerify,    TRUE,
  205.                         GA_RightBorder,    TRUE,
  206.  
  207.                         PGA_Freedom,    FREEVERT,
  208.                         PGA_NewLook,    TRUE,
  209.                         PGA_Borderless,    TRUE,
  210.  
  211.                         PGA_Visible,    1,
  212.                         PGA_Total,    1,
  213.                     TAG_DONE))
  214.                     {
  215.                         STATIC struct TagItem ArrowMappings[] = { GA_ID,GA_ID,TAG_END };
  216.  
  217.                         if(UpArrow = NewObject(NULL,"buttongclass",
  218.                             GA_ID,        GAD_UP,
  219.  
  220.                             GA_Image,    UpImage,
  221.                             GA_RelRight,    -(SizeWidth - 1),
  222.                             GA_RelBottom,    -(SizeHeight - 1 + 2 * ArrowHeight),
  223.                             GA_Height,    ArrowHeight,
  224.                             GA_Width,    SizeWidth,
  225.                             GA_Immediate,    TRUE,
  226.                             GA_RelVerify,    TRUE,
  227.                             GA_Previous,    Scroller,
  228.                             GA_RightBorder,    TRUE,
  229.  
  230.                             ICA_TARGET,    ICTARGET_IDCMP,
  231.                             ICA_MAP,    ArrowMappings,
  232.                         TAG_DONE))
  233.                         {
  234.                             if(DownArrow = NewObject(NULL,"buttongclass",
  235.                                 GA_ID,        GAD_DOWN,
  236.  
  237.                                 GA_Image,    DownImage,
  238.                                 GA_RelRight,    -(SizeWidth - 1),
  239.                                 GA_RelBottom,    -(SizeHeight - 1 + ArrowHeight),
  240.                                 GA_Height,    ArrowHeight,
  241.                                 GA_Width,    SizeWidth,
  242.                                 GA_Immediate,    TRUE,
  243.                                 GA_RelVerify,    TRUE,
  244.                                 GA_Previous,    UpArrow,
  245.                                 GA_RightBorder,    TRUE,
  246.  
  247.                                 ICA_TARGET,    ICTARGET_IDCMP,
  248.                                 ICA_MAP,    ArrowMappings,
  249.                             TAG_DONE))
  250.                                 Result = TRUE;
  251.                         }
  252.                     }
  253.                 }
  254.             }
  255.         }
  256.  
  257.         FreeScreenDrawInfo(Screen,DrawInfo);
  258.     }
  259.  
  260.     return(Result);
  261. }
  262.  
  263.     /* ReviewUpdatePot():
  264.      *
  265.      *    Update size and position of the scroller gadget.
  266.      */
  267.  
  268. STATIC VOID
  269. ReviewUpdatePot()
  270. {
  271.     if(ReviewGlobalLines)
  272.     {
  273.         SetGadgetAttrs(Scroller,ReviewWindow,NULL,
  274.             PGA_Top,    ReviewTop,
  275.             PGA_Visible,    ReviewLines,
  276.             PGA_Total,    ReviewGlobalLines,
  277.         TAG_DONE);
  278.     }
  279. }
  280.  
  281.     /* ReviewUp(LONG Count):
  282.      *
  283.      *    Move the contents of the review buffer up.
  284.      */
  285.  
  286. STATIC VOID __regargs
  287. ReviewUp(LONG Count)
  288. {
  289.     if(BufferLines)
  290.     {
  291.         if(Count == 1)
  292.         {
  293.             if(ReviewTop)
  294.             {
  295.                 WORD i;
  296.  
  297.                 for(i = ReviewMaxLines - 2 ; i >= 0 ; i--)
  298.                     ReviewLineWidths[i + 1] = ReviewLineWidths[i];
  299.  
  300.                 ReviewTop--;
  301.  
  302.                 ReviewWrites("\33[T");
  303.  
  304.                 ObtainSemaphore(BufferSemaphore);
  305.  
  306.                 PrintReviewLine(BufferLines[ReviewTop],1);
  307.  
  308.                 ReviewUpdatePot();
  309.  
  310.                 ReleaseSemaphore(BufferSemaphore);
  311.             }
  312.         }
  313.         else
  314.         {
  315.             LONG NewTop = ReviewTop;
  316.  
  317.             if(NewTop >= Count)
  318.                 NewTop -= Count;
  319.             else
  320.                 NewTop = 0;
  321.  
  322.             if(NewTop != ReviewTop)
  323.             {
  324.                 ScrollReview(NewTop);
  325.  
  326.                 ReviewUpdatePot();
  327.             }
  328.         }
  329.     }
  330. }
  331.  
  332.     /* ReviewDown(LONG Count):
  333.      *
  334.      *    Move the contents of the review buffer down.
  335.      */
  336.  
  337. STATIC VOID __regargs
  338. ReviewDown(LONG Count)
  339. {
  340.     if(BufferLines)
  341.     {
  342.         if(Count == 1)
  343.         {
  344.             if(ReviewTop + ReviewLines < Lines)
  345.             {
  346.                 LONG Last;
  347.                 WORD i;
  348.  
  349.                 for(i = 0 ; i < ReviewMaxLines - 1 ; i++)
  350.                     ReviewLineWidths[i] = ReviewLineWidths[i + 1];
  351.  
  352.                 ReviewTop++;
  353.  
  354.                 ReviewWrites("\33[S");
  355.  
  356.                 ObtainSemaphore(BufferSemaphore);
  357.  
  358.                 if((Last = ReviewTop + ReviewLines) < Lines)
  359.                     PrintReviewLine(BufferLines[Last],ReviewLines + 1);
  360.  
  361.                 ReviewUpdatePot();
  362.  
  363.                 ReleaseSemaphore(BufferSemaphore);
  364.             }
  365.         }
  366.         else
  367.         {
  368.             LONG NewTop = ReviewTop;
  369.  
  370.             if((NewTop + Count + ReviewLines) > Lines)
  371.             {
  372.                 if((NewTop = Lines - ReviewLines) < 0)
  373.                     NewTop = 0;
  374.             }
  375.             else
  376.                 NewTop += Count;
  377.  
  378.             if(NewTop != ReviewTop)
  379.             {
  380.                 ScrollReview(NewTop);
  381.  
  382.                 ReviewUpdatePot();
  383.             }
  384.         }
  385.     }
  386. }
  387.  
  388.     /* ReviewWrites(STRPTR String,...):
  389.      *
  390.      *    Write a string into the review buffer window.
  391.      */
  392.  
  393. STATIC VOID __stdargs
  394. ReviewWrites(STRPTR String,...)
  395. {
  396.     va_list    VarArgs;
  397.  
  398.     va_start(VarArgs,String);
  399.     VSPrintf(SharedBuffer,String,VarArgs);
  400.     va_end(VarArgs);
  401.  
  402.     ReviewWriteRequest -> io_Command    = CMD_WRITE;
  403.     ReviewWriteRequest -> io_Data        = SharedBuffer;
  404.     ReviewWriteRequest -> io_Length        = -1;
  405.  
  406.     DoIO(ReviewWriteRequest);
  407. }
  408.  
  409.     /* FilterReviewLine(register STRPTR Line,register LONG Length):
  410.      *
  411.      *    Replace non-printable characters in the text line
  412.      *    to be printed.
  413.      */
  414.      
  415.  
  416. STATIC STRPTR __regargs
  417. FilterReviewLine(register STRPTR Line,register LONG Length)
  418. {
  419.     STATIC UBYTE __far ISO[256] =
  420.     {
  421.          46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
  422.          46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
  423.          32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  424.          48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  425.          64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  426.          80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
  427.          96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
  428.         112,113,114,115,116,117,118,119,120,121,122,123,124,125,126, 46,
  429.          46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
  430.          46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
  431.         160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
  432.         176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
  433.         192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
  434.         208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
  435.         224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
  436.         240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
  437.     };
  438.  
  439.     STATIC UBYTE __far TempBuffer[256];
  440.  
  441.     register STRPTR Destination = TempBuffer;
  442.  
  443.     while(Length--)
  444.         *Destination++ = ISO[*Line++];
  445.  
  446.     return(TempBuffer);
  447. }
  448.  
  449.     /* PrintReviewLine(STRPTR Buffer,LONG Line):
  450.      *
  451.      *    Write the contents of a buffer line into the review buffer window.
  452.      */
  453.  
  454. STATIC VOID __regargs
  455. PrintReviewLine(STRPTR Buffer,LONG Line)
  456. {
  457.     WORD Length = Buffer[-1];
  458.  
  459.     if(Length > ReviewColumns)
  460.         Length = ReviewColumns;
  461.  
  462.     ReviewWrites("\33[%ldH",Line);
  463.  
  464.     ReviewWriteRequest -> io_Command    = CMD_WRITE;
  465.     ReviewWriteRequest -> io_Data        = FilterReviewLine(Buffer,Length);
  466.     ReviewWriteRequest -> io_Length        = Length;
  467.  
  468.     DoIO(ReviewWriteRequest);
  469.  
  470.     if(Length < ReviewLineWidths[Line - 1])
  471.         ReviewWrites("\33[0K");
  472.  
  473.     ReviewLineWidths[Line - 1] = Length;
  474. }
  475.  
  476.     /* RefreshReview(LONG Top):
  477.      *
  478.      *    Refresh the contents of the review buffer window.
  479.      */
  480.  
  481. STATIC VOID __regargs
  482. RefreshReview(LONG Top)
  483. {
  484.     LONG i,Last,Line = 0;
  485.  
  486.     ObtainSemaphore(BufferSemaphore);
  487.  
  488.     ReviewGlobalLines = Lines;
  489.  
  490.     if((Last = Top + ReviewLines + 1) >= Lines)
  491.     {
  492.         Last = Lines;
  493.  
  494.         if((Top = Last - ReviewLines) < 0)
  495.             Top = 0;
  496.  
  497.         ReviewTop = Top;
  498.     }
  499.  
  500.     if(BufferLines)
  501.     {
  502.         for(i = Top ; i < Last ; i++)
  503.             PrintReviewLine(BufferLines[i],++Line);
  504.     }
  505.  
  506.     if(Line <= ReviewLines)
  507.     {
  508.         if(Line)
  509.         {
  510.             for(i = Line - 1 ; i < ReviewLines ; i++)
  511.                 ReviewLineWidths[i] = 0;
  512.         }
  513.  
  514.         ReviewWrites("\33[0J\33[3%ldm",ReviewPen);
  515.     }
  516.  
  517.     ReleaseSemaphore(BufferSemaphore);
  518. }
  519.  
  520.     /* MoveUp(VOID):
  521.      *
  522.      *    Move the review buffer contents up a line.
  523.      */
  524.  
  525. STATIC VOID
  526. MoveUp(VOID)
  527. {
  528.     LONG i;
  529.  
  530.     for(i = 0 ; i < ReviewMaxLines - 1 ; i++)
  531.         ReviewLineWidths[i] = ReviewLineWidths[i + 1];
  532.  
  533.     ReviewWrites("\33[S");
  534.  
  535.     ObtainSemaphore(BufferSemaphore);
  536.     PrintReviewLine(BufferLines[ReviewTop + ReviewLines],ReviewLines + 1);
  537.     ReleaseSemaphore(BufferSemaphore);
  538. }
  539.  
  540.     /* ScrollReview(LONG Top):
  541.      *
  542.      *    Refresh the contents of the review buffer window, reprint
  543.      *    as few lines as possible.
  544.      */
  545.  
  546. STATIC VOID __regargs
  547. ScrollReview(LONG Top)
  548. {
  549.     LONG i,Last,Line = 0,Delta,Total;
  550.  
  551.     ObtainSemaphore(BufferSemaphore);
  552.  
  553.     ReviewGlobalLines = Lines;
  554.  
  555.     Delta = Top - ReviewTop;
  556.  
  557.     ReviewTop = Top;
  558.  
  559.     if((Last = Top + ReviewLines + 1) >= Lines)
  560.         Last = Lines;
  561.  
  562.     Total = Last - Top;
  563.  
  564.     if(ABS(Delta) < ReviewLines)
  565.     {
  566.         if(!Delta)
  567.         {
  568.             ReleaseSemaphore(BufferSemaphore);
  569.  
  570.             return;
  571.         }
  572.         else
  573.         {
  574.             if(Delta < 0)
  575.             {
  576.                 Last = Top - Delta;
  577.  
  578.                 for(i = ReviewMaxLines - 1 ; i > -Delta ; i--)
  579.                     ReviewLineWidths[i] = ReviewLineWidths[i + Delta];
  580.  
  581.                 ReviewWrites("\33[%ldT",-Delta);
  582.             }
  583.             else
  584.             {
  585.                 for(i = Delta ; i < ReviewMaxLines ; i++)
  586.                     ReviewLineWidths[i - Delta] = ReviewLineWidths[i];
  587.  
  588.                 Top += ReviewLines - Delta;
  589.                 Line = ReviewLines - Delta;
  590.  
  591.                 ReviewWrites("\33[%ldS",Delta);
  592.             }
  593.         }
  594.     }
  595.  
  596.     if(BufferLines)
  597.     {
  598.         for(i = Top ; i < Last ; i++)
  599.             PrintReviewLine(BufferLines[i],++Line);
  600.     }
  601.  
  602.     if(Total <= ReviewLines)
  603.         ReviewWrites("\33[0J");
  604.  
  605.     ReleaseSemaphore(BufferSemaphore);
  606. }
  607.  
  608.     /* ReviewQuery():
  609.      *
  610.      *    Update the current review buffer window dimensions.
  611.      */
  612.  
  613. STATIC BYTE
  614. ReviewQuery()
  615. {
  616.     struct ConUnit    *Unit = (struct ConUnit *)ReviewWriteRequest -> io_Unit;
  617.     BYTE         Refresh = FALSE;
  618.  
  619.     memset(ReviewLineWidths,0,ReviewMaxLines);
  620.  
  621.     if(ReviewColumns != Unit -> cu_XMax)
  622.     {
  623.         Refresh = TRUE;
  624.  
  625.         ReviewColumns = Unit -> cu_XMax;
  626.     }
  627.  
  628.     if(ReviewLines != Unit -> cu_YMax)
  629.     {
  630.         if(ReviewTop + ReviewLines == Lines)
  631.         {
  632.             LONG Delta = ReviewLines - Unit -> cu_YMax;
  633.  
  634.             if(Delta < 0)
  635.                 ReviewTop += Delta;
  636.             else
  637.                 ReviewTop -= Delta;
  638.  
  639.             if(ReviewTop < 0)
  640.                 ReviewTop = 0;
  641.         }
  642.  
  643.         Refresh = TRUE;
  644.  
  645.         ReviewLines = Unit -> cu_YMax;
  646.     }
  647.  
  648.     if(Refresh)
  649.         ReviewUpdatePot();
  650.  
  651.     return(TRUE);
  652. }
  653.  
  654.     /* GetReviewChar(BYTE WaitForIt):
  655.      *
  656.      *    Get the next character present at the console read port.
  657.      */
  658.  
  659. STATIC UBYTE __regargs
  660. GetReviewChar(BYTE WaitForIt)
  661. {
  662.     UBYTE Char;
  663.  
  664.     if(!WaitForIt)
  665.     {
  666.         if(!CheckIO(ReviewReadRequest))
  667.             return(0);
  668.     }
  669.  
  670.     WaitIO(ReviewReadRequest);
  671.  
  672.     Char = ReviewChar;
  673.  
  674.     ReviewReadRequest -> io_Command    = CMD_READ;
  675.     ReviewReadRequest -> io_Data    = &ReviewChar;
  676.     ReviewReadRequest -> io_Length    = 1;
  677.  
  678.     SendIO(ReviewReadRequest);
  679.  
  680.     return(Char);
  681. }
  682.  
  683.     /* MarkReviewLine(STRPTR Buffer,LONG Line,LONG Column,LONG Len):
  684.      *
  685.      *    Similar to PrintReviewLine(), but also allows to mark a
  686.      *    certain word on the line.
  687.      */
  688.  
  689. STATIC VOID __regargs
  690. MarkReviewLine(STRPTR Buffer,LONG Line,LONG Column,LONG Len)
  691. {
  692.     WORD Length = Buffer[-1];
  693.  
  694.     if(Length > ReviewColumns)
  695.         Length = ReviewColumns;
  696.  
  697.     ReviewWrites("\33[%ldH",Line);
  698.  
  699.     if(Length <= Column)
  700.     {
  701.         ReviewWriteRequest -> io_Command    = CMD_WRITE;
  702.         ReviewWriteRequest -> io_Data        = Buffer;
  703.         ReviewWriteRequest -> io_Length        = Length;
  704.  
  705.         DoIO(ReviewWriteRequest);
  706.  
  707.         ReviewWrites("\33[0K");
  708.     }
  709.     else
  710.     {
  711.         ReviewWriteRequest -> io_Command    = CMD_WRITE;
  712.         ReviewWriteRequest -> io_Data        = Buffer;
  713.         ReviewWriteRequest -> io_Length        = Column;
  714.  
  715.         DoIO(ReviewWriteRequest);
  716.  
  717.         ReviewWrites("\33[7;3%ldm",ReviewPen);
  718.  
  719.         ReviewWriteRequest -> io_Command    = CMD_WRITE;
  720.         ReviewWriteRequest -> io_Data        = &Buffer[Column];
  721.         ReviewWriteRequest -> io_Length        = Len;
  722.  
  723.         DoIO(ReviewWriteRequest);
  724.  
  725.         ReviewWrites("\33[0;3%ldm",ReviewPen);
  726.  
  727.         if(Column + Len < Length)
  728.         {
  729.             ReviewWriteRequest -> io_Command    = CMD_WRITE;
  730.             ReviewWriteRequest -> io_Data        = &Buffer[Column + Len];
  731.             ReviewWriteRequest -> io_Length        = Length - (Column + Len);
  732.  
  733.             DoIO(ReviewWriteRequest);
  734.         }
  735.  
  736.         ReviewWrites("\33[0K");
  737.     }
  738. }
  739.  
  740.     /* ReviewMarkArea(LONG Top,LONG Column,LONG Line,LONG Len,BYTE FullRefresh):
  741.      *
  742.      *    Mark a word on the current display.
  743.      */
  744.  
  745. STATIC VOID __regargs
  746. ReviewMarkArea(LONG Top,LONG Column,LONG Line,LONG Len,BYTE FullRefresh)
  747. {
  748.     STATIC LONG LastMarked = -1;
  749.  
  750.     LONG i,Last,LineIndex = 0;
  751.  
  752.     ReviewGlobalLines = Lines;
  753.  
  754.     ObtainSemaphore(BufferSemaphore);
  755.  
  756.     if((Last = Top + ReviewLines + 1) >= Lines)
  757.         Last = Lines;
  758.  
  759.     if(FullRefresh)
  760.     {
  761.         if(BufferLines)
  762.         {
  763.             for(i = Top ; i < Last ; i++)
  764.             {
  765.                 if(i != Line)
  766.                     PrintReviewLine(BufferLines[i],++LineIndex);
  767.                 else
  768.                     MarkReviewLine(BufferLines[i],++LineIndex,Column,Len);
  769.             }
  770.         }
  771.  
  772.         if(LineIndex <= ReviewLines)
  773.             ReviewWrites("\33[0J");
  774.     }
  775.     else
  776.     {
  777.         if(BufferLines)
  778.         {
  779.             for(i = Top ; i < Last ; i++)
  780.             {
  781.                 LineIndex++;
  782.  
  783.                 if(i == LastMarked)
  784.                     PrintReviewLine(BufferLines[i],LineIndex);
  785.  
  786.                 if(i == Line)
  787.                     MarkReviewLine(BufferLines[i],LineIndex,Column,Len);
  788.             }
  789.         }
  790.     }
  791.  
  792.     LastMarked = Line;
  793.  
  794.     ReleaseSemaphore(BufferSemaphore);
  795. }
  796.  
  797.     /* ReviewSearch(struct SearchInfo *SearchInfo):
  798.      *
  799.      *    Search for a certain word in the text buffer.
  800.      */
  801.  
  802. STATIC VOID __regargs
  803. ReviewSearch(struct SearchInfo *SearchInfo,STRPTR SearchBuffer)
  804. {
  805.     LT_LockWindow(ReviewWindow);
  806.  
  807.     if(Lines)
  808.     {
  809.         LONG LineNumber;
  810.  
  811.         ObtainSemaphore(BufferSemaphore);
  812.  
  813.         LineNumber = SearchTextBuffer(SearchInfo);
  814.  
  815.         ReleaseSemaphore(BufferSemaphore);
  816.  
  817.         if(LineNumber == -1)
  818.         {
  819.             RefreshReview(ReviewTop);
  820.  
  821.             MyEasyRequest(ReviewWindow,LocaleString(MSG_TERMBUFFER_DID_NOT_FIND_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SearchBuffer);
  822.  
  823.             SearchInfo -> FoundY = -1;
  824.         }
  825.         else
  826.         {
  827.             if(LineNumber < ReviewTop || LineNumber > ReviewTop + ReviewLines)
  828.             {
  829.                 if(LineNumber + ReviewLines > Lines)
  830.                 {
  831.                     ReviewTop = Lines - ReviewLines;
  832.  
  833.                     if(ReviewTop < 0)
  834.                         ReviewTop = 0;
  835.                 }
  836.                 else
  837.                     ReviewTop = LineNumber;
  838.  
  839.                 ReviewUpdatePot();
  840.  
  841.                 ReviewMarkArea(ReviewTop,SearchInfo -> FoundX,LineNumber,SearchInfo -> PatternWidth,TRUE);
  842.             }
  843.             else
  844.                 ReviewMarkArea(ReviewTop,SearchInfo -> FoundX,LineNumber,SearchInfo -> PatternWidth,FALSE);
  845.         }
  846.     }
  847.     else
  848.         MyEasyRequest(ReviewWindow,LocaleString(MSG_GLOBAL_NOTHING_IN_THE_BUFFER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  849.  
  850.     LT_UnlockWindow(ReviewWindow);
  851. }
  852.  
  853. STATIC VOID
  854. LocalDeleteReview(VOID)
  855. {
  856.     if(ReviewReadRequest)
  857.     {
  858.         if(ReviewReadRequest -> io_Device)
  859.         {
  860.             if(!CheckIO(ReviewReadRequest))
  861.                 AbortIO(ReviewReadRequest);
  862.  
  863.             WaitIO(ReviewReadRequest);
  864.         }
  865.  
  866.         FreeVecPooled(ReviewReadRequest);
  867.  
  868.         ReviewReadRequest = NULL;
  869.     }
  870.  
  871.     if(ReviewWriteRequest)
  872.     {
  873.         if(ReviewWriteRequest -> io_Device)
  874.             CloseDevice(ReviewWriteRequest);
  875.  
  876.         DeleteIORequest(ReviewWriteRequest);
  877.  
  878.         ReviewWriteRequest = NULL;
  879.     }
  880.  
  881.     if(ReviewWindow)
  882.     {
  883.         PutWindowInfo(WINDOW_REVIEW,ReviewWindow -> LeftEdge,ReviewWindow -> TopEdge,ReviewWindow -> Width,ReviewWindow -> Height);
  884.  
  885.         LT_DeleteWindowLock(ReviewWindow);
  886.  
  887.         ClearMenuStrip(ReviewWindow);
  888.  
  889.         CloseWindow(ReviewWindow);
  890.  
  891.         ReviewWindow = NULL;
  892.     }
  893.  
  894.     if(ReviewMenuStrip)
  895.     {
  896.         FreeMenus(ReviewMenuStrip);
  897.  
  898.         ReviewMenuStrip = NULL;
  899.     }
  900.  
  901.     ReviewDeleteScroller();
  902.  
  903.     if(ReviewWritePort)
  904.     {
  905.         DeleteMsgPort(ReviewWritePort);
  906.  
  907.         ReviewWritePort = NULL;
  908.     }
  909.  
  910.     if(ReviewPort)
  911.     {
  912.         DeleteMsgPort(ReviewPort);
  913.  
  914.         ReviewPort = NULL;
  915.     }
  916.  
  917.     if(ReviewSignal != -1)
  918.     {
  919.         FreeSignal(ReviewSignal);
  920.  
  921.         ReviewSignal = -1;
  922.     }
  923.  
  924.     if(ReviewLineWidths)
  925.     {
  926.         FreeVecPooled(ReviewLineWidths);
  927.  
  928.         ReviewLineWidths = NULL;
  929.     }
  930.  
  931.     if(ReviewQueue)
  932.     {
  933.         DeleteMsgQueue(ReviewQueue);
  934.  
  935.         ReviewQueue = NULL;
  936.     }
  937. }
  938.  
  939. STATIC BOOLEAN
  940. LocalCreateReview(VOID)
  941. {
  942.     if(ReviewBox . Left == -1)
  943.     {
  944.         ReviewBox . Left    = 0;
  945.         ReviewBox . Top        = Window -> WScreen -> BarHeight + 1;
  946.         ReviewBox . Width    = Window -> WScreen -> Width;
  947.         ReviewBox . Height    = Window -> WScreen -> Height - (Window -> WScreen -> BarHeight + 1);
  948.     }
  949.  
  950.     if((ReviewSignal = AllocSignal(-1)) != -1)
  951.     {
  952.         if(ReviewQueue = CreateMsgQueue(NULL,0))
  953.         {
  954.             if(ReviewCreateScroller(Window -> WScreen))
  955.             {
  956.                 LocalizeMenu(ReviewMenu,MSG_TERMREVIEW_PROJECT_MEN);
  957.  
  958.                 if(ReviewMenuStrip = CreateMenus(ReviewMenu,TAG_DONE))
  959.                 {
  960.                     if(LayoutMenus(ReviewMenuStrip,VisualInfo,
  961.                         AmigaGlyph ? GTMN_AmigaKey :  TAG_IGNORE, AmigaGlyph,
  962.                         CheckGlyph ? GTMN_Checkmark : TAG_IGNORE, CheckGlyph,
  963.  
  964.                         GTMN_TextAttr,        &UserFont,
  965.                         GTMN_NewLookMenus,    TRUE,
  966.                     TAG_DONE))
  967.                     {
  968.                         LONG    Left    = 0,
  969.                             Top    = 0,
  970.                             Width    = 0,
  971.                             Height    = 0;
  972.  
  973.                         GetWindowInfo(WINDOW_REVIEW,&Left,&Top,&Width,&Height,NULL,Window -> WScreen -> WBorTop + Window -> WScreen -> WBorBottom + 1 + Window -> WScreen -> Font -> ta_YSize + 10 * CurrentFont -> tf_YSize);
  974.  
  975.                         if(ReviewWindow = OpenWindowTags(NULL,
  976.                             WA_Left,        Left,
  977.                             WA_Top,            Top,
  978.                             WA_Width,        Width,
  979.                             WA_Height,        Height,
  980.                             WA_MinWidth,        Window -> WScreen -> WBorLeft + RightBorderWidth + 15 * CurrentFont -> tf_XSize,
  981.                             WA_MinHeight,        Window -> WScreen -> WBorTop + Window -> WScreen -> WBorBottom + 1 + Window -> WScreen -> Font -> ta_YSize + 2 * CurrentFont -> tf_YSize,
  982.                             WA_MaxWidth,        Window -> WScreen -> Width,
  983.                             WA_MaxHeight,        Window -> WScreen -> Height,
  984.                             WA_DragBar,        TRUE,
  985.                             WA_CloseGadget,        TRUE,
  986.                             WA_DepthGadget,        TRUE,
  987.                             WA_SizeGadget,        TRUE,
  988.                             WA_SizeBRight,        TRUE,
  989.                             WA_MenuHelp,        TRUE,
  990.                             WA_IDCMP,        IDCMP_IDCMPUPDATE | IDCMP_GADGETDOWN | IDCMP_SIZEVERIFY | IDCMP_MOUSEMOVE | IDCMP_MENUPICK | IDCMP_MENUHELP,
  991.                             WA_Title,        LocaleString(MSG_TERMREVIEW_REVIEWBUFFER_TXT),
  992.                             WA_CustomScreen,    Window -> WScreen,
  993.                             WA_SimpleRefresh,    TRUE,
  994.                             WA_RMBTrap,        TRUE,
  995.                             WA_Activate,        TRUE,
  996.                             WA_NewLookMenus,    TRUE,
  997.                             WA_Zoom,        &ReviewBox,
  998.                             WA_Gadgets,        Scroller,
  999.  
  1000.                             AmigaGlyph ? WA_AmigaKey  : TAG_IGNORE, AmigaGlyph,
  1001.                             CheckGlyph ? WA_Checkmark : TAG_IGNORE, CheckGlyph,
  1002.                         TAG_DONE))
  1003.                         {
  1004.                             ReviewMaxLines = (ReviewWindow -> WScreen -> Height - (ReviewWindow -> BorderTop + ReviewWindow -> BorderBottom)) / CurrentFont -> tf_YSize;
  1005.  
  1006.                             if(ReviewLineWidths = (UBYTE *)AllocVecPooled(ReviewMaxLines,MEMF_ANY | MEMF_CLEAR))
  1007.                             {
  1008.                                 SetMenuStrip(ReviewWindow,ReviewMenuStrip);
  1009.  
  1010.                                 SetFont(ReviewWindow -> RPort,CurrentFont);
  1011.  
  1012.                                 if(ReviewWritePort = CreateMsgPort())
  1013.                                 {
  1014.                                     if(ReviewPort = CreateMsgPort())
  1015.                                     {
  1016.                                         if(ReviewWriteRequest = CreateIORequest(ReviewPort,sizeof(struct IOStdReq)))
  1017.                                         {
  1018.                                             if(ReviewReadRequest = (struct IOStdReq *)AllocVecPooled(sizeof(struct IOStdReq),MEMF_ANY | MEMF_CLEAR))
  1019.                                             {
  1020.                                                 ReviewWriteRequest -> io_Data = ReviewWindow;
  1021.  
  1022.                                                 if(!OpenDevice("console.device",CONU_SNIPMAP,ReviewWriteRequest,CONFLAG_NODRAW_ON_NEWSIZE))
  1023.                                                 {
  1024.                                                     CopyMem(ReviewWriteRequest,ReviewReadRequest,sizeof(struct IOStdReq));
  1025.  
  1026.                                                     ReviewReadRequest -> io_Message . mn_ReplyPort = ReviewPort;
  1027.  
  1028.                                                     switch(Config -> ScreenConfig -> ColourMode)
  1029.                                                     {
  1030.                                                         case COLOUR_AMIGA:
  1031.                                                         case COLOUR_MONO:
  1032.  
  1033.                                                             ReviewPen = 1;
  1034.                                                             break;
  1035.  
  1036.                                                         case COLOUR_EIGHT:
  1037.                                                         case COLOUR_SIXTEEN:
  1038.  
  1039.                                                             ReviewPen = 7;
  1040.                                                             break;
  1041.                                                     }
  1042.  
  1043.                                                     ReviewPen = GetPenIndex(ReviewPen) & 7;
  1044.  
  1045.     /*                                                ReviewWrites("\33[0 p\33[11;12\173\33[3%ldm",RenderPens[1] & 7);*/
  1046.                                                     ReviewWrites("\33[0 p\33[11;12\173\33[3%ldm",ReviewPen);
  1047.  
  1048.                                                     ReviewQuery();
  1049.  
  1050.                                                     ObtainSemaphore(BufferSemaphore);
  1051.  
  1052.                                                     if(ReviewTop == -1 || !Config -> CaptureConfig -> RememberBufferWindow)
  1053.                                                     {
  1054.                                                         switch(Config -> CaptureConfig -> OpenBufferWindow)
  1055.                                                         {
  1056.                                                             case BUFFER_TOP:
  1057.  
  1058.                                                                 ReviewTop = 0;
  1059.                                                                 break;
  1060.  
  1061.                                                             case BUFFER_END:
  1062.  
  1063.                                                                 if((ReviewTop = Lines - ReviewLines) < 0)
  1064.                                                                     ReviewTop = 0;
  1065.  
  1066.                                                                 break;
  1067.  
  1068.                                                             default:
  1069.  
  1070.                                                                 ReviewTop = 0;
  1071.                                                                 break;
  1072.                                                         }
  1073.                                                     }
  1074.  
  1075.                                                     if(ReviewTop > Lines - ReviewLines)
  1076.                                                     {
  1077.                                                         if((ReviewTop = Lines - ReviewLines) < 0)
  1078.                                                             ReviewTop = 0;
  1079.                                                     }
  1080.  
  1081.                                                     ReleaseSemaphore(BufferSemaphore);
  1082.  
  1083.                                                     RefreshReview(ReviewTop);
  1084.  
  1085.                                                     ReviewUpdatePot();
  1086.  
  1087.                                                     ReviewReadRequest -> io_Command    = CMD_READ;
  1088.                                                     ReviewReadRequest -> io_Data    = &ReviewChar;
  1089.                                                     ReviewReadRequest -> io_Length    = 1;
  1090.  
  1091.                                                     SendIO(ReviewReadRequest);
  1092.  
  1093.                                                     ReviewWindow -> Flags &= ~WFLG_RMBTRAP;
  1094.  
  1095.                                                     return(TRUE);
  1096.                                                 }
  1097.                                             }
  1098.                                         }
  1099.                                     }
  1100.                                 }
  1101.                             }
  1102.                         }
  1103.                     }
  1104.                 }
  1105.             }
  1106.         }
  1107.     }
  1108.  
  1109.     LocalDeleteReview();
  1110.  
  1111.     return(FALSE);
  1112. }
  1113.  
  1114.     /* LocalUpdateReview():
  1115.      *
  1116.      *    Update the contents of the review buffer window.
  1117.      */
  1118.  
  1119. STATIC VOID __regargs
  1120. LocalUpdateReview(BYTE Force)
  1121. {
  1122.     if(Force)
  1123.     {
  1124.         if(Lines)
  1125.         {
  1126.             if(ReviewTop > 0)
  1127.             {
  1128.                 SetGadgetAttrs(Scroller,ReviewWindow,NULL,
  1129.                     PGA_Top,--ReviewTop,
  1130.                 TAG_DONE);
  1131.             }
  1132.             else
  1133.                 MoveUp();
  1134.         }
  1135.     }
  1136.     else
  1137.     {
  1138.         if(Lines >= ReviewGlobalLines && ReviewGlobalLines <= ReviewLines)
  1139.             RefreshReview(ReviewTop);
  1140.     }
  1141.  
  1142.     ReviewGlobalLines = Lines;
  1143.  
  1144.     if(!Lines)
  1145.     {
  1146.         SetGadgetAttrs(Scroller,ReviewWindow,NULL,
  1147.             PGA_Top,    ReviewTop = 0,
  1148.             PGA_Visible,    1,
  1149.             PGA_Total,    1,
  1150.         TAG_DONE);
  1151.  
  1152.         ReviewWrites("\f\33[3%ldm",ReviewPen);
  1153.     }
  1154.     else
  1155.         ReviewUpdatePot();
  1156. }
  1157.  
  1158.     /* LocalMoveReview(BYTE Mode):
  1159.      *
  1160.      *    Move the currently visible review area.
  1161.      */
  1162.  
  1163. STATIC VOID __regargs
  1164. LocalMoveReview(BYTE Mode)
  1165. {
  1166.     LONG NewTop;
  1167.  
  1168.     switch(Mode)
  1169.     {
  1170.         case REVIEW_MOVE_TOP:
  1171.  
  1172.             if(ReviewTop)
  1173.             {
  1174.                 ScrollReview(0);
  1175.  
  1176.                 ReviewUpdatePot();
  1177.             }
  1178.  
  1179.             break;
  1180.  
  1181.         case REVIEW_MOVE_BOTTOM:
  1182.  
  1183.             NewTop = Lines - ReviewLines;
  1184.  
  1185.             if(NewTop < 0)
  1186.                 NewTop = 0;
  1187.  
  1188.             if(ReviewTop != NewTop)
  1189.             {
  1190.                 ScrollReview(NewTop);
  1191.  
  1192.                 ReviewUpdatePot();
  1193.             }
  1194.  
  1195.             break;
  1196.  
  1197.         case REVIEW_MOVE_UP:
  1198.  
  1199.             ReviewUp(ReviewLines);
  1200.             break;
  1201.  
  1202.         case REVIEW_MOVE_DOWN:
  1203.  
  1204.             ReviewDown(ReviewLines);
  1205.             break;
  1206.     }
  1207. }
  1208.  
  1209. STATIC VOID __stdargs
  1210. ReviewDestructor(struct MsgItem *Item)
  1211. {
  1212.     Signal(ReviewTask,1L << ReviewSignal);
  1213. }
  1214.  
  1215. STATIC VOID __regargs
  1216. ReviewSerWrite(APTR Data,LONG Size)
  1217. {
  1218.     struct DataMsg Msg;
  1219.  
  1220.     InitMsgItem(&Msg,ReviewDestructor);
  1221.  
  1222.     Msg . Type = DATAMSGTYPE_WRITE;
  1223.     Msg . Data = Data;
  1224.     Msg . Size = Size;
  1225.  
  1226.     Forbid();
  1227.  
  1228.     ClrSignal(1L << ReviewSignal);
  1229.  
  1230.     PutMsgItem(SpecialQueue,(struct MsgItem *)&Msg);
  1231.  
  1232.     Wait(1L << ReviewSignal);
  1233.  
  1234.     Permit();
  1235. }
  1236.  
  1237. STATIC VOID __saveds
  1238. ReviewTaskEntry(VOID)
  1239. {
  1240.     struct Process *Father = ThisProcess;
  1241.  
  1242.     if(LocalCreateReview())
  1243.     {
  1244.         UBYTE             SearchBuffer[256];
  1245.         struct Hook         HistoryHook;
  1246.         ULONG             Signals;
  1247.         BOOLEAN             Done        = FALSE;
  1248.         struct SearchInfo    *SearchInfo    = NULL;
  1249.         struct SearchContext    *Context    = NULL;
  1250.  
  1251.         HistoryHook . h_Data = &ReviewBufferHistory;
  1252.  
  1253.         ReviewTask = SysBase -> ThisTask;
  1254.  
  1255.         Signal(ThisProcess,SIG_HANDSHAKE);
  1256.  
  1257.         do
  1258.         {
  1259.             Signals = Wait(SIG_KILL | SIG_REVIEWPORT | SIG_REVIEWWINDOW | ReviewQueue -> SigMask);
  1260.  
  1261.             if(Signals & SIG_KILL)
  1262.                 break;
  1263.  
  1264.             if(Signals & SIG_REVIEWPORT)
  1265.             {
  1266.                 UBYTE Char;
  1267.  
  1268.                     /* Control sequence available? */
  1269.  
  1270.                 if((Char = GetReviewChar(FALSE)) == CSI)
  1271.                 {
  1272.                     UBYTE    InputBuffer[257];
  1273.                     WORD    Count = 0;
  1274.  
  1275.                         /* Try to read the entire sequence. */
  1276.  
  1277.                     while(Char = GetReviewChar(FALSE))
  1278.                     {
  1279.                         InputBuffer[Count++] = Char;
  1280.  
  1281.                         if(Char != ' ' && Char != ';' && (Char < '0' || Char > '9'))
  1282.                             break;
  1283.                     }
  1284.  
  1285.                         /* Provide termination. */
  1286.  
  1287.                     InputBuffer[Count] = 0;
  1288.  
  1289.                         /* Raw event? */
  1290.  
  1291.                     if(!strcmp(InputBuffer,"?~"))
  1292.                         GuideDisplay(CONTEXT_TEXTBUFFER);
  1293.  
  1294.                     if(!strcmp(InputBuffer,"A"))
  1295.                         ReviewUp(1);
  1296.  
  1297.                     if(!strcmp(InputBuffer,"B"))
  1298.                         ReviewDown(1);
  1299.  
  1300.                     if(!strcmp(InputBuffer,"T"))
  1301.                         ReviewUp(ReviewLines);
  1302.  
  1303.                     if(!strcmp(InputBuffer,"S"))
  1304.                         ReviewDown(ReviewLines);
  1305.  
  1306.                     if(!memcmp(InputBuffer,"11;",3))
  1307.                     {
  1308.                         Done = TRUE;
  1309.  
  1310.                         if(!(SetSignal(0,SIG_KILL) & SIG_KILL))
  1311.                             Father = NULL;
  1312.                     }
  1313.  
  1314.                     if(!memcmp(InputBuffer,"12;",3))
  1315.                     {
  1316.                         if(ReviewQuery())
  1317.                             RefreshReview(ReviewTop);
  1318.                     }
  1319.  
  1320.                     if(!strcmp(InputBuffer,"0 v"))
  1321.                     {
  1322.                         struct DataMsg Msg;
  1323.  
  1324.                         InitMsgItem(&Msg,ReviewDestructor);
  1325.  
  1326.                         Msg . Type = DATAMSGTYPE_WRITECLIP;
  1327.                         Msg . Size = Config -> ClipConfig -> ClipboardUnit;
  1328.  
  1329.                         Forbid();
  1330.  
  1331.                         ClrSignal(1L << ReviewSignal);
  1332.  
  1333.                         PutMsgItem(SpecialQueue,(struct MsgItem *)&Msg);
  1334.  
  1335.                         Wait(1L << ReviewSignal);
  1336.  
  1337.                         Permit();
  1338.                     }
  1339.                 }
  1340.                 else
  1341.                 {
  1342.                     if(Char)
  1343.                     {
  1344.                         if(Config -> SerialConfig -> StripBit8)
  1345.                             Char &= 0x7F;
  1346.  
  1347.                         if(Status == STATUS_HOLDING)
  1348.                         {
  1349.                             if(Char == XOF)
  1350.                             {
  1351.                                 ReviewSerWrite(&Char,1);
  1352.  
  1353.                                 Status = STATUS_READY;
  1354.                             }
  1355.                         }
  1356.                         else
  1357.                         {
  1358.                                 /* Convert chars
  1359.                                  * as approriate.
  1360.                                  */
  1361.  
  1362.                             if(Char == '\n')
  1363.                             {
  1364.                                 switch(Config -> TerminalConfig -> SendLF)
  1365.                                 {
  1366.                                     case EOL_LF:
  1367.  
  1368.                                         goto SendIt;
  1369.  
  1370.                                     case EOL_LFCR:
  1371.  
  1372.                                         ReviewSerWrite("\n\r",2);
  1373.                                         break;
  1374.  
  1375.                                     case EOL_CRLF:
  1376.  
  1377.                                         ReviewSerWrite("\r\n",2);
  1378.                                         break;
  1379.  
  1380.                                     case EOL_CR:
  1381.  
  1382.                                         ReviewSerWrite("\r",1);
  1383.                                         break;
  1384.                                 }
  1385.                             }
  1386.  
  1387.                             if(Char == '\r')
  1388.                             {
  1389.                                 switch(Config -> TerminalConfig -> SendCR)
  1390.                                 {
  1391.                                     case EOL_CR:
  1392.  
  1393.                                         goto SendIt;
  1394.  
  1395.                                     case EOL_LFCR:
  1396.  
  1397.                                         ReviewSerWrite("\n\r",2);
  1398.                                         break;
  1399.  
  1400.                                     case EOL_CRLF:
  1401.  
  1402.                                         ReviewSerWrite("\r\n",2);
  1403.                                         break;
  1404.  
  1405.                                     case EOL_LF:
  1406.  
  1407.                                         ReviewSerWrite("\n",1);
  1408.                                         break;
  1409.                                 }
  1410.                             }
  1411.  
  1412.                                 /* Stop in/output. */
  1413.  
  1414.                             if(Char == XON)
  1415.                             {
  1416.                                 if(Config -> SerialConfig -> PassThrough)
  1417.                                     ReviewSerWrite(&Char,1);
  1418.                                 else
  1419.                                 {
  1420.                                     if(Config -> SerialConfig -> xONxOFF)
  1421.                                         Status = STATUS_HOLDING;
  1422.                                 }
  1423.                             }
  1424.  
  1425.                                 /* Restart in/output. */
  1426.  
  1427.                             if(Char == XOF)
  1428.                             {
  1429.                                 if(Config -> SerialConfig -> PassThrough)
  1430.                                     ReviewSerWrite(&Char,1);
  1431.                             }
  1432.  
  1433.                                 /* Convert special
  1434.                                  * Amiga characters into
  1435.                                  * alien IBM dialect.
  1436.                                  */
  1437.  
  1438. SendIt:                            if(Config -> TerminalConfig -> FontMode == FONT_IBM)
  1439.                             {
  1440.                                 if(IBMConversion[Char])
  1441.                                     ReviewSerWrite(&IBMConversion[Char],1);
  1442.                                 else
  1443.                                     ReviewSerWrite(&Char,1);
  1444.                             }
  1445.                             else
  1446.                                 ReviewSerWrite(&Char,1);
  1447.                         }
  1448.                     }
  1449.                 }
  1450.             }
  1451.  
  1452.             if(Signals & SIG_REVIEWWINDOW)
  1453.             {
  1454.                 struct IntuiMessage    *Message;
  1455.                 struct MenuItem        *MenuItem;
  1456.                 struct TagItem        *TagList;
  1457.                 ULONG             MsgClass;
  1458.                 UWORD             MsgCode,
  1459.                              MsgQualifier;
  1460.  
  1461.                 while(Message = (struct IntuiMessage *)GetMsg(ReviewWindow -> UserPort))
  1462.                 {
  1463.                     if(Context && Context -> SearchWindow == Message -> IDCMPWindow)
  1464.                     {
  1465.                         MsgClass = NULL;
  1466.  
  1467.                         if(HandleSearchMessage(Context,&Message))
  1468.                         {
  1469.                             BOOLEAN Ok = Context -> Ok;
  1470.  
  1471.                             DeleteSearchContext(Context);
  1472.  
  1473.                             Context = NULL;
  1474.  
  1475.                             if(Ok)
  1476.                             {
  1477.                                 if(SearchInfo)
  1478.                                     DeleteSearchInfo(SearchInfo);
  1479.  
  1480.                                 if(SearchInfo = CreateSearchInfo(SearchBuffer,SearchForward,IgnoreCase,WholeWords))
  1481.                                     ReviewSearch(SearchInfo,SearchBuffer);
  1482.                             }
  1483.                             else
  1484.                             {
  1485.                                 if(SearchInfo)
  1486.                                 {
  1487.                                     DeleteSearchInfo(SearchInfo);
  1488.  
  1489.                                     SearchInfo = NULL;
  1490.                                 }
  1491.                             }
  1492.                         }
  1493.                     }
  1494.                     else
  1495.                     {
  1496.                         MsgClass    = Message -> Class;
  1497.                         MsgCode        = Message -> Code;
  1498.                         MsgQualifier    = Message -> Qualifier;
  1499.                         TagList        = (struct TagItem *)Message -> IAddress;
  1500.  
  1501.                         ReplyMsg((struct Message *)Message);
  1502.                     }
  1503.  
  1504.                     switch(MsgClass)
  1505.                     {
  1506.                         case IDCMP_MENUHELP:
  1507.  
  1508.                             GuideDisplay(CONTEXT_BUFFER_MENU);
  1509.                             break;
  1510.  
  1511.                         case IDCMP_IDCMPUPDATE:
  1512.  
  1513.                             switch(GetTagData(GA_ID,0,TagList))
  1514.                             {
  1515.                                 case GAD_UP:    ReviewUp(1);
  1516.                                         break;
  1517.  
  1518.                                 case GAD_DOWN:    ReviewDown(1);
  1519.                                         break;
  1520.                             }
  1521.  
  1522.                             break;
  1523.  
  1524.                         case IDCMP_GADGETDOWN:
  1525.                         case IDCMP_MOUSEMOVE:
  1526.  
  1527.                             if(ReviewGlobalLines > ReviewLines)
  1528.                             {
  1529.                                 LONG NewTop;
  1530.  
  1531.                                 if(GetAttr(PGA_Top,Scroller,(ULONG *)&NewTop))
  1532.                                     ScrollReview(NewTop);
  1533.                             }
  1534.  
  1535.                             break;
  1536.  
  1537.                         case IDCMP_MENUPICK:
  1538.  
  1539.                             while(MsgCode != MENUNULL)
  1540.                             {
  1541.                                 MenuItem = ItemAddress(ReviewMenuStrip,MsgCode);
  1542.  
  1543.                                 switch((ULONG)GTMENUITEM_USERDATA(MenuItem))
  1544.                                 {
  1545.                                     case MEN_SEARCH:
  1546.  
  1547.                                         if(Context)
  1548.                                             LT_ShowWindow(Context -> SearchHandle,TRUE);
  1549.                                         else
  1550.                                             Context = CreateSearchContext(ReviewWindow,SearchBuffer,&HistoryHook,&SearchForward,&IgnoreCase,&WholeWords);
  1551.  
  1552.                                         break;
  1553.  
  1554.                                     case MEN_REPEAT:
  1555.  
  1556.                                         if(Context)
  1557.                                             LT_ShowWindow(Context -> SearchHandle,TRUE);
  1558.                                         else
  1559.                                         {
  1560.                                             if(SearchInfo)
  1561.                                                 ReviewSearch(SearchInfo,SearchBuffer);
  1562.                                             else
  1563.                                                 Context = CreateSearchContext(ReviewWindow,SearchBuffer,&HistoryHook,&SearchForward,&IgnoreCase,&WholeWords);
  1564.                                         }
  1565.  
  1566.                                         break;
  1567.  
  1568.                                     case MEN_QUITBUF:
  1569.  
  1570.                                         Done = TRUE;
  1571.  
  1572.                                         if(!(SetSignal(0,SIG_KILL) & SIG_KILL))
  1573.                                             Father = NULL;
  1574.  
  1575.                                         break;
  1576.  
  1577.                                     case MEN_CLEARBUF:
  1578.  
  1579.                                         if(Lines)
  1580.                                         {
  1581.                                             if(MsgQualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1582.                                                 FreeBuffer();
  1583.                                             else
  1584.                                             {
  1585.                                                 if(MyEasyRequest(ReviewWindow,LocaleString(MSG_TERMBUFFER_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Lines))
  1586.                                                     FreeBuffer();
  1587.                                             }
  1588.                                         }
  1589.  
  1590.                                         break;
  1591.                                 }
  1592.  
  1593.                                 MsgCode = MenuItem -> NextSelect;
  1594.                             }
  1595.  
  1596.                             break;
  1597.                     }
  1598.                 }
  1599.             }
  1600.  
  1601.             if(Signals & ReviewQueue -> SigMask)
  1602.             {
  1603.                 struct DataMsg *Msg;
  1604.  
  1605.                 while(Msg = (struct DataMsg *)GetMsgItem(ReviewQueue))
  1606.                 {
  1607.                     switch(Msg -> Type)
  1608.                     {
  1609.                         case DATAMSGTYPE_UPDATEREVIEW:
  1610.  
  1611.                             LocalUpdateReview(Msg -> Size);
  1612.                             break;
  1613.  
  1614.                         case DATAMSGTYPE_MOVEREVIEW:
  1615.  
  1616.                             LocalMoveReview(Msg -> Size);
  1617.                             break;
  1618.                     }
  1619.  
  1620.                     DeleteMsgItem(Msg);
  1621.                 }
  1622.             }
  1623.         }
  1624.         while(!Done);
  1625.  
  1626.         if(Context)
  1627.             DeleteSearchContext(Context);
  1628.  
  1629.         if(SearchInfo)
  1630.             DeleteSearchInfo(SearchInfo);
  1631.  
  1632.         LocalDeleteReview();
  1633.     }
  1634.  
  1635.     Forbid();
  1636.  
  1637.     ReviewTask = NULL;
  1638.  
  1639.     if(Father)
  1640.         Signal(Father,SIG_HANDSHAKE);
  1641.     else
  1642.         CheckItem(MEN_REVIEW_WINDOW,FALSE);
  1643. }
  1644.  
  1645. STATIC VOID __stdargs
  1646. ReviewClientDestructor(struct DataMsg *Item)
  1647. {
  1648.     Signal((struct Task *)Item -> Data,SIG_HANDSHAKE);
  1649. }
  1650.  
  1651. VOID __regargs
  1652. UpdateReview(BYTE Force)
  1653. {
  1654.     if(ReviewQueue)
  1655.     {
  1656.         if(SysBase -> ThisTask != ReviewTask)
  1657.         {
  1658.             struct DataMsg Msg;
  1659.  
  1660.             InitMsgItem(&Msg,ReviewClientDestructor);
  1661.  
  1662.             Msg . Type = DATAMSGTYPE_UPDATEREVIEW;
  1663.             Msg . Data = (UBYTE *)SysBase -> ThisTask;
  1664.             Msg . Size = Force;
  1665.  
  1666.             Forbid();
  1667.  
  1668.             PutMsgItem(ReviewQueue,(struct MsgItem *)&Msg);
  1669.  
  1670.             ClrSignal(SIG_HANDSHAKE);
  1671.  
  1672.             Wait(SIG_HANDSHAKE);
  1673.  
  1674.             Permit();
  1675.         }
  1676.         else
  1677.             LocalUpdateReview(Force);
  1678.     }
  1679. }
  1680.  
  1681. VOID __regargs
  1682. MoveReview(BYTE Mode)
  1683. {
  1684.     if(ReviewQueue)
  1685.     {
  1686.         if(SysBase -> ThisTask != ReviewTask)
  1687.         {
  1688.             struct DataMsg Msg;
  1689.  
  1690.             InitMsgItem(&Msg,ReviewClientDestructor);
  1691.  
  1692.             Msg . Type = DATAMSGTYPE_MOVEREVIEW;
  1693.             Msg . Data = (UBYTE *)SysBase -> ThisTask;
  1694.             Msg . Size = Mode;
  1695.  
  1696.             Forbid();
  1697.  
  1698.             PutMsgItem(ReviewQueue,(struct MsgItem *)&Msg);
  1699.  
  1700.             ClrSignal(SIG_HANDSHAKE);
  1701.  
  1702.             Wait(SIG_HANDSHAKE);
  1703.  
  1704.             Permit();
  1705.         }
  1706.         else
  1707.             LocalMoveReview(Mode);
  1708.     }
  1709. }
  1710.  
  1711. VOID
  1712. DeleteReview()
  1713. {
  1714.     CheckItem(MEN_REVIEW_WINDOW,FALSE);
  1715.  
  1716.     if(ReviewTask)
  1717.     {
  1718.         Forbid();
  1719.  
  1720.         ClrSignal(SIG_HANDSHAKE);
  1721.  
  1722.         Signal(ReviewTask,SIG_KILL);
  1723.  
  1724.         Wait(SIG_HANDSHAKE);
  1725.  
  1726.         Permit();
  1727.     }
  1728. }
  1729.  
  1730. BYTE
  1731. CreateReview()
  1732. {
  1733.     if(ReviewTask)
  1734.         return(TRUE);
  1735.     else
  1736.     {
  1737.         BYTE Result = FALSE;
  1738.  
  1739.         Forbid();
  1740.  
  1741.         if(CreateTask("term Review Task",SysBase -> ThisTask -> tc_Node . ln_Pri,ReviewTaskEntry,4000))
  1742.         {
  1743.             ClrSignal(SIG_HANDSHAKE);
  1744.  
  1745.             Wait(SIG_HANDSHAKE);
  1746.  
  1747.             if(ReviewTask)
  1748.             {
  1749.                 CheckItem(MEN_REVIEW_WINDOW,TRUE);
  1750.  
  1751.                 Result = TRUE;
  1752.             }
  1753.         }
  1754.  
  1755.         Permit();
  1756.  
  1757.         return(Result);
  1758.     }
  1759. }
  1760.