home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d8xx / d832 / term.lha / Term / term-3.1-Source.lha / termPacket.c < prev    next >
C/C++ Source or Header  |  1993-02-18  |  24KB  |  1,072 lines

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