home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / comm / term23_2.lha / Source_Code / termSource / termReview.c < prev    next >
C/C++ Source or Header  |  1992-08-18  |  14KB  |  768 lines

  1. /*
  2. **    $Id: termReview.c,v 1.7 92/08/15 20:14:56 olsen Sta Locker: olsen $
  3. **    $Revision: 1.7 $
  4. **    $Date: 92/08/15 20:14:56 $
  5. **
  6. **    Support routines for the review buffer (not the log book!)
  7. **
  8. **    Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
  9. **        All Rights Reserved
  10. */
  11.  
  12. #include "termGlobal.h"
  13.  
  14.     /* Scroller gadget flags. */
  15.  
  16. #define PROP_FLAGS    (AUTOKNOB | FREEVERT | PROPBORDERLESS | PROPNEWLOOK)
  17.  
  18.     /* Number of context lines to keep between pages. */
  19.  
  20. #define CONTEXT_LINES    1
  21.  
  22.     /* Local routines. */
  23.  
  24. STATIC VOID        ReviewUpdatePot(VOID);
  25. STATIC VOID __stdargs    ReviewWrites(STRPTR String,...);
  26. STATIC VOID __regargs    PrintReviewLine(STRPTR Buffer,LONG Line);
  27. STATIC VOID __regargs    RefreshReview(LONG Top);
  28. STATIC BYTE        ReviewQuery(VOID);
  29. STATIC UBYTE __regargs    GetReviewChar(BYTE WaitForIt);
  30.  
  31.     /* Local variables. */
  32.  
  33. STATIC struct IBox     ReviewBox;
  34. STATIC struct IOStdReq    *ReviewWriteRequest,
  35.             *ReviewReadRequest;
  36.  
  37. STATIC struct MsgPort    *ReviewWritePort;
  38.  
  39. STATIC LONG         ReviewWidth = -1,ReviewHeight,
  40.              ReviewX,ReviewY;
  41. STATIC UBYTE         ReviewChar;
  42. STATIC LONG         ReviewColumns,ReviewLines,ReviewTop,ReviewGlobalLines;
  43. STATIC LONG         ReviewBody = -1,ReviewPot = -1;
  44.  
  45. STATIC struct Image     ReviewPropImage;
  46.  
  47. STATIC struct PropInfo ReviewPropInfo =
  48. {
  49.     PROP_FLAGS,
  50.     0,MAXPOT,
  51.     0,MAXBODY,
  52.     0,0,
  53.     0,0,
  54.     0,0
  55. };
  56.  
  57. STATIC struct Gadget ReviewPropGadget =
  58. {
  59.     NULL,
  60.     0,0,
  61.     0,0,
  62.     GFLG_GADGHCOMP | GFLG_RELRIGHT | GFLG_RELHEIGHT,
  63.     GACT_IMMEDIATE | GACT_FOLLOWMOUSE,
  64.     GTYP_PROPGADGET,
  65.     &ReviewPropImage,
  66.     NULL,
  67.     NULL,
  68.     0,
  69.     (APTR)&ReviewPropInfo,
  70.     0,
  71.     NULL
  72. };
  73.  
  74.     /* ReviewUpdatePot():
  75.      *
  76.      *    Update size and position of the scroller gadget.
  77.      */
  78.  
  79. STATIC VOID
  80. ReviewUpdatePot()
  81. {
  82.     if(ReviewGlobalLines)
  83.     {
  84.         LONG    Body,
  85.             Pot,
  86.             Hidden;
  87.  
  88.         Hidden = MAX(ReviewGlobalLines - ReviewLines,0);
  89.  
  90.         if(ReviewTop > Hidden)
  91.             ReviewTop = 0;
  92.  
  93.         if(Hidden > 0)
  94.         {
  95.             Body    = (UWORD)(((ULONG)(ReviewLines - CONTEXT_LINES) * MAXBODY) / (ReviewGlobalLines - CONTEXT_LINES));
  96.             Pot    = (UWORD)(((ULONG)ReviewTop * MAXPOT) / Hidden);
  97.         }
  98.         else
  99.         {
  100.             Body    = MAXBODY;
  101.             Pot    = 0;
  102.         }
  103.  
  104.         if(Body != ReviewBody || Pot != ReviewPot)
  105.         {
  106.             NewModifyProp(&ReviewPropGadget,ReviewWindow,NULL,PROP_FLAGS,0,Pot,0,Body,1);
  107.  
  108.             ReviewBody    = Body;
  109.             ReviewPot    = Pot;
  110.         }
  111.     }
  112. }
  113.  
  114.     /* ReviewUp(LONG Count):
  115.      *
  116.      *    Move the contents of the review buffer up.
  117.      */
  118.  
  119. STATIC VOID __regargs
  120. ReviewUp(LONG Count)
  121. {
  122.     if(Count == 1)
  123.     {
  124.         if(ReviewTop)
  125.         {
  126.             ReviewTop--;
  127.  
  128.             ReviewWrites("\033[T");
  129.  
  130.             ObtainSemaphore(BufferSemaphore);
  131.  
  132.             PrintReviewLine(BufferLines[ReviewTop],1);
  133.  
  134.             ReviewUpdatePot();
  135.  
  136.             ReleaseSemaphore(BufferSemaphore);
  137.         }
  138.     }
  139.     else
  140.     {
  141.         LONG NewTop = ReviewTop;
  142.  
  143.         if(NewTop >= Count)
  144.             NewTop -= Count;
  145.         else
  146.             NewTop = 0;
  147.  
  148.         if(NewTop != ReviewTop)
  149.         {
  150.             ReviewTop = NewTop;
  151.  
  152.             RefreshReview(ReviewTop);
  153.  
  154.             ReviewUpdatePot();
  155.         }
  156.     }
  157. }
  158.  
  159.     /* ReviewDown(LONG Count):
  160.      *
  161.      *    Move the contents of the review buffer down.
  162.      */
  163.  
  164. STATIC VOID __regargs
  165. ReviewDown(LONG Count)
  166. {
  167.     if(Count == 1)
  168.     {
  169.         if(ReviewTop + ReviewLines < Lines)
  170.         {
  171.             LONG Last;
  172.  
  173.             ReviewTop++;
  174.  
  175.             ReviewWrites("\033[S");
  176.  
  177.             ObtainSemaphore(BufferSemaphore);
  178.  
  179.             if((Last = ReviewTop + ReviewLines) < Lines)
  180.                 PrintReviewLine(BufferLines[Last],ReviewLines + 1);
  181.  
  182.             ReviewUpdatePot();
  183.  
  184.             ReleaseSemaphore(BufferSemaphore);
  185.         }
  186.     }
  187.     else
  188.     {
  189.         LONG NewTop = ReviewTop;
  190.  
  191.         if((NewTop + Count + ReviewLines) > Lines)
  192.         {
  193.             if((NewTop = Lines - ReviewLines) < 0)
  194.                 NewTop = 0;
  195.         }
  196.         else
  197.             NewTop += Count;
  198.  
  199.         if(NewTop != ReviewTop)
  200.         {
  201.             ReviewTop = NewTop;
  202.  
  203.             RefreshReview(ReviewTop);
  204.  
  205.             ReviewUpdatePot();
  206.         }
  207.     }
  208. }
  209.  
  210.     /* ReviewWrites(STRPTR String,...):
  211.      *
  212.      *    Write a string into the review buffer window.
  213.      */
  214.  
  215. STATIC VOID __stdargs
  216. ReviewWrites(STRPTR String,...)
  217. {
  218.     va_list    VarArgs;
  219.  
  220.     va_start(VarArgs,String);
  221.     VSPrintf(SharedBuffer,String,VarArgs);
  222.     va_end(VarArgs);
  223.  
  224.     ReviewWriteRequest -> io_Command    = CMD_WRITE;
  225.     ReviewWriteRequest -> io_Data        = SharedBuffer;
  226.     ReviewWriteRequest -> io_Length        = -1;
  227.  
  228.     DoIO(ReviewWriteRequest);
  229. }
  230.  
  231.     /* PrintReviewLine(STRPTR Buffer,LONG Line):
  232.      *
  233.      *    Write the contents of a buffer line into the review buffer window.
  234.      */
  235.  
  236. STATIC VOID __regargs
  237. PrintReviewLine(STRPTR Buffer,LONG Line)
  238. {
  239.     WORD Length = ((ULONG *)Buffer)[-1];
  240.  
  241.     if(Length > ReviewColumns)
  242.         Length = ReviewColumns;
  243.  
  244.     ReviewWrites("\033[%ldH",Line);
  245.  
  246.     ReviewWriteRequest -> io_Command    = CMD_WRITE;
  247.     ReviewWriteRequest -> io_Data        = Buffer;
  248.     ReviewWriteRequest -> io_Length        = Length;
  249.  
  250.     DoIO(ReviewWriteRequest);
  251.  
  252.     ReviewWrites("\033[0K");
  253. }
  254.  
  255.     /* RefreshReview(LONG Top):
  256.      *
  257.      *    Refresh the contents of the review buffer window.
  258.      */
  259.  
  260. STATIC VOID __regargs
  261. RefreshReview(LONG Top)
  262. {
  263.     LONG i,Last,Line = 0;
  264.  
  265.     ReviewGlobalLines = Lines;
  266.  
  267.     ObtainSemaphore(BufferSemaphore);
  268.  
  269.     if((Last = Top + ReviewLines + 1) >= Lines)
  270.         Last = Lines;
  271.  
  272.     for(i = Top ; i < Last ; i++)
  273.         PrintReviewLine(BufferLines[i],++Line);
  274.  
  275.     if(Line <= ReviewLines)
  276.         ReviewWrites("\033[0J");
  277.  
  278.     ReleaseSemaphore(BufferSemaphore);
  279. }
  280.  
  281.     /* ReviewQuery():
  282.      *
  283.      *    Update the current review buffer window dimensions.
  284.      */
  285.  
  286. STATIC BYTE
  287. ReviewQuery()
  288. {
  289.     struct ConUnit    *Unit = (struct ConUnit *)ReviewWriteRequest -> io_Unit;
  290.     BYTE         Refresh = FALSE;
  291.  
  292.     if(ReviewColumns != Unit -> cu_XMax)
  293.     {
  294.         Refresh = TRUE;
  295.  
  296.         ReviewColumns = Unit -> cu_XMax;
  297.     }
  298.  
  299.     if(ReviewLines != Unit -> cu_YMax)
  300.     {
  301.         LONG Delta = ABS(Unit -> cu_YMax - ReviewLines);
  302.  
  303.         Refresh = TRUE;
  304.  
  305.         if(ReviewLines)
  306.         {
  307.             if(Unit -> cu_YMax > ReviewLines)
  308.             {
  309.                 if((ReviewTop = ReviewTop - Delta) < 0)
  310.                     ReviewTop = 0;
  311.             }
  312.             else
  313.                 ReviewTop += Delta;
  314.         }
  315.  
  316.         ReviewLines = Unit -> cu_YMax;
  317.     }
  318.  
  319.     if(Refresh)
  320.         ReviewUpdatePot();
  321.  
  322.     return(Refresh);
  323. }
  324.  
  325.     /* GetReviewChar(BYTE WaitForIt):
  326.      *
  327.      *    Get the next character present at the console read port.
  328.      */
  329.  
  330. STATIC UBYTE __regargs
  331. GetReviewChar(BYTE WaitForIt)
  332. {
  333.     UBYTE Char;
  334.  
  335.     if(!WaitForIt)
  336.     {
  337.         if(!CheckIO(ReviewReadRequest))
  338.             return(0);
  339.     }
  340.  
  341.     WaitIO(ReviewReadRequest);
  342.  
  343.     Char = ReviewChar;
  344.  
  345.     ReviewReadRequest -> io_Command    = CMD_READ;
  346.     ReviewReadRequest -> io_Data    = &ReviewChar;
  347.     ReviewReadRequest -> io_Length    = 1;
  348.  
  349.     SendIO(ReviewReadRequest);
  350.  
  351.     return(Char);
  352. }
  353.  
  354.     /* DeleteReview():
  355.      *
  356.      *    Delete the review buffer.
  357.      */
  358.  
  359. VOID
  360. DeleteReview()
  361. {
  362.     struct MenuItem *Item;
  363.  
  364.     if(Item = FindThisItem(MEN_REVIEW_WINDOW))
  365.         Item -> Flags &= ~CHECKED;
  366.  
  367.     if(ReviewWriteRequest)
  368.     {
  369.         if(ReviewWriteRequest -> io_Device)
  370.         {
  371.             ReviewWriteRequest -> io_Command = CMD_CLEAR;
  372.  
  373.             DoIO(ReviewWriteRequest);
  374.  
  375.             CloseDevice(ReviewWriteRequest);
  376.         }
  377.  
  378.         DeleteIORequest(ReviewWriteRequest);
  379.  
  380.         ReviewWriteRequest = NULL;
  381.     }
  382.  
  383.     if(ReviewReadRequest)
  384.     {
  385.         if(ReviewReadRequest -> io_Device)
  386.         {
  387.             if(!CheckIO(ReviewReadRequest))
  388.                 AbortIO(ReviewReadRequest);
  389.  
  390.             WaitIO(ReviewReadRequest);
  391.         }
  392.  
  393.         FreeVec(ReviewReadRequest);
  394.  
  395.         ReviewReadRequest = NULL;
  396.     }
  397.  
  398.     ReviewPot = ReviewBody = -1;
  399.  
  400.     if(ReviewWindow)
  401.     {
  402.         ReviewWidth    = ReviewWindow -> Width;
  403.         ReviewHeight    = ReviewWindow -> Height;
  404.         ReviewX        = ReviewWindow -> LeftEdge;
  405.         ReviewY        = ReviewWindow -> TopEdge;
  406.  
  407.         CloseWindow(ReviewWindow);
  408.  
  409.         ReviewWindow = NULL;
  410.     }
  411.  
  412.     if(ReviewWritePort)
  413.     {
  414.         DeleteMsgPort(ReviewWritePort);
  415.  
  416.         ReviewWritePort = NULL;
  417.     }
  418.  
  419.     if(ReviewPort)
  420.     {
  421.         DeleteMsgPort(ReviewPort);
  422.  
  423.         ReviewPort = NULL;
  424.     }
  425. }
  426.  
  427.     /* CreateReview():
  428.      *
  429.      *    Create the review buffer.
  430.      */
  431.  
  432. BYTE
  433. CreateReview()
  434. {
  435.     if(ReviewWidth == -1)
  436.     {
  437.         ReviewWidth        = Screen -> Width;
  438.         ReviewHeight        = Screen -> WBorTop + Screen -> WBorBottom + 1 + Screen -> Font -> ta_YSize + 5 * Screen -> Font -> ta_YSize;
  439.         ReviewX            = 0;
  440.         ReviewY            = Screen -> BarHeight + 1;
  441.  
  442.         ReviewBox . Left    = 0;
  443.         ReviewBox . Top        = Screen -> BarHeight + 1;
  444.         ReviewBox . Width    = Screen -> Width;
  445.         ReviewBox . Height    = Screen -> Height - (Screen -> BarHeight + 1);
  446.     }
  447.  
  448.     ReviewPropGadget . TopEdge    = Screen -> WBorTop + Screen -> Font -> ta_YSize + 2;
  449.     ReviewPropGadget . LeftEdge    = -15;
  450.     ReviewPropGadget . Width    = 14;
  451.     ReviewPropGadget . Height    = -(ReviewPropGadget . TopEdge + Screen -> WBorBottom + 9);
  452.  
  453.     if(ReviewWindow = OpenWindowTags(NULL,
  454.         WA_Left,        ReviewX,
  455.         WA_Top,            ReviewY,
  456.         WA_Width,        ReviewWidth,
  457.         WA_Height,        ReviewHeight,
  458.         WA_MinWidth,        Screen -> WBorLeft + Screen -> WBorRight + 15 * 8,
  459.         WA_MinHeight,        Screen -> WBorTop + Screen -> WBorBottom + 1 + 2 * Screen -> Font -> ta_YSize,
  460.         WA_MaxWidth,        Screen -> Width,
  461.         WA_MaxHeight,        Screen -> Height,
  462.         WA_DragBar,        TRUE,
  463.         WA_CloseGadget,        TRUE,
  464.         WA_DepthGadget,        TRUE,
  465.         WA_SizeGadget,        TRUE,
  466.         WA_IDCMP,        IDCMP_GADGETDOWN | IDCMP_MOUSEMOVE,
  467.         WA_Title,        LocaleString(MSG_TERMREVIEW_REVIEWBUFFER_TXT),
  468.         WA_CustomScreen,    Screen,
  469.         WA_SimpleRefresh,    TRUE,
  470.         WA_RMBTrap,        TRUE,
  471.         WA_Activate,        TRUE,
  472.         WA_Zoom,        &ReviewBox,
  473.     TAG_DONE))
  474.     {
  475.         AddGadget(ReviewWindow,&ReviewPropGadget,-1);
  476.         RefreshGadgets(&ReviewPropGadget,ReviewWindow,NULL);
  477.  
  478.         SetFont(ReviewWindow -> RPort,CurrentFont);
  479.  
  480.         if(ReviewWritePort = CreateMsgPort())
  481.         {
  482.             if(ReviewPort = CreateMsgPort())
  483.             {
  484.                 if(ReviewWriteRequest = CreateIORequest(ReviewPort,sizeof(struct IOStdReq)))
  485.                 {
  486.                     if(ReviewReadRequest = (struct IOStdReq *)AllocVec(sizeof(struct IOStdReq),MEMF_PUBLIC | MEMF_CLEAR))
  487.                     {
  488.                         ReviewWriteRequest -> io_Data = ReviewWindow;
  489.  
  490.                         if(!OpenDevice("console.device",CONU_SNIPMAP,ReviewWriteRequest,CONFLAG_NODRAW_ON_NEWSIZE))
  491.                         {
  492.                             struct MenuItem    *Item;
  493.                             BYTE         Pen;
  494.  
  495.                             if(Item = FindThisItem(MEN_REVIEW_WINDOW))
  496.                                 Item -> Flags |= CHECKED;
  497.  
  498.                             switch(Config . ColourMode)
  499.                             {
  500.                                 case COLOUR_EIGHT:
  501.                                 case COLOUR_SIXTEEN:    Pen = 7;
  502.                                             break;
  503.  
  504.                                 default:        Pen = 1;
  505.                                             break;
  506.                             }
  507.  
  508.                             CopyMem(ReviewWriteRequest,ReviewReadRequest,sizeof(struct IOStdReq));
  509.  
  510.                             ReviewReadRequest -> io_Message . mn_ReplyPort = ReviewPort;
  511.  
  512.                             ReviewWrites("\033[0 p\033[11;12{\033[3%ldm",Pen);
  513.  
  514.                             ReviewQuery();
  515.  
  516.                             ObtainSemaphore(BufferSemaphore);
  517.  
  518.                             if((ReviewTop = Lines - ReviewLines) < 0)
  519.                                 ReviewTop = 0;
  520.  
  521.                             ReleaseSemaphore(BufferSemaphore);
  522.  
  523.                             RefreshReview(ReviewTop);
  524.  
  525.                             ReviewUpdatePot();
  526.  
  527.                             ReviewReadRequest -> io_Command    = CMD_READ;
  528.                             ReviewReadRequest -> io_Data    = &ReviewChar;
  529.                             ReviewReadRequest -> io_Length    = 1;
  530.  
  531.                             SendIO(ReviewReadRequest);
  532.  
  533.                             return(TRUE);
  534.                         }
  535.                     }
  536.                 }
  537.             }
  538.         }
  539.     }
  540.  
  541.     DeleteReview();
  542.  
  543.     return(FALSE);
  544. }
  545.  
  546.     /* UpdateReview():
  547.      *
  548.      *    Update the contents of the review buffer window.
  549.      */
  550.  
  551. VOID
  552. UpdateReview(BYTE Force)
  553. {
  554.     if(ReviewPort)
  555.     {
  556.         if(Force || (Lines >= ReviewGlobalLines && ReviewGlobalLines <= ReviewLines))
  557.             RefreshReview(ReviewTop);
  558.  
  559.         ReviewGlobalLines = Lines;
  560.  
  561.         ReviewUpdatePot();
  562.     }
  563. }
  564.  
  565.     /* HandleReview():
  566.      *
  567.      *    Process console and user input.
  568.      */
  569.  
  570. BYTE
  571. HandleReview()
  572. {
  573.     BYTE Result = FALSE;
  574.  
  575.     if(ReviewWindow)
  576.     {
  577.         struct IntuiMessage *Message;
  578.  
  579.         if(Message = (struct IntuiMessage *)GetMsg(ReviewWindow -> UserPort))
  580.         {
  581.             ReplyMsg((struct Message *)Message);
  582.  
  583.             if(ReviewGlobalLines > ReviewLines)
  584.             {
  585.                 UWORD Hidden;
  586.  
  587.                 Hidden        = MAX(ReviewGlobalLines - ReviewLines,0);
  588.                 ReviewTop    = (((ULONG)Hidden * ReviewPropInfo . VertPot) + (MAXPOT / 2)) >> 16;
  589.  
  590.                 RefreshReview(ReviewTop);
  591.             }
  592.  
  593.             Result = TRUE;
  594.         }
  595.     }
  596.  
  597.     if(ReviewPort)
  598.     {
  599.         UBYTE Char;
  600.  
  601.         if(Char = GetReviewChar(FALSE))
  602.         {
  603.             if(Char == CSI)
  604.             {
  605.                 WORD Count = 0;
  606.  
  607.                 Char = GetReviewChar(TRUE);
  608.  
  609.                 switch(Char)
  610.                 {
  611.                     case 'A':    ReviewUp(1);
  612.                             break;
  613.  
  614.                     case 'B':    ReviewDown(1);
  615.                             break;
  616.  
  617.                     case 'T':    ReviewUp(ReviewLines);
  618.                             break;
  619.  
  620.                     case 'S':    ReviewDown(ReviewLines);
  621.                             break;
  622.  
  623.                     default:    SharedBuffer[Count++] = Char;
  624.  
  625.                             while(Char = GetReviewChar(FALSE))
  626.                             {
  627.                                 SharedBuffer[Count++] = Char;
  628.  
  629.                                 if(Char == 'v' || Char == '|')
  630.                                     break;
  631.                             }
  632.  
  633.                             SharedBuffer[Count] = 0;
  634.  
  635.                             if(!strcmp(SharedBuffer,"0 v"))
  636.                             {
  637.                                 if(!ClipInput)
  638.                                 {
  639.                                     if(!OpenClip())
  640.                                         ClipInput = ClipXerox = TRUE;
  641.                                     else
  642.                                         ClipInput = ClipXerox = FALSE;
  643.                                 }
  644.                             }
  645.                             else
  646.                             {
  647.                                 if(!strncmp(SharedBuffer,"11",2))
  648.                                 {
  649.                                     DeleteReview();
  650.  
  651.                                     return(Result);
  652.                                 }
  653.  
  654.                                 if(!strncmp(SharedBuffer,"12",2))
  655.                                 {
  656.                                     if(ReviewQuery())
  657.                                         RefreshReview(ReviewTop);
  658.                                 }
  659.                             }
  660.  
  661.                             break;
  662.                 }
  663.             }
  664.             else
  665.             {
  666.                 if(Config . StripBit8)
  667.                     Char &= 0x7F;
  668.  
  669.                 if(Status == STATUS_HOLDING)
  670.                 {
  671.                     if(Char == XOF)
  672.                     {
  673.                         SerWrite(&Char,1);
  674.  
  675.                         Status = STATUS_READY;
  676.                     }
  677.                     else
  678.                         DoBeep();
  679.                 }
  680.                 else
  681.                 {
  682.                         /* Convert chars
  683.                          * as approriate.
  684.                          */
  685.  
  686.                     if(Char == '\n')
  687.                     {
  688.                         switch(Config . SendLF)
  689.                         {
  690.                             case LF_IGNORE:    break;
  691.  
  692.                             case LF_ASLF:    goto SendIt;
  693.  
  694.                             case LF_ASLFCR:    SerWrite("\n\r",2);
  695.                                     break;
  696.                         }
  697.  
  698.                         return(TRUE);
  699.                     }
  700.  
  701.                     if(Char == '\r')
  702.                     {
  703.                         switch(Config . SendCR)
  704.                         {
  705.                             case CR_IGNORE:    break;
  706.  
  707.                             case CR_ASCR:    goto SendIt;
  708.  
  709.                             case CR_ASCRLF:    SerWrite("\r\n",2);
  710.                                     break;
  711.                         }
  712.  
  713.                         return(TRUE);
  714.                     }
  715.  
  716.                         /* Stop in/output. */
  717.  
  718.                     if(Char == XON)
  719.                     {
  720.                         if(Config . PassThrough)
  721.                         {
  722.                             SerWrite(&Char,1);
  723.  
  724.                             return(TRUE);
  725.                         }
  726.                         else
  727.                         {
  728.                             if(Config . xONxOFF)
  729.                                 Status = STATUS_HOLDING;
  730.                         }
  731.                     }
  732.  
  733.                         /* Restart in/output. */
  734.  
  735.                     if(Char == XOF)
  736.                     {
  737.                         if(Config . PassThrough)
  738.                         {
  739.                             SerWrite(&Char,1);
  740.  
  741.                             return(TRUE);
  742.                         }
  743.                     }
  744.  
  745.                         /* Convert special
  746.                          * Amiga characters into
  747.                          * alien IBM dialect.
  748.                          */
  749.  
  750. SendIt:                    if(Config . Font == FONT_IBM)
  751.                     {
  752.                         if(IBMConversion[Char])
  753.                             SerWrite(&IBMConversion[Char],1);
  754.                         else
  755.                             SerWrite(&Char,1);
  756.                     }
  757.                     else
  758.                         SerWrite(&Char,1);
  759.                 }
  760.             }
  761.  
  762.             return(TRUE);
  763.         }
  764.     }
  765.  
  766.     return(Result);
  767. }
  768.