home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / comms / comprgs / term232.lha / Source_Code / termSource / termPacket.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-18  |  23.3 KB  |  1,050 lines

  1. /*
  2. **    $Id: termPacket.c,v 1.4 92/08/18 16:12:47 olsen Sta Locker: olsen $
  3. **    $Revision: 1.4 $
  4. **    $Date: 92/08/18 16:12:47 $
  5. **
  6. **    Support routines for the `packet window'
  7. **
  8. **    Copyright ⌐ 1990-1992 by Olaf `Olsen' Barthel & MXM
  9. **        All Rights Reserved
  10. */
  11.  
  12. #include "termGlobal.h"
  13.  
  14.     /* A custom message structure. */
  15.  
  16. struct PacketMessage
  17. {
  18.     struct Message     VanillaMessage;
  19.     LONG         Line;
  20. };
  21.  
  22.     /* Some private data required to handle both the window,
  23.      * the editing functions and the command history buffer.
  24.      */
  25.  
  26. STATIC struct Hook         PacketHook;
  27. STATIC UBYTE             PacketWorkBuffer[256];
  28. STATIC struct StringInfo    *PacketInfo;
  29.  
  30. STATIC struct MsgPort        *PacketPort;
  31.  
  32. STATIC LONG             PacketLine;
  33. STATIC LONG             PacketCount;
  34. STATIC STRPTR             PacketString = NULL;
  35. STATIC LONG             PacketX = -1,PacketY = -1,PacketWidth = -1,PacketHeight = -1;
  36.  
  37. STATIC BYTE             HasList = FALSE;
  38.  
  39.     /* Gadget IDs */
  40.  
  41. enum    {    GAD_STRING, GAD_LIST };
  42.  
  43.     /* The menu to attach to the packet window. */
  44.  
  45. enum    {    MEN_LOADHISTORY=1,MEN_SAVEHISTORY,MEN_CLEARHISTORY,MEN_OTHERWINDOW,MEN_QUITPANEL };
  46.  
  47. STATIC struct NewMenu NewPacketMenu[] =
  48. {
  49.     { NM_TITLE, NULL,         0 , 0, 0, (APTR)0},
  50.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_LOADHISTORY},
  51.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_SAVEHISTORY},
  52.     {  NM_ITEM, NM_BARLABEL,     0 , 0, 0, (APTR)0},
  53.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_CLEARHISTORY},
  54.     {  NM_ITEM, NM_BARLABEL,     0 , 0, 0, (APTR)0},
  55.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_OTHERWINDOW},
  56.     {  NM_ITEM, NM_BARLABEL,     0 , 0, 0, (APTR)0},
  57.     {  NM_ITEM, NULL,         0 , 0, 0, (APTR)MEN_QUITPANEL},
  58.     { NM_END, 0,             0 , 0, 0, (APTR)0}
  59. };
  60.  
  61.     /* SendPacketMsg(LONG Line):
  62.      *
  63.      *    Tell the main process to display a certain line.
  64.      */
  65.  
  66. STATIC VOID __regargs
  67. SendPacketMsg(LONG Line)
  68. {
  69.     struct PacketMessage *Msg;
  70.  
  71.     if(Msg = (struct PacketMessage *)AllocVec(sizeof(struct PacketMessage),MEMF_PUBLIC|MEMF_CLEAR))
  72.     {
  73.         Msg -> VanillaMessage . mn_Length    = sizeof(struct PacketMessage);
  74.         Msg -> Line                = Line;
  75.  
  76.         PutMsg(PacketPort,Msg);
  77.     }
  78. }
  79.  
  80.     /* ClearPacketHistory():
  81.      *
  82.      *    Release the command history.
  83.      */
  84.  
  85. VOID
  86. ClearPacketHistory()
  87. {
  88.     struct Node *SomeNode,*NextNode;
  89.  
  90.     if(HasList)
  91.     {
  92.         GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  93.             GTLV_Labels,    ~0,
  94.         TAG_DONE);
  95.     }
  96.  
  97.     SomeNode = PacketHistoryList . lh_Head;
  98.  
  99.     while(SomeNode -> ln_Succ)
  100.     {
  101.         NextNode = SomeNode -> ln_Succ;
  102.  
  103.         Remove(SomeNode);
  104.  
  105.         FreeVec(SomeNode);
  106.  
  107.         SomeNode = NextNode;
  108.     }
  109.  
  110.     PacketCount = PacketLine = 0;
  111.  
  112.     if(HasList)
  113.     {
  114.         GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  115.             GTLV_Labels,    &PacketHistoryList,
  116.         TAG_DONE);
  117.     }
  118.  
  119.     PacketString = NULL;
  120. }
  121.  
  122.     /* DeletePacketWindow():
  123.      *
  124.      *    Delete the packet window and release the command
  125.      *    history.
  126.      */
  127.  
  128. VOID
  129. DeletePacketWindow(BYTE WindowOnly)
  130. {
  131.     struct MenuItem    *Item;
  132.  
  133.     if(Item = FindThisItem(MEN_PACKET_WINDOW))
  134.         Item -> Flags &= ~CHECKED;
  135.  
  136.     if(PacketWindow)
  137.     {
  138.         PacketWindow -> Flags |= WFLG_RMBTRAP;
  139.  
  140.         ClearMenuStrip(PacketWindow);
  141.  
  142.         if(PacketGadgetList)
  143.             RemoveGList(PacketWindow,PacketGadgetList,(UWORD)-1);
  144.  
  145.         PacketX        = PacketWindow -> LeftEdge;
  146.         PacketY        = PacketWindow -> TopEdge;
  147.  
  148.         PacketWidth    = PacketWindow -> Width;
  149.         PacketHeight    = PacketWindow -> Height;
  150.  
  151.         CloseWindow(PacketWindow);
  152.  
  153.         PacketWindow = NULL;
  154.     }
  155.  
  156.     if(PacketGadgetList)
  157.     {
  158.         FreeGadgets(PacketGadgetList);
  159.  
  160.         PacketGadgetList = NULL;
  161.     }
  162.  
  163.     if(PacketMenu)
  164.     {
  165.         FreeMenus(PacketMenu);
  166.  
  167.         PacketMenu = NULL;
  168.     }
  169.  
  170.     if(PacketPort)
  171.     {
  172.         struct Message *Message;
  173.     
  174.         while(Message = GetMsg(PacketPort))
  175.             FreeVec(Message);
  176.  
  177.         FreeVec(PacketPort);
  178.  
  179.         PacketPort = NULL;
  180.     }
  181.  
  182.     if(!WindowOnly)
  183.     {
  184.         HasList = FALSE;
  185.  
  186.         ClearPacketHistory();
  187.     }
  188. }
  189.  
  190.     /* AddPacketHistory(UBYTE *Buffer):
  191.      *
  192.      *    Add a line to the packet window command history. This
  193.      *    works very much the same as the AddLine()-routine.
  194.      */
  195.  
  196. VOID
  197. AddPacketHistory(UBYTE *Buffer)
  198. {
  199.     struct Node *SomeNode;
  200.  
  201.     if(HasList)
  202.     {
  203.         GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  204.             GTLV_Labels,    ~0,
  205.         TAG_DONE);
  206.     }
  207.  
  208.     if(SomeNode = (struct Node *)AllocVec(sizeof(struct Node) + strlen(Buffer) + 1,MEMF_ANY|MEMF_CLEAR))
  209.     {
  210.         SomeNode -> ln_Name = (UBYTE *)(SomeNode + 1);
  211.  
  212.         strcpy(SomeNode -> ln_Name,Buffer);
  213.  
  214.         AddTail(&PacketHistoryList,SomeNode);
  215.  
  216.         PacketCount = ++PacketLine;
  217.     }
  218.  
  219.     if(HasList)
  220.     {
  221.         GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  222.             GTLV_Top,    PacketCount - 1,
  223.             GTLV_Labels,    &PacketHistoryList,
  224.         TAG_DONE);
  225.     }
  226. }
  227.  
  228.     /* CreateAllGadgets():
  229.      *
  230.      *    Create the packet string gadget.
  231.      */
  232.  
  233. STATIC struct Gadget *
  234. CreateAllGadgets(LONG Width,struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge)
  235. {
  236.     struct Gadget        *Gadget;
  237.     struct NewGadget     NewGadget;
  238.  
  239.     SZ_SizeSetup(Screen,&UserFont,TRUE);
  240.  
  241.     memset(&NewGadget,0,sizeof(struct NewGadget));
  242.  
  243.     if(Gadget = CreateContext(GadgetList))
  244.     {
  245.         WORD Rest,StringHeight,ProtoHeight;
  246.  
  247.         StringHeight    = SZ_Height(STRING_KIND,0,0);
  248.         ProtoHeight    = Screen -> WBorTop + Screen -> Font -> ta_YSize + 1 + 2 + StringHeight + 2;
  249.         Rest        = (PacketHeight - 2 - ProtoHeight - 2) / UserFontHeight;
  250.  
  251.         NewGadget . ng_Width        = Width - 26;
  252.         NewGadget . ng_Height        = StringHeight;
  253.         NewGadget . ng_GadgetText    = NULL;
  254.         NewGadget . ng_TextAttr        = &UserFont;
  255.         NewGadget . ng_VisualInfo    = VisualInfo;
  256.         NewGadget . ng_GadgetID        = GAD_STRING;
  257.         NewGadget . ng_Flags        = 0;
  258.         NewGadget . ng_LeftEdge        = 6;
  259.         NewGadget . ng_TopEdge        = 1 + TopEdge;
  260.  
  261.         GadgetArray[GAD_STRING] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
  262.             GTST_MaxChars,    256,
  263.             GTST_EditHook,    &PacketHook,
  264.             GA_TabCycle,    FALSE,
  265.         TAG_DONE);
  266.  
  267.             /* If the window is large enough to display the
  268.              * list, create the list view gadget.
  269.              */
  270.  
  271.         if(Rest > 0)
  272.         {
  273.             NewGadget . ng_Height        = 2 + Rest * UserFontHeight + 2 + StringHeight;
  274.             NewGadget . ng_GadgetID        = GAD_LIST;
  275.  
  276.             GadgetArray[GAD_LIST] = Gadget = CreateGadget(LISTVIEW_KIND,Gadget,&NewGadget,
  277.                 GTLV_ShowSelected,    GadgetArray[GAD_STRING],
  278.                 GTLV_Labels,        &PacketHistoryList,
  279.                 GTLV_Selected,        PacketCount,
  280.                 GTLV_Top,        PacketCount,
  281.             TAG_DONE);
  282.  
  283.             if(Gadget)
  284.                 HasList = TRUE;
  285.             else
  286.                 HasList = FALSE;
  287.         }
  288.         else
  289.             HasList = FALSE;
  290.     }
  291.  
  292.     return(Gadget);
  293. }
  294.  
  295.     /* CreatePacketWindow():
  296.      *
  297.      *    Open the packet window and allocate the command history
  298.      *    buffer.
  299.      */
  300.  
  301. BYTE
  302. CreatePacketWindow()
  303. {
  304.     LocalizeMenu(NewPacketMenu,MSG_PACKET_PROJECT_MEN);
  305.  
  306.     if(PacketPort = (struct MsgPort *)AllocVec(sizeof(struct MsgPort),MEMF_PUBLIC | MEMF_CLEAR))
  307.     {
  308.         if(PacketMenu = CreateMenus(NewPacketMenu,TAG_DONE))
  309.         {
  310.             if(LayoutMenus(PacketMenu,VisualInfo,
  311.                 GTMN_TextAttr,        &UserFont,
  312.                 GTMN_NewLookMenus,    TRUE,
  313.             TAG_DONE))
  314.             {
  315.                 LONG ProtoHeight;
  316.  
  317.                 SZ_SizeSetup(Screen,&UserFont,TRUE);
  318.  
  319.                 ProtoHeight = Screen -> WBorTop + Screen -> Font -> ta_YSize + 1 + 2 + SZ_Height(STRING_KIND,0,0) + 2;
  320.  
  321.                 if(PacketWidth == -1)
  322.                     PacketWidth = Screen -> Width;
  323.  
  324.                 if(PacketHeight < ProtoHeight)
  325.                     PacketHeight = ProtoHeight;
  326.  
  327.                 if(PacketX == -1 || (PacketX + PacketWidth > Screen -> Width))
  328.                 {
  329.                     PacketX = 0;
  330.  
  331.                     if(PacketX + PacketWidth > Screen -> Width)
  332.                         PacketWidth = Screen -> Width;
  333.                 }
  334.  
  335.                 if(PacketY == -1 || (PacketY + PacketHeight > Screen -> Height))
  336.                 {
  337.                     PacketY = Window -> TopEdge + Window -> Height;
  338.  
  339.                     if(PacketY + PacketHeight > Screen -> Height)
  340.                         PacketHeight = ProtoHeight;
  341.                 }
  342.  
  343.                 if(CreateAllGadgets(PacketWidth,&PacketGadgetArray[0],&PacketGadgetList,VisualInfo,Screen -> WBorTop + Screen -> Font -> ta_YSize + 1))
  344.                 {
  345.                     if(PacketWindow = OpenWindowTags(NULL,
  346.                         WA_Width,        PacketWidth,
  347.                         WA_Height,        PacketHeight,
  348.  
  349.                         WA_Left,        PacketX,
  350.                         WA_Top,            PacketY,
  351.  
  352.                         WA_Activate,        TRUE,
  353.                         WA_DragBar,        TRUE,
  354.                         WA_DepthGadget,        TRUE,
  355.                         WA_CloseGadget,        TRUE,
  356.                         WA_RMBTrap,        TRUE,
  357.                         WA_SizeGadget,        TRUE,
  358.                         WA_MinWidth,        80,
  359.                         WA_MinHeight,        ProtoHeight,
  360.                         WA_MaxWidth,        Screen -> Width,
  361.                         WA_MaxHeight,        Screen -> Height,
  362.                         WA_CustomScreen,    Screen,
  363.                         WA_NoCareRefresh,    TRUE,
  364.                         WA_NewLookMenus,    TRUE,
  365.  
  366.                         WA_IDCMP,        STRINGIDCMP | LISTVIEWIDCMP | IDCMP_NEWSIZE | IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_ACTIVEWINDOW | IDCMP_RAWKEY | IDCMP_MOUSEBUTTONS,
  367.  
  368.                         WA_Title,        LocaleString(MSG_GLOBAL_PACKET_WINDOW_TXT),
  369.                     TAG_DONE))
  370.                     {
  371.                         struct MenuItem    *Item;
  372.  
  373.                         if(Item = FindThisItem(MEN_PACKET_WINDOW))
  374.                             Item -> Flags |= CHECKED;
  375.  
  376.                         PacketPort -> mp_Flags        = PA_SIGNAL;
  377.                         PacketPort -> mp_SigBit        = PacketWindow -> UserPort -> mp_SigBit;
  378.                         PacketPort -> mp_SigTask    = PacketWindow -> UserPort -> mp_SigTask;
  379.  
  380.                         NewList(&PacketPort -> mp_MsgList);
  381.  
  382.                         PacketHook . h_Entry        = (APTR)PacketKey;
  383.                         PacketHook . h_SubEntry        = NULL;
  384.                         PacketHook . h_Data        = NULL;
  385.  
  386.                         PacketInfo = (struct StringInfo *)PacketGadgetArray[GAD_STRING] -> SpecialInfo;
  387.  
  388.                         AddGList(PacketWindow,PacketGadgetList,(UWORD)-1,(UWORD)-1,NULL);
  389.                         RefreshGList(PacketGadgetList,PacketWindow,NULL,(UWORD)-1);
  390.                         GT_RefreshWindow(PacketWindow,NULL);
  391.  
  392.                         SetMenuStrip(PacketWindow,PacketMenu);
  393.  
  394.                         PacketWindow -> Flags &= ~WFLG_RMBTRAP;
  395.  
  396.                         ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  397.  
  398.                         return(TRUE);
  399.                     }
  400.                 }
  401.             }
  402.         }
  403.     }
  404.  
  405.     DeletePacketWindow(FALSE);
  406.  
  407.     return(FALSE);
  408. }
  409.  
  410.     /* PacketKey(struct Hook *Hook,struct SGWork *Work,ULONG *Msg):
  411.      *
  412.      *    This is a string gadget editing call back routine
  413.      *    (a so-called `hook') which is to perform all the
  414.      *    line editing and command history actions supported
  415.      *    by the packet window.
  416.      */
  417.  
  418. VOID __saveds __asm
  419. PacketKey(register __a0 struct Hook *Hook,register __a1 ULONG *Msg,register __a2 struct SGWork *Work)
  420. {
  421.         /* Someone activated the string gadget and
  422.          * hit a key.
  423.          */
  424.  
  425.     if(Msg[0] == SGH_KEY)
  426.     {
  427.         if(Work -> IEvent -> ie_Qualifier & IEQUALIFIER_RCOMMAND)
  428.         {
  429.             if(Work -> Code == 'c')
  430.             {
  431.                 Work -> Actions &= ~SGA_USE;
  432.                 Work -> Actions |= SGA_BEEP;
  433.  
  434.                 if(Work -> PrevBuffer[0])
  435.                 {
  436.                     struct MsgPort *ReplyPort;
  437.  
  438.                     if(ReplyPort = CreateMsgPort())
  439.                     {
  440.                         struct Message ClipMessage;
  441.  
  442.                         ClipMessage . mn_Node . ln_Name    = Work -> PrevBuffer;
  443.                         ClipMessage . mn_ReplyPort    = ReplyPort;
  444.                         ClipMessage . mn_Length        = sizeof(struct Message);
  445.  
  446.                         PutMsg(ClipPort,&ClipMessage);
  447.  
  448.                         WaitPort(ReplyPort);
  449.  
  450.                         GetMsg(ReplyPort);
  451.  
  452.                         DeleteMsgPort(ReplyPort);
  453.  
  454.                         Work -> Actions &= ~SGA_BEEP;
  455.                     }
  456.                 }
  457.  
  458.                 return;
  459.             }
  460.  
  461.             if(Work -> Code == 'v')
  462.             {
  463.                 Work -> Actions &= ~SGA_USE;
  464.                 Work -> Actions |= SGA_BEEP;
  465.  
  466.                 if(!(Work -> Gadget -> Activation & GACT_LONGINT))
  467.                 {
  468.                     struct MsgPort *ReplyPort;
  469.  
  470.                     if(ReplyPort = CreateMsgPort())
  471.                     {
  472.                         STATIC UBYTE    Buffer[2048];
  473.                         struct Message    ClipMessage;
  474.  
  475.                         Buffer[0] = 0;
  476.  
  477.                         ClipMessage . mn_Node . ln_Name    = &Buffer[0];
  478.                         ClipMessage . mn_ReplyPort    = ReplyPort;
  479.                         ClipMessage . mn_Length        = sizeof(struct Message);
  480.  
  481.                         PutMsg(ClipPort,&ClipMessage);
  482.  
  483.                         WaitPort(ReplyPort);
  484.  
  485.                         GetMsg(ReplyPort);
  486.  
  487.                         DeleteMsgPort(ReplyPort);
  488.  
  489.                         if(Buffer[0])
  490.                         {
  491.                             WORD Len = strlen(Buffer);
  492.  
  493.                             while(Len > 0 && Work -> NumChars + Len > Work -> StringInfo -> MaxChars)
  494.                                 Len--;
  495.  
  496.                             if(Len > 0)
  497.                             {
  498.                                 STATIC UBYTE OtherBuffer[2048];
  499.  
  500.                                 Buffer[Len] = 0;
  501.  
  502.                                 if(Work -> StringInfo -> UndoBuffer)
  503.                                     strcpy(Work -> StringInfo -> UndoBuffer,Work -> PrevBuffer);
  504.  
  505.                                 Work -> StringInfo -> UndoPos = --Work -> BufferPos;
  506.  
  507.                                 if(Work -> BufferPos)
  508.                                     CopyMem(Work -> PrevBuffer,OtherBuffer,Work -> BufferPos);
  509.  
  510.                                 OtherBuffer[Work -> BufferPos] = 0;
  511.  
  512.                                 strcat(OtherBuffer,Buffer);
  513.  
  514.                                 strcat(OtherBuffer,&Work -> PrevBuffer[Work -> BufferPos]);
  515.  
  516.                                 strcpy(Work -> WorkBuffer,OtherBuffer);
  517.  
  518.                                 Work -> BufferPos += Len;
  519.                                 Work -> NumChars    += Len;
  520.  
  521.                                 Work -> Actions    |= SGA_USE;
  522.                                 Work -> EditOp     = EO_BIGCHANGE;
  523.  
  524.                                 Work -> Actions &= ~SGA_BEEP;
  525.                             }
  526.                         }
  527.                         else
  528.                             Work -> Actions &= ~SGA_BEEP;
  529.                     }
  530.                 }
  531.  
  532.                 return;
  533.             }
  534.         }
  535.  
  536.             /* Right-Amiga-key was pressed, release the
  537.              * string gadget so user may select a menu
  538.              * item.
  539.              */
  540.  
  541.         if((Work -> IEvent -> ie_Qualifier & AMIGARIGHT) && Work -> IEvent -> ie_Code < 96)
  542.         {
  543.             if(!(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) && (Work -> IEvent -> ie_Code == KEYCODE_X || Work -> IEvent -> ie_Code == KEYCODE_Q))
  544.                 return;
  545.             else
  546.             {
  547.                 Work -> Actions |= (SGA_END|SGA_REUSE);
  548.                 Work -> Actions &= ~(SGA_USE|SGA_BEEP);
  549.  
  550.                 CommandWindow = Work -> GadgetInfo -> gi_Window;
  551.                 CommandGadget = Work -> Gadget;
  552.             }
  553.         }
  554.  
  555.             /* The user pressed the cursor-right key to
  556.              * move the cursor to the next word in the buffer.
  557.              */
  558.  
  559.         if(Work -> IEvent -> ie_Code == CURSORRIGHT && (Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CONTROL))
  560.         {
  561.             if(Work -> BufferPos != Work -> NumChars)
  562.             {
  563.                 WORD i,Position = -1;
  564.  
  565.                 for(i = Work -> BufferPos ; i < Work -> NumChars ; i++)
  566.                 {
  567.                     if(Work -> WorkBuffer[i] == ' ')
  568.                     {
  569.                         for( ; i < Work -> NumChars ; i++)
  570.                         {
  571.                             if(Work -> WorkBuffer[i] != ' ')
  572.                             {
  573.                                 Position = i;
  574.                                 break;
  575.                             }
  576.                         }
  577.  
  578.                         break;
  579.                     }
  580.                 }
  581.  
  582.                 if(Position != -1)
  583.                     Work -> BufferPos = Position;
  584.                 else
  585.                     Work -> BufferPos = Work -> NumChars;
  586.  
  587.                 Work -> EditOp = EO_MOVECURSOR;
  588.             }
  589.         }
  590.  
  591.             /* The user pressed the cursor-right key to
  592.              * move the cursor to the previous word in the buffer.
  593.              */
  594.  
  595.         if(Work -> IEvent -> ie_Code == CURSORLEFT && (Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CONTROL))
  596.         {
  597.             if(Work -> BufferPos)
  598.             {
  599.                 WORD i,Position = -1;
  600.  
  601.                 for(i = Work -> BufferPos ; i >= 0 ; i--)
  602.                 {
  603.                     if(Work -> WorkBuffer[i] != ' ')
  604.                     {
  605.                         Position = i;
  606.                         break;
  607.                     }
  608.                 }
  609.  
  610.                 if(Position == -1)
  611.                     Position = 0;
  612.  
  613.                 if(Position)
  614.                 {
  615.                     i = Position;
  616.  
  617.                     Position = -1;
  618.  
  619.                     for( ; i >= 0 ; i--)
  620.                     {
  621.                         if(Work -> WorkBuffer[i] == ' ')
  622.                         {
  623.                             Position = i + 1;
  624.                             break;
  625.                         }
  626.                     }
  627.                 }
  628.  
  629.                 if(Position != -1)
  630.                     Work -> BufferPos = Position;
  631.                 else
  632.                     Work -> BufferPos = 0;
  633.  
  634.                 Work -> EditOp = EO_MOVECURSOR;
  635.             }
  636.         }
  637.  
  638.             /* The user pressed the cursor-up key to
  639.              * scroll through the command history.
  640.              */
  641.  
  642.         if(Work -> IEvent -> ie_Code == CURSORUP)
  643.         {
  644.                 /* Shift key: jump to first command
  645.                  * history entry.
  646.                  */
  647.  
  648.             if(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  649.             {
  650.                 if(PacketLine)
  651.                     SendPacketMsg(0);
  652.             }
  653.             else
  654.             {
  655.                 if(PacketLine && PacketCount > 0)
  656.                     SendPacketMsg(PacketCount - 1);
  657.             }
  658.         }
  659.  
  660.             /* The user pressed the cursor-down key to
  661.              * scroll through the command history.
  662.              */
  663.  
  664.         if(Work -> IEvent -> ie_Code == CURSORDOWN)
  665.         {
  666.                 /* Shift key: jump to last command
  667.                  * history entry.
  668.                  */
  669.  
  670.             if(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  671.             {
  672.                 if(PacketLine > 0)
  673.                     SendPacketMsg(PacketLine);
  674.             }
  675.             else
  676.             {
  677.                 if(PacketCount < PacketLine)
  678.                     SendPacketMsg(PacketCount + 1);
  679.             }
  680.         }
  681.     }
  682. }
  683.  
  684.     /* HandlePacket():
  685.      *
  686.      *    Process the input coming through the packet window.
  687.      */
  688.  
  689. BYTE
  690. HandlePacket()
  691. {
  692.     struct IntuiMessage    *Massage;
  693.     struct PacketMessage    *PacketMsg;
  694.     ULONG             Class,Code;
  695.     struct Gadget        *Gadget;
  696.     struct FileRequest    *FileRequest;
  697.     UBYTE             DummyBuffer[256];
  698.     BYTE             SwapWindow = FALSE;
  699.  
  700.         /* Are we already shut down? */
  701.  
  702.     if(PacketWindow)
  703.     {
  704.         BYTE Result = FALSE;
  705.  
  706.         if(Massage = (struct IntuiMessage *)GT_GetIMsg(PacketWindow -> UserPort))
  707.         {
  708.             Class    = Massage -> Class;
  709.             Code    = Massage -> Code;
  710.             Gadget    = (struct Gadget *)Massage -> IAddress;
  711.  
  712.             GT_ReplyIMsg(Massage);
  713.  
  714.                 /* Re-enable the string gadget if necessary. */
  715.  
  716.             if(Class == IDCMP_RAWKEY)
  717.                 if(Code == IECODE_UP_PREFIX|103 && CommandWindow == PacketWindow)
  718.                     ActivateGadget(CommandGadget,PacketWindow,NULL);
  719.  
  720.                 /* Handle the menu. */
  721.  
  722.             if(Class == IDCMP_MENUPICK)
  723.             {
  724.                 struct MenuItem *MenuItem;
  725.  
  726.                 while(Code != MENUNULL)
  727.                 {
  728.                     MenuItem = ItemAddress(PacketMenu,Code);
  729.  
  730.                     switch((ULONG)GTMENUITEM_USERDATA(MenuItem))
  731.                     {
  732.                         case MEN_QUITPANEL:    Class = IDCMP_CLOSEWINDOW;
  733.                                     break;
  734.  
  735.                         case MEN_LOADHISTORY:    BlockWindows();
  736.  
  737.                                     if(FileRequest = GetFile(LocaleString(MSG_PACKET_LOAD_HISTORY_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_LOAD_TXT)))
  738.                                     {
  739.                                         if(GetFileSize(DummyBuffer))
  740.                                         {
  741.                                             BPTR SomeFile;
  742.  
  743.                                             if(SomeFile = Open(DummyBuffer,MODE_OLDFILE))
  744.                                             {
  745.                                                 if(PacketLine)
  746.                                                 {
  747.                                                     switch(MyEasyRequest(Window,LocaleString(MSG_PACKET_PACKET_WINDOW_STILL_HOLDS_LINES_TXT),LocaleString(MSG_PACKET_DISCARD_APPEND_CANCEL_TXT),PacketLine))
  748.                                                     {
  749.                                                         case 1:    ClearPacketHistory();
  750.                                                             break;
  751.  
  752.                                                         case 2:    break;
  753.  
  754.                                                         case 0:    Close(SomeFile);
  755.                                                             SomeFile = NULL;
  756.                                                             break;
  757.                                                     }
  758.                                                 }
  759.  
  760.                                                 if(SomeFile)
  761.                                                 {
  762.                                                     WORD Len;
  763.  
  764.                                                     LineRead(NULL,NULL,NULL);
  765.  
  766.                                                     while(Len = LineRead(SomeFile,DummyBuffer,255))
  767.                                                     {
  768.                                                         DummyBuffer[Len - 1] = 0;
  769.  
  770.                                                         AddPacketHistory(DummyBuffer);
  771.                                                     }
  772.  
  773.                                                     Close(SomeFile);
  774.                                                 }
  775.                                             }
  776.                                         }
  777.                                     }
  778.  
  779.                                     ReleaseWindows();
  780.                                     break;
  781.  
  782.                         case MEN_SAVEHISTORY:    BlockWindows();
  783.  
  784.                                     if(!PacketLine)
  785.                                         MyEasyRequest(Window,LocaleString(MSG_PACKET_NOTHING_IN_THE_BUFFER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  786.                                     else
  787.                                     {
  788.                                         if(FileRequest = GetFile(LocaleString(MSG_PACKET_SAVE_HISTORY_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT)))
  789.                                         {
  790.                                             BPTR SomeFile = NULL;
  791.  
  792.                                                 /* If the file we are about
  793.                                                  * to create already exists,
  794.                                                  * ask the user whether we are
  795.                                                  * to create, append or skip
  796.                                                  * the file.
  797.                                                  */
  798.  
  799.                                             if(GetFileSize(DummyBuffer))
  800.                                             {
  801.                                                 switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  802.                                                 {
  803.                                                     case 1:    SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  804.                                                         break;
  805.  
  806.                                                     case 2:    if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
  807.                                                         {
  808.                                                             if(Seek(SomeFile,0,OFFSET_END) == -1)
  809.                                                             {
  810.                                                                 Close(SomeFile);
  811.  
  812.                                                                 SomeFile = NULL;
  813.                                                             }
  814.                                                         }
  815.                                                         break;
  816.                                                 }
  817.                                             }
  818.                                             else
  819.                                                 SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  820.  
  821.                                             if(!SomeFile)
  822.                                                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_ERROR_OPENING_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  823.                                             else
  824.                                             {
  825.                                                 struct Node *SomeNode;
  826.  
  827.                                                 SomeNode = PacketHistoryList . lh_Head;
  828.  
  829.                                                 while(SomeNode -> ln_Succ)
  830.                                                 {
  831.                                                     FPrintf(SomeFile,"%s\n",SomeNode -> ln_Name);
  832.  
  833.                                                     SomeNode = SomeNode -> ln_Succ;
  834.                                                 }
  835.  
  836.                                                 Close(SomeFile);
  837.                                             }
  838.  
  839.                                             FreeAslRequest(FileRequest);
  840.                                         }
  841.                                     }
  842.  
  843.                                     ReleaseWindows();
  844.  
  845.                                     break;
  846.  
  847.                         case MEN_CLEARHISTORY:  BlockWindows();
  848.  
  849.                                     ClearPacketHistory();
  850.  
  851.                                     ReleaseWindows();
  852.                                     break;
  853.  
  854.                         case MEN_OTHERWINDOW:    SwapWindow = TRUE;
  855.                                     break;
  856.  
  857.                         default:        break;
  858.                     }
  859.  
  860.                     Code = MenuItem -> NextSelect;
  861.                 }
  862.  
  863.                 ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  864.             }
  865.  
  866.                 /* Shut down. */
  867.  
  868.             if(Class == IDCMP_CLOSEWINDOW)
  869.             {
  870.                 DeletePacketWindow(FALSE);
  871.  
  872.                 return(FALSE);
  873.             }
  874.  
  875.                 /* Activate the string gadget as well. */
  876.  
  877.             if(Class == IDCMP_ACTIVEWINDOW)
  878.                 ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  879.  
  880.             if(Class == IDCMP_NEWSIZE)
  881.             {
  882.                 PacketWindow -> Flags |= WFLG_RMBTRAP;
  883.  
  884.                 strcpy(DummyBuffer,PacketInfo -> Buffer);
  885.  
  886.                 RemoveGList(PacketWindow,PacketGadgetList,(UWORD)-1);
  887.  
  888.                 FreeGadgets(PacketGadgetList);
  889.  
  890.                 PacketGadgetList = NULL;
  891.  
  892.                 SetAPen(PacketWindow -> RPort,0);
  893.                 RectFill(PacketWindow -> RPort,PacketWindow -> BorderLeft,PacketWindow -> BorderTop,PacketWindow -> Width - PacketWindow -> BorderRight,PacketWindow -> Height - PacketWindow -> BorderBottom);
  894.                 RefreshWindowFrame(PacketWindow);
  895.  
  896.                 PacketHeight    = PacketWindow -> Height;
  897.                 PacketWidth    = PacketWindow -> Width;
  898.  
  899.                 if(CreateAllGadgets(PacketWindow -> Width,&PacketGadgetArray[0],&PacketGadgetList,VisualInfo,Screen -> WBorTop + Screen -> Font -> ta_YSize + 1))
  900.                 {
  901.                     PacketInfo = (struct StringInfo *)PacketGadgetArray[GAD_STRING] -> SpecialInfo;
  902.  
  903.                     strcpy(PacketInfo -> Buffer,DummyBuffer);
  904.  
  905.                     AddGList(PacketWindow,PacketGadgetList,(UWORD)-1,(UWORD)-1,NULL);
  906.                     RefreshGList(PacketGadgetList,PacketWindow,NULL,(UWORD)-1);
  907.                     GT_RefreshWindow(PacketWindow,NULL);
  908.  
  909.                     PacketWindow -> Flags &= ~WFLG_RMBTRAP;
  910.  
  911.                     ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  912.                 }
  913.                 else
  914.                 {
  915.                     DeletePacketWindow(FALSE);
  916.  
  917.                     return(FALSE);
  918.                 }
  919.             }
  920.  
  921.             if(Class == IDCMP_MOUSEBUTTONS)
  922.                 ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  923.  
  924.                 /* User has entered a string. */
  925.  
  926.             if(Class == IDCMP_GADGETUP)
  927.             {
  928.                 switch(Gadget -> GadgetID)
  929.                 {
  930.                     case GAD_STRING:        /* Just pressed Right-Amiga? */
  931.  
  932.                                     /* Is there anything in the buffer at all? */
  933.  
  934.                                 if(PacketInfo -> Buffer[0])
  935.                                 {
  936.                                     strcpy(DummyBuffer,PacketInfo -> Buffer);
  937.  
  938.                                     if(PacketString)
  939.                                     {
  940.                                         if(strcmp(PacketString,DummyBuffer))
  941.                                             AddPacketHistory(DummyBuffer);
  942.  
  943.                                         PacketString = NULL;
  944.                                     }
  945.                                     else
  946.                                         AddPacketHistory(DummyBuffer);
  947.  
  948.                                         /* Convert alien IBM characters. */
  949.  
  950.                                     if(Config . Font == FONT_IBM)
  951.                                     {
  952.                                         WORD i;
  953.                                         UBYTE Char;
  954.  
  955.                                         for(i = 0 ; i < strlen(DummyBuffer) ; i++)
  956.                                         {
  957.                                             if(Char = IBMConversion[DummyBuffer[i]])
  958.                                                 DummyBuffer[i] = Char;
  959.                                         }
  960.                                     }
  961.  
  962.                                         /* Execute the command. */
  963.  
  964.                                     SerialCommand(DummyBuffer);
  965.                                 }
  966.  
  967.                                     /* Clear the packet window string
  968.                                      * gadget.
  969.                                      */
  970.  
  971.                                 GT_SetGadgetAttrs(PacketGadgetArray[GAD_STRING],PacketWindow,NULL,
  972.                                     GTST_String,    "",
  973.                                 TAG_DONE);
  974.  
  975.                                     /* Send a terminating `CR'. */
  976.  
  977.                                 switch(Config . SendCR)
  978.                                 {
  979.                                     case CR_IGNORE:    break;
  980.  
  981.                                     case CR_ASCR:    SerWrite("\r",1);
  982.                                             break;
  983.  
  984.                                     case CR_ASCRLF:    SerWrite("\r\n",2);
  985.                                             break;
  986.                                 }
  987.  
  988.                                     /* Re-activate the string gadget. */
  989.  
  990.                                 ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  991.  
  992.                                 break;
  993.  
  994.                     case GAD_LIST:        ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  995.                                 break;
  996.                 }
  997.             }
  998.  
  999.             if(SwapWindow)
  1000.                 BumpWindow(Window);
  1001.  
  1002.             Result = TRUE;
  1003.         }
  1004.  
  1005.         if(PacketMsg = (struct PacketMessage *)GetMsg(PacketPort))
  1006.         {
  1007.             struct Node *Node;
  1008.  
  1009.             Result = TRUE;
  1010.  
  1011.             if(Node = GetListNode(PacketMsg -> Line,&PacketHistoryList))
  1012.             {
  1013.                 PacketString = Node -> ln_Name;
  1014.  
  1015.                 if(HasList)
  1016.                 {
  1017.                     GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  1018.                         GTLV_Selected,    PacketMsg -> Line,
  1019.                         GTLV_Top,    PacketMsg -> Line,
  1020.                     TAG_DONE);
  1021.                 }
  1022.                 else
  1023.                 {
  1024.                     GT_SetGadgetAttrs(PacketGadgetArray[GAD_STRING],PacketWindow,NULL,
  1025.                         GTST_String,    Node -> ln_Name,
  1026.                     TAG_DONE);
  1027.                 }
  1028.             }
  1029.             else
  1030.             {
  1031.                 PacketString = NULL;
  1032.  
  1033.                 GT_SetGadgetAttrs(PacketGadgetArray[GAD_STRING],PacketWindow,NULL,
  1034.                     GTST_String,    "",
  1035.                 TAG_DONE);
  1036.             }
  1037.  
  1038.             PacketCount = PacketMsg -> Line;
  1039.  
  1040.             FreeVec(PacketMsg);
  1041.  
  1042.             ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  1043.         }
  1044.  
  1045.         return(Result);
  1046.     }
  1047.  
  1048.     return(FALSE);
  1049. }
  1050.