home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / communication / bbs / termv4.6 / extras / source / term-source.lha / XEM.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-18  |  21.6 KB  |  1,189 lines

  1. /*
  2. **    XEM.c
  3. **
  4. **    External emulation support routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16. STATIC LONG __saveds __asm
  17. xem_sflush(VOID)
  18. {
  19.     return((LONG)FlushSerialRead());
  20. }
  21.  
  22. STATIC LONG __saveds __asm
  23. xem_squery(VOID)
  24. {
  25.     if(WriteRequest)
  26.     {
  27.         ULONG    Waiting;
  28.         UWORD    Status;
  29.  
  30.         GetSerialInfo(&Waiting,&Status);
  31.  
  32.             /* Return error if carrier is lost. */
  33.  
  34.         if((Status & CIAF_COMCD) && Config->SerialConfig->CheckCarrier && !Config->SerialConfig->DirectConnection)
  35.             SetOnlineState(FALSE);
  36.         else
  37.             return((LONG)Waiting);
  38.     }
  39.  
  40.     return(-1);
  41. }
  42.  
  43. STATIC LONG __saveds __asm
  44. xem_sread(REG(a0) APTR Buffer,REG(d0) LONG Size,REG(d1) ULONG Timeout)
  45. {
  46.     DB(kprintf("xem_sread(0x%08lx,%ld,%ld)\n",Buffer,Size,Timeout));
  47.  
  48.         /* Are both IORequests available? */
  49.  
  50.     if(WriteRequest && ReadRequest)
  51.     {
  52.             /* Valid size parameter? */
  53.  
  54.         if(Size > 0)
  55.         {
  56.             ULONG    Waiting;
  57.             UWORD    Status;
  58.  
  59.             GetSerialInfo(&Waiting,&Status);
  60.  
  61.                 /* Return error if carrier is lost. */
  62.  
  63.             if(Config->SerialConfig->CheckCarrier && !Config->SerialConfig->DirectConnection)
  64.             {
  65.                 if(Status & CIAF_COMCD)
  66.                 {
  67.                     SetOnlineState(FALSE);
  68.  
  69.                     TransferError = TRUE;
  70.  
  71.                     return(-1);
  72.                 }
  73.             }
  74.  
  75.             /* ALWAYS */
  76.             {
  77.                 if(Waiting)
  78.                 {
  79.                         /* No timeout specified? Read as many
  80.                          * bytes as available.
  81.                          */
  82.  
  83.                     if(!Timeout)
  84.                     {
  85.                         if(Waiting > Size)
  86.                             Waiting = Size;
  87.  
  88.                         if(DoSerialRead(Buffer,Waiting))
  89.                             Waiting = ReadRequest->IOSer.io_Actual;
  90.  
  91.                         BytesIn += Waiting;
  92.  
  93.                         return((LONG)Waiting);
  94.                     }
  95.  
  96.                         /* Enough data pending to be read? */
  97.  
  98.                     if(Waiting >= Size)
  99.                     {
  100.                         if(DoSerialRead(Buffer,Size))
  101.                             Size = ReadRequest->IOSer.io_Actual;
  102.  
  103.                         BytesIn += Size;
  104.  
  105.                         return(Size);
  106.                     }
  107.                 }
  108.                 else
  109.                 {
  110.                         /* No timeout & no bytes available:
  111.                          * return immediately.
  112.                          */
  113.  
  114.                     if(!Timeout)
  115.                         return(0);
  116.                 }
  117.             }
  118.  
  119.             /* ALWAYS */
  120.             {
  121.                 register ULONG    SignalSet,
  122.                                 SerialMask = PORTMASK(ReadPort);
  123.  
  124.                     /* Set up the timer. */
  125.  
  126.                 StartTime(Timeout / MILLION,Timeout % MILLION);
  127.  
  128.                     /* Set up the read request. */
  129.  
  130.                 StartSerialRead(Buffer,Size);
  131.  
  132.                 FOREVER
  133.                 {
  134.                     SignalSet = Wait(SerialMask | SIG_TIMER);
  135.  
  136.                         /* Receive buffer filled? */
  137.  
  138.                     if(SignalSet & SerialMask)
  139.                     {
  140.                             /* Abort the timer request. */
  141.  
  142.                         StopTime();
  143.  
  144.                             /* Did the request terminate gracefully? */
  145.  
  146.                         if(WaitSerialRead())
  147.                             Size = ReadRequest->IOSer.io_Actual;
  148.  
  149.                         BytesIn += Size;
  150.  
  151.                         return(Size);
  152.                     }
  153.  
  154.                         /* Hit by timeout? */
  155.  
  156.                     if(SignalSet & SIG_TIMER)
  157.                     {
  158.                             /* Abort the read request. */
  159.  
  160.                         StopSerialRead();
  161.  
  162.                             /* Remove the timer request. */
  163.  
  164.                         WaitTime();
  165.  
  166.                             /* Did the driver receive any
  167.                              * data?
  168.                              */
  169.  
  170.                         if(ReadRequest->IOSer.io_Actual)
  171.                         {
  172.                             BytesIn += ReadRequest->IOSer.io_Actual;
  173.  
  174.                             return((LONG)ReadRequest->IOSer.io_Actual);
  175.                         }
  176.                         else
  177.                         {
  178.                                 /* Take a second look and query the number of
  179.                                  * bytes ready to be received, there may
  180.                                  * still be some bytes in the buffer.
  181.                                  * Note: this depends on the way the
  182.                                  * driver handles read abort.
  183.                                  */
  184.  
  185.                             Waiting = GetSerialWaiting();
  186.  
  187.                                 /* Don't read too much. */
  188.  
  189.                             if(Size > Waiting)
  190.                                 Size = Waiting;
  191.  
  192.                                 /* Are there any bytes to be transferred? */
  193.  
  194.                             if(Size)
  195.                             {
  196.                                     /* Read the data. */
  197.  
  198.                                 if(DoSerialRead(Buffer,Size))
  199.                                     Size = ReadRequest->IOSer.io_Actual;
  200.  
  201.                                 BytesIn += Size;
  202.                             }
  203.  
  204.                             return(Size);
  205.                         }
  206.                     }
  207.                 }
  208.             }
  209.         }
  210.         else
  211.             return(0);
  212.     }
  213.     else
  214.         return(-1);
  215. }
  216.  
  217. STATIC ULONG __saveds __asm
  218. xem_toptions(REG(d0) LONG NumOpts,REG(a0) struct xem_option **Opts)
  219. {
  220.     if(NumOpts && Opts)
  221.     {
  222.         enum    {    GAD_USE=1,GAD_CANCEL,GAD_SPECIAL };
  223.  
  224.         LayoutHandle    *Handle;
  225.         ULONG             Flags = NULL;
  226.  
  227.             /* We only have 32 bits! */
  228.  
  229.         if(NumOpts > 32)
  230.             NumOpts = 32;
  231.  
  232.         if(Handle = LT_CreateHandleTags(Window->WScreen,
  233.             LH_LocaleHook,    &LocaleHook,
  234.         TAG_DONE))
  235.         {
  236.             struct Window    *PanelWindow;
  237.             LONG             i,Split;
  238.  
  239.             if(NumOpts > 16)
  240.                 Split = NumOpts / 2;
  241.             else
  242.                 Split = -1;
  243.  
  244.             LT_New(Handle,
  245.                 LA_Type,VERTICAL_KIND,
  246.             TAG_DONE);
  247.             {
  248.                 LT_New(Handle,
  249.                     LA_Type,HORIZONTAL_KIND,
  250.                 TAG_DONE);
  251.                 {
  252.                     LT_New(Handle,
  253.                         LA_Type,VERTICAL_KIND,
  254.                     TAG_DONE);
  255.                     {
  256.                         for(i = 0 ; i < NumOpts ; i++)
  257.                         {
  258.                             if(Opts[i])
  259.                             {
  260.                                 switch(Opts[i]->xemo_type)
  261.                                 {
  262.                                     case XEMO_BOOLEAN:
  263.  
  264.                                         LT_New(Handle,
  265.                                             LA_Type,        CHECKBOX_KIND,
  266.                                             LA_LabelText,    Opts[i]->xemo_description,
  267.                                             LA_ID,            GAD_SPECIAL + i,
  268.                                             GTCB_Checked,    String2Boolean(Opts[i]->xemo_value),
  269.                                         TAG_DONE);
  270.  
  271.                                         break;
  272.  
  273.                                     case XEMO_LONG:
  274.  
  275.                                         LT_New(Handle,
  276.                                             LA_Type,                INTEGER_KIND,
  277.                                             LA_LabelText,            Opts[i]->xemo_description,
  278.                                             LA_ID,                    GAD_SPECIAL + i,
  279.                                             LA_Chars,                15,
  280.                                             GTIN_Number,            Atol(Opts[i]->xemo_value),
  281.                                             LAIN_UseIncrementers,    TRUE,
  282.                                         TAG_DONE);
  283.  
  284.                                         break;
  285.  
  286.                                     case XEMO_STRING:
  287.  
  288.                                         LT_New(Handle,
  289.                                             LA_Type,        STRING_KIND,
  290.                                             LA_LabelText,    Opts[i]->xemo_description,
  291.                                             LA_ID,            GAD_SPECIAL + i,
  292.                                             LA_Chars,        15,
  293.                                             GTST_String,    Opts[i]->xemo_value,
  294.                                             GTST_MaxChars,    Opts[i]->xemo_length - 1,
  295.                                         TAG_DONE);
  296.  
  297.                                         break;
  298.  
  299.                                     case XEMO_COMMPAR:
  300.  
  301.                                         LT_New(Handle,
  302.                                             LA_Type,        STRING_KIND,
  303.                                             LA_LabelText,    Opts[i]->xemo_description,
  304.                                             LA_ID,            GAD_SPECIAL + i,
  305.                                             LA_Chars,        15,
  306.                                             LA_HighLabel,    TRUE,
  307.                                             GTST_String,    Opts[i]->xemo_value,
  308.                                             GTST_MaxChars,    Opts[i]->xemo_length - 1,
  309.                                         TAG_DONE);
  310.  
  311.                                         break;
  312.  
  313.                                     case XEMO_HEADER:
  314.  
  315.                                         LT_New(Handle,
  316.                                             LA_Type,        TEXT_KIND,
  317.                                             LA_LabelText,    Opts[i]->xemo_description,
  318.                                             LA_HighLabel,    TRUE,
  319.                                             GTTX_Text,        " ",
  320.                                         TAG_DONE);
  321.  
  322.                                         break;
  323.  
  324.                                     case XEMO_COMMAND:
  325.  
  326.                                         LT_New(Handle,
  327.                                             LA_Type,        BUTTON_KIND,
  328.                                             LA_LabelText,    Opts[i]->xemo_description,
  329.                                             LA_ID,            GAD_SPECIAL + i,
  330.                                             LA_Chars,        15,
  331.                                         TAG_DONE);
  332.  
  333.                                         break;
  334.                                 }
  335.                             }
  336.  
  337.                             if(i == Split)
  338.                             {
  339.                                 LT_EndGroup(Handle);
  340.  
  341.                                 LT_New(Handle,
  342.                                     LA_Type,VERTICAL_KIND,
  343.                                 TAG_DONE);
  344.                                 {
  345.                                     LT_New(Handle,
  346.                                         LA_Type,YBAR_KIND,
  347.                                     TAG_DONE);
  348.  
  349.                                     LT_EndGroup(Handle);
  350.                                 }
  351.  
  352.                                 LT_New(Handle,
  353.                                     LA_Type,VERTICAL_KIND,
  354.                                 TAG_DONE);
  355.                             }
  356.                         }
  357.  
  358.                         LT_EndGroup(Handle);
  359.                     }
  360.  
  361.                     LT_EndGroup(Handle);
  362.                 }
  363.  
  364.                 LT_New(Handle,
  365.                     LA_Type,VERTICAL_KIND,
  366.                 TAG_DONE);
  367.                 {
  368.                     LT_New(Handle,
  369.                         LA_Type,        XBAR_KIND,
  370.                         LAXB_FullSize,    TRUE,
  371.                     TAG_DONE);
  372.  
  373.                     LT_EndGroup(Handle);
  374.                 }
  375.  
  376.                 LT_New(Handle,LA_Type,HORIZONTAL_KIND,
  377.                     LAGR_SameSize,    TRUE,
  378.                     LAGR_Spread,    TRUE,
  379.                 TAG_DONE);
  380.                 {
  381.                     LT_New(Handle,
  382.                         LA_Type,        BUTTON_KIND,
  383.                         LA_LabelID,        MSG_GLOBAL_USE_GAD,
  384.                         LA_ID,            GAD_USE,
  385.                         LABT_ReturnKey,    TRUE,
  386.                         LABT_ExtraFat,    TRUE,
  387.                     TAG_DONE);
  388.  
  389.                     LT_New(Handle,
  390.                         LA_Type,        BUTTON_KIND,
  391.                         LA_LabelID,        MSG_GLOBAL_CANCEL_GAD,
  392.                         LA_ID,            GAD_CANCEL,
  393.                         LABT_EscKey,    TRUE,
  394.                         LABT_ExtraFat,    TRUE,
  395.                     TAG_DONE);
  396.  
  397.                     LT_EndGroup(Handle);
  398.                 }
  399.  
  400.                 LT_EndGroup(Handle);
  401.             }
  402.  
  403.             if(PanelWindow = LT_Build(Handle,
  404.                 LAWN_TitleText,        OptionTitle ? OptionTitle : LocaleString(MSG_V36_1840),
  405.                 LAWN_IDCMP,            IDCMP_CLOSEWINDOW,
  406.                 LAWN_HelpHook,        &GuideHook,
  407.                 LAWN_Parent,        Window,
  408.                 WA_DepthGadget,        TRUE,
  409.                 WA_CloseGadget,        TRUE,
  410.                 WA_DragBar,            TRUE,
  411.                 WA_RMBTrap,            TRUE,
  412.                 WA_Activate,        TRUE,
  413.                 WA_SimpleRefresh,    TRUE,
  414.             TAG_DONE))
  415.             {
  416.                 struct IntuiMessage    *Message;
  417.                 BOOL                 Done = FALSE;
  418.                 ULONG                 MsgClass;
  419.                 UWORD                 MsgCode;
  420.                 struct Gadget        *MsgGadget;
  421.                 BOOL                 CheckFlags = FALSE;
  422.  
  423.                 PushWindow(PanelWindow);
  424.  
  425.                 LT_ShowWindow(Handle,TRUE);
  426.  
  427.                 do
  428.                 {
  429.                     if(Wait(PORTMASK(PanelWindow->UserPort) | SIG_BREAK) & SIG_BREAK)
  430.                         break;
  431.  
  432.                     while(Message = (struct IntuiMessage *)LT_GetIMsg(Handle))
  433.                     {
  434.                         MsgClass    = Message->Class;
  435.                         MsgCode        = Message->Code;
  436.                         MsgGadget    = (struct Gadget *)Message->IAddress;
  437.  
  438.                         LT_ReplyIMsg(Message);
  439.  
  440.                         if(MsgClass == IDCMP_CLOSEWINDOW)
  441.                             Done = TRUE;
  442.  
  443.                         if(MsgClass == IDCMP_GADGETUP)
  444.                         {
  445.                             switch(MsgGadget->GadgetID)
  446.                             {
  447.                                 case GAD_USE:
  448.  
  449.                                     LT_UpdateStrings(Handle);
  450.  
  451.                                     Done = CheckFlags = TRUE;
  452.                                     break;
  453.  
  454.                                 case GAD_CANCEL:
  455.  
  456.                                     Done = TRUE;
  457.                                     break;
  458.  
  459.                                 default:
  460.  
  461.                                     if(MsgGadget->GadgetID - GAD_SPECIAL < NumOpts)
  462.                                     {
  463.                                         i = MsgGadget->GadgetID - GAD_SPECIAL;
  464.  
  465.                                         if(Opts[i]->xemo_type == XEMO_COMMAND || (Opts[i]->xemo_type == XEMO_COMMPAR && MsgCode != '\t'))
  466.                                         {
  467.                                             Flags = (1L << i);
  468.  
  469.                                             Done = CheckFlags = TRUE;
  470.                                         }
  471.                                     }
  472.  
  473.                                     break;
  474.                             }
  475.                         }
  476.                     }
  477.                 }
  478.                 while(!Done);
  479.  
  480.                 PopWindow();
  481.  
  482.                 if(CheckFlags)
  483.                 {
  484.                     STRPTR String;
  485.  
  486.                     LT_LockWindow(PanelWindow);
  487.  
  488.                     for(i = 0 ; i < NumOpts ; i++)
  489.                     {
  490.                         if(Opts[i])
  491.                         {
  492.                             switch(Opts[i]->xemo_type)
  493.                             {
  494.                                 case XEMO_BOOLEAN:
  495.  
  496.                                     if(LT_GetAttributes(Handle,GAD_SPECIAL + i,TAG_DONE) != String2Boolean(Opts[i]->xemo_value))
  497.                                     {
  498.                                         Flags |= (1L << i);
  499.  
  500.                                         if(LT_GetAttributes(Handle,GAD_SPECIAL + i,TAG_DONE))
  501.                                             strcpy(Opts[i]->xemo_value,"yes");
  502.                                         else
  503.                                             strcpy(Opts[i]->xemo_value,"no");
  504.  
  505.                                         NewOptions = TRUE;
  506.                                     }
  507.  
  508.                                     break;
  509.  
  510.                                 case XEMO_LONG:
  511.  
  512.                                     if(Atol(Opts[i]->xemo_value) != LT_GetAttributes(Handle,GAD_SPECIAL + i,TAG_DONE))
  513.                                     {
  514.                                         Flags |= (1L << i);
  515.  
  516.                                         SPrintf(Opts[i]->xemo_value,"%ld",LT_GetAttributes(Handle,GAD_SPECIAL + i,TAG_DONE));
  517.  
  518.                                         NewOptions = TRUE;
  519.                                     }
  520.  
  521.                                     break;
  522.  
  523.                                 case XEMO_COMMPAR:
  524.                                 case XEMO_STRING:
  525.  
  526.                                     if(String = (STRPTR)LT_GetAttributes(Handle,GAD_SPECIAL + i,TAG_DONE))
  527.                                     {
  528.                                         if(strcmp(Opts[i]->xemo_value,String))
  529.                                         {
  530.                                             Flags |= (1L << i);
  531.  
  532.                                             strcpy(Opts[i]->xemo_value,(STRPTR)LT_GetAttributes(Handle,GAD_SPECIAL + i,TAG_DONE));
  533.  
  534.                                             NewOptions = TRUE;
  535.                                         }
  536.                                     }
  537.  
  538.                                     break;
  539.                             }
  540.                         }
  541.                     }
  542.  
  543.                     LT_UnlockWindow(PanelWindow);
  544.                 }
  545.                 else
  546.                     Flags = NULL;
  547.             }
  548.  
  549.             LT_DeleteHandle(Handle);
  550.         }
  551.  
  552.         return(Flags);
  553.     }
  554.     else
  555.         return(NULL);
  556. }
  557.  
  558.     /* xem_swrite():
  559.      *
  560.      *    Send a few bytes across the serial line.
  561.      */
  562.  
  563. STATIC LONG __saveds __asm
  564. xem_swrite(REG(a0) STRPTR Buffer,REG(d0) LONG Size)
  565. {
  566.     if(WriteRequest)
  567.     {
  568.         SerWrite(Buffer,Size);
  569.  
  570.         return(0);
  571.     }
  572.     else
  573.         return(-1);
  574. }
  575.  
  576.     /* xem_sbreak():
  577.      *
  578.      *    Send a break signal across the serial line.
  579.      */
  580.  
  581. STATIC LONG __saveds __asm
  582. xem_sbreak(VOID)
  583. {
  584.     if(!WriteRequest)
  585.         return(-1);
  586.     else
  587.     {
  588.         SendBreak();
  589.  
  590.         return(0);
  591.     }
  592. }
  593.  
  594.     /* xem_sstart():
  595.      *
  596.      *    Restart serial read activity.
  597.      */
  598.  
  599. STATIC VOID __saveds __asm
  600. xem_sstart(VOID)
  601. {
  602.     RestartSerial();
  603. }
  604.  
  605.     /* xem_sstop():
  606.      *
  607.      *    Stop serial read activity.
  608.      */
  609.  
  610. STATIC LONG __saveds __asm
  611. xem_sstop(VOID)
  612. {
  613.     StopSerialRead();
  614.  
  615.     return(0);
  616. }
  617.  
  618.     /* xem_tgets(STRPTR Prompt,STRPTR Buffer,ULONG Size):
  619.      *
  620.      *    Get a string from the user.
  621.      */
  622.  
  623. STATIC LONG __saveds __asm
  624. xem_tgets(REG(a0) STRPTR Prompt,REG(a1) STRPTR Buffer,REG(d0) ULONG Size)
  625. {
  626.     enum    {    GAD_OK=1,GAD_CANCEL,GAD_STRING };
  627.  
  628.     LayoutHandle    *Handle;
  629.     LONG             Success = FALSE;
  630.     UBYTE             LocalBuffer[256];
  631.  
  632.     if(strlen(Buffer) > 255)
  633.     {
  634.         CopyMem(Buffer,LocalBuffer,255);
  635.  
  636.         LocalBuffer[255] = 0;
  637.     }
  638.     else
  639.         strcpy(LocalBuffer,Buffer);
  640.  
  641.     if(!Prompt)
  642.         Prompt = LocaleString(MSG_TERMXPR_INPUT_REQUIRED_TXT);
  643.  
  644.     if(Handle = LT_CreateHandleTags(Window->WScreen,
  645.         LH_LocaleHook,    &LocaleHook,
  646.     TAG_DONE))
  647.     {
  648.         struct Window *PanelWindow;
  649.  
  650.         LT_New(Handle,
  651.             LA_Type,VERTICAL_KIND,
  652.         TAG_DONE);
  653.         {
  654.             LT_New(Handle,
  655.                 LA_Type,        VERTICAL_KIND,
  656.                 LA_LabelText,    Prompt,
  657.             TAG_DONE);
  658.             {
  659.                 LT_New(Handle,
  660.                     LA_Type,        STRING_KIND,
  661.                     LA_STRPTR,        LocalBuffer,
  662.                     LA_Chars,        30,
  663.                     GTST_MaxChars,    Size,
  664.                 TAG_DONE);
  665.  
  666.                 LT_EndGroup(Handle);
  667.             }
  668.  
  669.             LT_New(Handle,
  670.                 LA_Type,VERTICAL_KIND,
  671.             TAG_DONE);
  672.             {
  673.                 LT_New(Handle,
  674.                     LA_Type,        XBAR_KIND,
  675.                     LAXB_FullSize,    TRUE,
  676.                 TAG_DONE);
  677.  
  678.                 LT_EndGroup(Handle);
  679.             }
  680.  
  681.             LT_New(Handle,LA_Type,HORIZONTAL_KIND,
  682.                 LAGR_SameSize,    TRUE,
  683.                 LAGR_Spread,    TRUE,
  684.             TAG_DONE);
  685.             {
  686.                 LT_New(Handle,
  687.                     LA_Type,        BUTTON_KIND,
  688.                     LA_LabelID,        MSG_TERMXPR_OKAY_GAD,
  689.                     LA_ID,            GAD_OK,
  690.                     LABT_ReturnKey,    TRUE,
  691.                     LABT_ExtraFat,    TRUE,
  692.                 TAG_DONE);
  693.  
  694.                 LT_New(Handle,
  695.                     LA_Type,        BUTTON_KIND,
  696.                     LA_LabelID,        MSG_GLOBAL_CANCEL_GAD,
  697.                     LA_ID,            GAD_CANCEL,
  698.                     LABT_EscKey,    TRUE,
  699.                     LABT_ExtraFat,    TRUE,
  700.                 TAG_DONE);
  701.  
  702.                 LT_EndGroup(Handle);
  703.             }
  704.         }
  705.  
  706.         if(PanelWindow = LT_Build(Handle,
  707.             LAWN_TitleID,        MSG_GLOBAL_ENTER_TEXT_TXT,
  708.             LAWN_IDCMP,            IDCMP_CLOSEWINDOW,
  709.             LAWN_HelpHook,        &GuideHook,
  710.             LAWN_Parent,        Window,
  711.             WA_DepthGadget,        TRUE,
  712.             WA_CloseGadget,        TRUE,
  713.             WA_DragBar,            TRUE,
  714.             WA_RMBTrap,            TRUE,
  715.             WA_Activate,        TRUE,
  716.             WA_SimpleRefresh,    TRUE,
  717.         TAG_DONE))
  718.         {
  719.             struct IntuiMessage    *Message;
  720.             BOOL                 Done = FALSE;
  721.             ULONG                 MsgClass;
  722.             UWORD                 MsgCode;
  723.             struct Gadget        *MsgGadget;
  724.  
  725.             PushWindow(PanelWindow);
  726.  
  727.             LT_ShowWindow(Handle,TRUE);
  728.  
  729.             LT_Activate(Handle,GAD_STRING);
  730.  
  731.             do
  732.             {
  733.                 if(Wait(PORTMASK(PanelWindow->UserPort) | SIG_BREAK) & SIG_BREAK)
  734.                     break;
  735.  
  736.                 while(Message = (struct IntuiMessage *)LT_GetIMsg(Handle))
  737.                 {
  738.                     MsgClass    = Message->Class;
  739.                     MsgCode        = Message->Code;
  740.                     MsgGadget    = (struct Gadget *)Message->IAddress;
  741.  
  742.                     LT_ReplyIMsg(Message);
  743.  
  744.                     if(MsgClass == IDCMP_CLOSEWINDOW)
  745.                         Done = TRUE;
  746.  
  747.                     if(MsgClass == IDCMP_GADGETUP)
  748.                     {
  749.                         switch(MsgGadget->GadgetID)
  750.                         {
  751.                             case GAD_STRING:
  752.  
  753.                                 if(MsgCode == '\r')
  754.                                 {
  755.                                     strcpy(Buffer,LocalBuffer);
  756.  
  757.                                     Success = Done = TRUE;
  758.  
  759.                                     LT_PressButton(Handle,GAD_OK);
  760.                                 }
  761.  
  762.                                 break;
  763.  
  764.                             case GAD_OK:
  765.  
  766.                                 strcpy(Buffer,LocalBuffer);
  767.  
  768.                                 Success = Done = TRUE;
  769.                                 break;
  770.  
  771.                             case GAD_CANCEL:
  772.  
  773.                                 Done = TRUE;
  774.                                 break;
  775.                         }
  776.                     }
  777.                 }
  778.             }
  779.             while(!Done);
  780.  
  781.             PopWindow();
  782.         }
  783.  
  784.         LT_DeleteHandle(Handle);
  785.     }
  786.  
  787.     return(Success);
  788. }
  789.  
  790.     /* xem_tbeep(ULONG Times,ULONG Delay):
  791.      *
  792.      *    Beep the terminal display.
  793.      */
  794.  
  795. STATIC VOID __saveds __asm
  796. xem_tbeep(REG(d0) ULONG Times,REG(d1) ULONG Delay)
  797. {
  798.     LONG i;
  799.  
  800.     for(i = 0 ; i < Times ; i++)
  801.     {
  802.             /* Handle the visual part. */
  803.  
  804.         if(Config->TerminalConfig->BellMode != BELL_AUDIBLE)
  805.         {
  806.             if(StatusProcess)
  807.                 Signal(StatusProcess,SIG_BELL);
  808.         }
  809.  
  810.             /* Let it beep. */
  811.  
  812.         if(Config->TerminalConfig->BellMode == BELL_AUDIBLE || Config->TerminalConfig->BellMode == BELL_BOTH)
  813.             SoundPlay(SOUND_BELL);
  814.     }
  815. }
  816.  
  817.     /* xem_macrodispatch(struct XEmulatorMacroKey *XEM_MacroKey):
  818.      *
  819.      *    Dispatch a macro key call.
  820.      */
  821.  
  822. STATIC LONG __saveds __asm
  823. xem_macrodispatch(REG(a0) struct XEmulatorMacroKey *XEM_MacroKey)
  824. {
  825.     VOID (*Routine)(VOID);
  826.  
  827.         /* If a routine to call is available (most likely xON or xOFF),
  828.          * make a call to it, else process the macro key data.
  829.          */
  830.  
  831.     if(Routine = (VPTR)XEM_MacroKey->xmk_UserData)
  832.         (*Routine)();
  833.     else
  834.         SerialCommand(MacroKeys->Keys[XEM_MacroKey->xmk_Qualifier][XEM_MacroKey->xmk_Code - 0x50]);
  835.  
  836.     return(0);
  837. }
  838.  
  839.     /* SetEmulatorOptions(BYTE Mode):
  840.      *
  841.      *    Save or load the emulator options.
  842.      */
  843.  
  844. BOOL
  845. SetEmulatorOptions(LONG Mode)
  846. {
  847.     BOOL Success = FALSE;
  848.  
  849.         /* Is the library available and running? */
  850.  
  851.     if(XEmulatorBase && XEM_IO)
  852.     {
  853.             /* Are we using the new library code? */
  854.  
  855.         if(XEmulatorBase->lib_Version >= 4)
  856.         {
  857.                 /* Get the name of the library. */
  858.  
  859.             strcpy(SharedBuffer,FilePart(XEmulatorBase->lib_Node.ln_Name));
  860.  
  861.                 /* Does it have any name? */
  862.  
  863.             if(SharedBuffer[0])
  864.             {
  865.                 UBYTE    OtherBuffer[50];
  866.                 LONG    i;
  867.  
  868.                     /* Strip the `.library' bit. */
  869.  
  870.                 for(i = strlen(SharedBuffer) - 1 ; i >= 0 ; i--)
  871.                 {
  872.                     if(SharedBuffer[i] == '.')
  873.                     {
  874.                         SharedBuffer[i] = 0;
  875.  
  876.                         break;
  877.                     }
  878.                 }
  879.  
  880.                     /* What are we to do? */
  881.  
  882.                 if(Mode == XEM_PREFS_LOAD)
  883.                 {
  884.                         /* Restore settings... */
  885.  
  886.                     strcpy(OtherBuffer,"ENV:");
  887.  
  888.                     if(AddPart(OtherBuffer,SharedBuffer,50))
  889.                     {
  890.                             /* If we can't load them,
  891.                              * reset to defaults.
  892.                              */
  893.  
  894.                         if(!XEmulatorPreferences(XEM_IO,OtherBuffer,Mode))
  895.                         {
  896.                             strcpy(OtherBuffer,"ENV:xem");
  897.  
  898.                             if(AddPart(OtherBuffer,SharedBuffer,50))
  899.                             {
  900.                                 if(XEmulatorPreferences(XEM_IO,OtherBuffer,Mode))
  901.                                     Success = TRUE;
  902.                             }
  903.                         }
  904.                         else
  905.                             Success = TRUE;
  906.  
  907.                         if(!Success)
  908.                             XEmulatorPreferences(XEM_IO,NULL,XEM_PREFS_RESET);
  909.                     }
  910.                 }
  911.                 else
  912.                 {
  913.                         /* Save settings to ENV: */
  914.  
  915.                     strcpy(OtherBuffer,"ENV:");
  916.  
  917.                     if(AddPart(OtherBuffer,SharedBuffer,50))
  918.                     {
  919.                         if(XEmulatorPreferences(XEM_IO,OtherBuffer,Mode))
  920.                             Success = TRUE;
  921.                     }
  922.  
  923.                     if(Success)
  924.                     {
  925.                         Success = FALSE;
  926.  
  927.                             /* Save settings to ENVARC: */
  928.  
  929.                         strcpy(OtherBuffer,"ENVARC:");
  930.  
  931.                         if(AddPart(OtherBuffer,SharedBuffer,50))
  932.                         {
  933.                             if(XEmulatorPreferences(XEM_IO,OtherBuffer,Mode))
  934.                                 Success = TRUE;
  935.                         }
  936.                     }
  937.                 }
  938.             }
  939.         }
  940.     }
  941.  
  942.         /* Return result. */
  943.  
  944.     return(Success);
  945. }
  946.  
  947.     /* SetupEmulator(BOOL OpenConsole):
  948.      *
  949.      *    Initialize the XEM_IO structure.
  950.      */
  951.  
  952. STATIC BOOL
  953. SetupEmulator(VOID)
  954. {
  955.     if(!XEM_IO)
  956.     {
  957.         if(XEM_IO = (struct XEM_IO *)AllocVec(sizeof(struct XEM_IO),MEMF_ANY | MEMF_CLEAR | MEMF_PUBLIC))
  958.         {
  959.             XEM_IO->xem_window                = Window;
  960.             XEM_IO->xem_font                = CurrentFont;
  961.             XEM_IO->xem_signal                = &XEM_Signal;
  962.             XEM_IO->xem_screendepth            = GetBitMapDepth(Window->WScreen->RastPort.BitMap);
  963.  
  964.             XEM_IO->xem_sread                = xem_sread;
  965.             XEM_IO->xem_swrite                = xem_swrite;
  966.             XEM_IO->xem_sflush                = xem_sflush;
  967.             XEM_IO->xem_sbreak                = xem_sbreak;
  968.             XEM_IO->xem_squery                = xem_squery;
  969.             XEM_IO->xem_sstart                = xem_sstart;
  970.             XEM_IO->xem_sstop                = xem_sstop;
  971.  
  972.             XEM_IO->xem_tbeep                = xem_tbeep;
  973.             XEM_IO->xem_tgets                = xem_tgets;
  974.             XEM_IO->xem_toptions            = xem_toptions;
  975.  
  976.             XEM_IO->xem_process_macrokeys    = xem_macrodispatch;
  977.  
  978.             return(TRUE);
  979.         }
  980.     }
  981.  
  982.     return(FALSE);
  983. }
  984.  
  985.     /* CloseEmulator():
  986.      *
  987.      *    Close the emulation library.
  988.      */
  989.  
  990. VOID
  991. CloseEmulator(BOOL Exit)
  992. {
  993.     if(XEmulatorBase)
  994.     {
  995.         if(XEM_IO)
  996.         {
  997.             XEmulatorMacroKeyFilter(XEM_IO,NULL);
  998.             XEmulatorCloseConsole(XEM_IO);
  999.             XEmulatorCleanup(XEM_IO);
  1000.  
  1001.             FreeVec(XEM_IO);
  1002.             XEM_IO = NULL;
  1003.         }
  1004.  
  1005.         CloseLibrary(XEmulatorBase);
  1006.         XEmulatorBase = NULL;
  1007.  
  1008.         if(!Exit)
  1009.         {
  1010.             XEM_Signal = NULL;
  1011.  
  1012.             strcpy(EmulationName,LocaleString(MSG_TERMXEM_NO_EMULATION_TXT));
  1013.  
  1014.             RasterEnabled = TRUE;
  1015.  
  1016.             ClearCursor();
  1017.  
  1018.             Reset();
  1019.  
  1020.             DrawCursor();
  1021.         }
  1022.     }
  1023. }
  1024.  
  1025.     /* OpenEmulator(STRPTR Name):
  1026.      *
  1027.      *    Open an emulation library.
  1028.      */
  1029.  
  1030. BOOL
  1031. OpenEmulator(STRPTR Name)
  1032. {
  1033.     CloseEmulator(FALSE);
  1034.  
  1035.     XEM_HostData.Source            = NULL;
  1036.     XEM_HostData.Destination    = NULL;
  1037.     XEM_HostData.InESC            = FALSE;
  1038.     XEM_HostData.InCSI            = FALSE;
  1039.  
  1040.     if(XEmulatorBase = OpenLibrary(Name,0))
  1041.     {
  1042.         ClearCursor();
  1043.  
  1044.         Reset();
  1045.  
  1046.         if(SetupEmulator())
  1047.         {
  1048.             SetMask(RPort,DepthMask);
  1049.  
  1050.             ClearSerial();
  1051.  
  1052.             if(XEmulatorSetup(XEM_IO))
  1053.             {
  1054.                 RestartSerial();
  1055.  
  1056.                 SetEmulatorOptions(XEM_PREFS_LOAD);
  1057.  
  1058.                 if(XEmulatorOpenConsole(XEM_IO))
  1059.                 {
  1060.                     STRPTR LibName = FilePart(XEmulatorBase->lib_Node.ln_Name);
  1061.  
  1062.                     strcpy(EmulationName,&LibName[3]);
  1063.  
  1064.                     EmulationName[strlen(EmulationName) - 8] = 0;
  1065.  
  1066.                     SetupXEM_MacroKeys(MacroKeys);
  1067.  
  1068.                     return(TRUE);
  1069.                 }
  1070.             }
  1071.             else
  1072.                 RestartSerial();
  1073.         }
  1074.  
  1075.         DrawCursor();
  1076.  
  1077.         CloseLibrary(XEmulatorBase);
  1078.  
  1079.         XEmulatorBase = NULL;
  1080.     }
  1081.  
  1082.     XEM_Signal = NULL;
  1083.  
  1084.     strcpy(EmulationName,LocaleString(MSG_TERMXEM_NO_EMULATION_TXT));
  1085.  
  1086.     return(FALSE);
  1087. }
  1088.  
  1089.     /* xOn():
  1090.      *
  1091.      *    Small local routine, complements XOff().
  1092.      */
  1093.  
  1094. STATIC VOID
  1095. xOn(VOID)
  1096. {
  1097.     UBYTE c = XON;
  1098.  
  1099.     if(Config->SerialConfig->xONxOFF)
  1100.         Status = STATUS_HOLDING;
  1101.  
  1102.     if(Config->SerialConfig->PassThrough)
  1103.         SerWrite(&c,1);
  1104. }
  1105.  
  1106.     /* xOff():
  1107.      *
  1108.      *    Small local routine, complements XOn() in Serial.c
  1109.      */
  1110.  
  1111. STATIC VOID
  1112. xOff(VOID)
  1113. {
  1114.     UBYTE c = XOF;
  1115.  
  1116.     if(Status == STATUS_HOLDING)
  1117.         Status = STATUS_READY;
  1118.  
  1119.     if(Config->SerialConfig->PassThrough)
  1120.         SerWrite(&c,1);
  1121. }
  1122.  
  1123.     /* SetupXEM_MacroKeys(struct MacroKeys *Keys):
  1124.      *
  1125.      *    Sets up the internal representation of the macro key
  1126.      *    data to fit the XEM specification.
  1127.      */
  1128.  
  1129. VOID
  1130. SetupXEM_MacroKeys(struct MacroKeys *Keys)
  1131. {
  1132.         /* Are we allowed to do what we want to do? */
  1133.  
  1134.     if(XEM_MacroKeys && XEmulatorBase && Config->TerminalConfig->EmulationMode == EMULATION_EXTERNAL)
  1135.     {
  1136.         LONG i,j,k = 0;
  1137.  
  1138.             /* Clear the macro list. */
  1139.  
  1140.         NewList(&XEM_MacroList);
  1141.  
  1142.             /* Run down the list of qualifiers. */
  1143.  
  1144.         for(i = XMKQ_NONE ; i <= XMKQ_CONTROL ; i++)
  1145.         {
  1146.                 /* Run down the function keys. */
  1147.  
  1148.             for(j = 0 ; j < 10 ; j++)
  1149.             {
  1150.                     /* If the key has no data attached,
  1151.                      * don't use it in the list.
  1152.                      */
  1153.  
  1154.                 if(Keys->Keys[i][j][0])
  1155.                 {
  1156.                     XEM_MacroKeys[k].xmk_Type        = XMKT_RAWKEY;
  1157.                     XEM_MacroKeys[k].xmk_Qualifier    = i;
  1158.                     XEM_MacroKeys[k].xmk_Code        = 0x50 + j;
  1159.                     XEM_MacroKeys[k].xmk_UserData    = NULL;
  1160.  
  1161.                     AddTail(&XEM_MacroList,(struct Node *)&XEM_MacroKeys[k++]);
  1162.                 }
  1163.             }
  1164.         }
  1165.  
  1166.             /* Take care of the rest, add support for the xON key. */
  1167.  
  1168.         XEM_MacroKeys[k].xmk_Type         = XMKT_COOKED;
  1169.         XEM_MacroKeys[k].xmk_Qualifier    = NULL;
  1170.         XEM_MacroKeys[k].xmk_Code        = XON;
  1171.         XEM_MacroKeys[k].xmk_UserData    = (APTR)xOn;
  1172.  
  1173.         AddTail(&XEM_MacroList,(struct Node *)&XEM_MacroKeys[k++]);
  1174.  
  1175.             /* Take care of the xOFF key. */
  1176.  
  1177.         XEM_MacroKeys[k].xmk_Type         = XMKT_COOKED;
  1178.         XEM_MacroKeys[k].xmk_Qualifier    = NULL;
  1179.         XEM_MacroKeys[k].xmk_Code        = XOF;
  1180.         XEM_MacroKeys[k].xmk_UserData    = (APTR)xOff;
  1181.  
  1182.         AddTail(&XEM_MacroList,(struct Node *)&XEM_MacroKeys[k]);
  1183.  
  1184.             /* Make the emulator notice the new settings. */
  1185.  
  1186.         XEmulatorMacroKeyFilter(XEM_IO,&XEM_MacroList);
  1187.     }
  1188. }
  1189.