/* $Revision Header * Header built automatically - do not edit! *************
 *
 *	(C) Copyright 1991 by Olaf 'Olsen' Barthel & MXM
 *
 *	Name .....: Packet.c
 *	Created ..: Wednesday 06-Feb-91 12:35
 *	Revision .: 0
 *
 *	Date            Author          Comment
 *	=========       ========        ====================
 *	06-Feb-91       Olsen           Created this file!
 *
 * $Revision Header ********************************************************/

#include "TermGlobal.h"

	/* Some private data required to handle both the window,
	 * the editing functions and the command history buffer.
	 */

STATIC struct Hook		 PacketHook;
STATIC UBYTE			 PacketWorkBuffer[256];
STATIC struct StringInfo	*PacketInfo;

STATIC struct Node		*PacketNode;
STATIC LONG			 PacketLine;

STATIC LONG			 PacketX = -1,PacketY = -1,PacketWidth = -1,PacketHeight = -1;

	/* The menu to attach to the packet window. */

enum	{	MEN_LOADHISTORY=1,MEN_SAVEHISTORY,MEN_CLEARHISTORY,MEN_OTHERWINDOW,MEN_QUITPANEL };

STATIC struct NewMenu NewPacketMenu[] =
{
	{ NM_TITLE, "Project",		 0 , 0, 0, (APTR)0},
	{  NM_ITEM, "Load History...",	"O", 0, 0, (APTR)MEN_LOADHISTORY},
	{  NM_ITEM, "Save History...",	"S", 0, 0, (APTR)MEN_SAVEHISTORY},
	{  NM_ITEM, NM_BARLABEL,	 0 , 0, 0, (APTR)0},
	{  NM_ITEM, "Clear History",	"K", 0, 0, (APTR)MEN_CLEARHISTORY},
	{  NM_ITEM, NM_BARLABEL,	 0 , 0, 0, (APTR)0},
	{  NM_ITEM, "Other Window",	"-", 0, 0, (APTR)MEN_OTHERWINDOW},
	{  NM_ITEM, NM_BARLABEL,	 0 , 0, 0, (APTR)0},
	{  NM_ITEM, "Quit",		"Q", 0, 0, (APTR)MEN_QUITPANEL},
	{ NM_END, 0,			 0 , 0, 0, (APTR)0}
};

	/* ClearPacketHistory():
	 *
	 *	Release the command history.
	 */

VOID
ClearPacketHistory()
{
	struct Node *SomeNode,*NextNode;

	SomeNode = PacketHistoryList . lh_Head;

	while(SomeNode -> ln_Succ)
	{
		NextNode = SomeNode -> ln_Succ;

		Remove(SomeNode);

		FreeVec(SomeNode);

		SomeNode = NextNode;
	}

	PacketNode = PacketHistoryList . lh_Head;

	PacketLine = 0;
}

	/* DeletePacketWindow():
	 *
	 *	Delete the packet window and release the command
	 *	history.
	 */

VOID
DeletePacketWindow()
{
	if(PacketWindow)
	{
		PacketWindow -> Flags |= WFLG_RMBTRAP;

		ClearMenuStrip(PacketWindow);

		if(PacketGadgetList)
			RemoveGList(PacketWindow,PacketGadgetList,(UWORD)-1);

		PacketX		= PacketWindow -> LeftEdge;
		PacketY		= PacketWindow -> TopEdge;

		PacketWidth	= PacketWindow -> Width;
		PacketHeight	= PacketWindow -> Height;

		CloseWindow(PacketWindow);

		PacketWindow = NULL;
	}

	if(PacketGadgetList)
	{
		FreeGadgets(PacketGadgetList);

		PacketGadgetList = NULL;
	}

	ClearPacketHistory();

	if(PacketMenu)
	{
		FreeMenus(PacketMenu);

		PacketMenu = NULL;
	}
}

	/* AddPacketHistory(UBYTE *Buffer):
	 *
	 *	Add a line to the packet window command history. This
	 *	works very much the same as the AddLine()-routine.
	 */

VOID
AddPacketHistory(UBYTE *Buffer)
{
	struct Node *SomeNode;

	if(SomeNode = (struct Node *)AllocVec(sizeof(struct Node) + strlen(Buffer) + 1,MEMF_PUBLIC|MEMF_CLEAR))
	{
		SomeNode -> ln_Name = (UBYTE *)(SomeNode + 1);

		strcpy(SomeNode -> ln_Name,Buffer);

		AddTail(&PacketHistoryList,SomeNode);

		PacketNode = NULL;

		PacketLine++;
	}
}

	/* CreateAllGadgets():
	 *
	 *	Create the packet string gadget.
	 */

STATIC struct Gadget *
CreateAllGadgets(LONG Width,struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR VisualInfo,UWORD TopEdge)
{
	struct Gadget		*Gadget;
	struct NewGadget	 NewGadget;

	memset(&NewGadget,0,sizeof(struct NewGadget));

	if(Gadget = CreateContext(GadgetList))
	{
		NewGadget . ng_Width		= Width - 26;
		NewGadget . ng_Height		= PacketHeight - 15;
		NewGadget . ng_GadgetText	= NULL;
		NewGadget . ng_TextAttr		= &DefaultFont;
		NewGadget . ng_VisualInfo	= VisualInfo;
		NewGadget . ng_GadgetID		= 0;
		NewGadget . ng_Flags		= 0;
		NewGadget . ng_LeftEdge		= 6;
		NewGadget . ng_TopEdge		= 1 + TopEdge;

		GadgetArray[0] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
			GTST_MaxChars,	256,
			GTST_EditHook,	&PacketHook,
			GA_TabCycle,	FALSE,
		TAG_DONE);
	}

	return(Gadget);
}

	/* CreatePacketWindow():
	 *
	 *	Open the packet window and allocate the command history
	 *	buffer.
	 */

BYTE
CreatePacketWindow()
{
	PacketNode = PacketHistoryList . lh_Head;

	if(PacketMenu = CreateMenus(NewPacketMenu,
		GTMN_FrontPen, 0,
	TAG_DONE))
	{
		if(LayoutMenus(PacketMenu,VisualInfo,
			GTMN_TextAttr,&DefaultFont,
		TAG_DONE))
		{
			if(PacketWidth == -1)
				PacketWidth = Screen -> Width;

			if(PacketHeight == -1)
				PacketHeight = 29;

			if(PacketX == -1 || (PacketX + PacketWidth > Screen -> Width))
			{
				PacketX = 0;

				if(PacketX + PacketWidth > Screen -> Width)
					PacketWidth = Screen -> Width;
			}

			if(PacketY == -1 || (PacketY + PacketHeight > Screen -> Height))
			{
				PacketY = Window -> TopEdge + Window -> Height;

				if(PacketY + PacketHeight > Screen -> Height)
					PacketHeight = 29;
			}

			if(CreateAllGadgets(PacketWidth,&PacketGadgetArray[0],&PacketGadgetList,VisualInfo,Screen -> WBorTop + Screen -> Font -> ta_YSize + 1))
			{
				if(PacketWindow = OpenWindowTags(NULL,
					WA_Width,	PacketWidth,
					WA_Height,	PacketHeight,

					WA_Left,	PacketX,
					WA_Top,		PacketY,

					WA_Activate,	TRUE,
					WA_DragBar,	TRUE,
					WA_DepthGadget,	TRUE,
					WA_CloseGadget,	TRUE,
					WA_RMBTrap,	TRUE,
					WA_SizeGadget,	TRUE,
					WA_MinWidth,	80,
					WA_MinHeight,	29,
					WA_MaxWidth,	Screen -> Width,
					WA_MaxHeight,	29,
					WA_CustomScreen,Screen,

					WA_IDCMP,	STRINGIDCMP | IDCMP_NEWSIZE | IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_ACTIVEWINDOW | IDCMP_RAWKEY,

					WA_Title,	"Packet Window",
				TAG_DONE))
				{
					InitHook(&PacketHook,PacketKey);

					PacketInfo = (struct StringInfo *)PacketGadgetArray[0] -> SpecialInfo;

					AddGList(PacketWindow,PacketGadgetList,(UWORD)-1,(UWORD)-1,NULL);
					RefreshGList(PacketGadgetList,PacketWindow,NULL,(UWORD)-1);
					GT_RefreshWindow(PacketWindow,NULL);

					SetMenuStrip(PacketWindow,PacketMenu);

					PacketWindow -> Flags &= ~WFLG_RMBTRAP;

					ActivateGadget(PacketGadgetArray[0],PacketWindow,NULL);
					return(TRUE);
				}
			}
		}
	}

	DeletePacketWindow();

	return(FALSE);
}

	/* PacketKey(struct Hook *Hook,struct SGWork *Work,ULONG *Msg):
	 *
	 *	This is a string gadget editing call back routine
	 *	(a so-called `hook') which is to perform all the
	 *	line editing and command history actions supported
	 *	by the packet window.
	 */

VOID
PacketKey(struct Hook *Hook,struct SGWork *Work,ULONG *Msg)
{
		/* Someone activated the string gadget and
		 * hit a key.
		 */

	if(Msg[0] == SGH_KEY)
	{
		if(Work -> IEvent -> ie_Qualifier & IEQUALIFIER_RCOMMAND)
		{
			if(Work -> Code == 'c')
			{
				Work -> Actions &= ~SGA_USE;
				Work -> Actions |= SGA_BEEP;

				if(Work -> PrevBuffer[0])
				{
					struct MsgPort *ReplyPort;

					if(ReplyPort = CreateMsgPort())
					{
						struct Message ClipMessage;

						ClipMessage . mn_Node . ln_Name	= Work -> PrevBuffer;
						ClipMessage . mn_ReplyPort	= ReplyPort;
						ClipMessage . mn_Length		= sizeof(struct Message);

						PutMsg(ClipPort,&ClipMessage);

						WaitPort(ReplyPort);

						GetMsg(ReplyPort);

						DeleteMsgPort(ReplyPort);

						Work -> Actions &= ~SGA_BEEP;
					}
				}

				return;
			}

			if(Work -> Code == 'v')
			{
				Work -> Actions &= ~SGA_USE;
				Work -> Actions |= SGA_BEEP;

				if(!(Work -> Gadget -> Activation & GACT_LONGINT))
				{
					struct MsgPort *ReplyPort;

					if(ReplyPort = CreateMsgPort())
					{
						STATIC UBYTE	Buffer[2048];
						struct Message	ClipMessage;

						Buffer[0] = 0;

						ClipMessage . mn_Node . ln_Name	= &Buffer[0];
						ClipMessage . mn_ReplyPort	= ReplyPort;
						ClipMessage . mn_Length		= sizeof(struct Message);

						PutMsg(ClipPort,&ClipMessage);

						WaitPort(ReplyPort);

						GetMsg(ReplyPort);

						DeleteMsgPort(ReplyPort);

						if(Buffer[0])
						{
							WORD Len = strlen(Buffer);

							while(Len > 0 && Work -> NumChars + Len > Work -> StringInfo -> MaxChars)
								Len--;

							if(Len > 0)
							{
								STATIC UBYTE OtherBuffer[2048];

								Buffer[Len] = 0;

								if(Work -> StringInfo -> UndoBuffer)
									strcpy(Work -> StringInfo -> UndoBuffer,Work -> PrevBuffer);

								Work -> StringInfo -> UndoPos = --Work -> BufferPos;

								if(Work -> BufferPos)
									CopyMem(Work -> PrevBuffer,OtherBuffer,Work -> BufferPos);

								OtherBuffer[Work -> BufferPos] = 0;

								strcat(OtherBuffer,Buffer);

								strcat(OtherBuffer,&Work -> PrevBuffer[Work -> BufferPos]);

								strcpy(Work -> WorkBuffer,OtherBuffer);

								Work -> BufferPos += Len;
								Work -> NumChars	+= Len;

								Work -> Actions	|= SGA_USE;
								Work -> EditOp	 = EO_BIGCHANGE;

								Work -> Actions &= ~SGA_BEEP;
							}
						}
						else
							Work -> Actions &= ~SGA_BEEP;
					}
				}

				return;
			}
		}

			/* Right-Amiga-key was pressed, release the
			 * string gadget so user may select a menu
			 * item.
			 */

		if((Work -> IEvent -> ie_Qualifier & AMIGARIGHT) && Work -> IEvent -> ie_Code < 96)
		{
			if(!(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) && (Work -> IEvent -> ie_Code == KEYCODE_X || Work -> IEvent -> ie_Code == KEYCODE_Q))
				return;
			else
			{
				Work -> Actions |= (SGA_END|SGA_REUSE);
				Work -> Actions &= ~(SGA_USE|SGA_BEEP);

				CommandWindow = Work -> GadgetInfo -> gi_Window;
				CommandGadget = Work -> Gadget;
			}
		}

			/* The user pressed the cursor-right key to
			 * move the cursor to the next word in the buffer.
			 */

		if(Work -> IEvent -> ie_Code == CURSORRIGHT && (Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CONTROL))
		{
			if(Work -> BufferPos != Work -> NumChars)
			{
				WORD i,Position = -1;

				for(i = Work -> BufferPos ; i < Work -> NumChars ; i++)
				{
					if(Work -> WorkBuffer[i] == ' ')
					{
						for( ; i < Work -> NumChars ; i++)
						{
							if(Work -> WorkBuffer[i] != ' ')
							{
								Position = i;
								break;
							}
						}

						break;
					}
				}

				if(Position != -1)
					Work -> BufferPos = Position;
				else
					Work -> BufferPos = Work -> NumChars;

				Work -> EditOp = EO_MOVECURSOR;
			}
		}

			/* The user pressed the cursor-right key to
			 * move the cursor to the previous word in the buffer.
			 */

		if(Work -> IEvent -> ie_Code == CURSORLEFT && (Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CONTROL))
		{
			if(Work -> BufferPos)
			{
				WORD i,Position = -1;

				for(i = Work -> BufferPos ; i >= 0 ; i--)
				{
					if(Work -> WorkBuffer[i] != ' ')
					{
						Position = i;
						break;
					}
				}

				if(Position == -1)
					Position = 0;

				if(Position)
				{
					i = Position;

					Position = -1;

					for( ; i >= 0 ; i--)
					{
						if(Work -> WorkBuffer[i] == ' ')
						{
							Position = i + 1;
							break;
						}
					}
				}

				if(Position != -1)
					Work -> BufferPos = Position;
				else
					Work -> BufferPos = 0;

				Work -> EditOp = EO_MOVECURSOR;
			}
		}

			/* The user pressed the cursor-up key to
			 * scroll through the command history.
			 */

		if(Work -> IEvent -> ie_Code == CURSORUP)
		{
				/* Shift key: jump to first command
				 * history entry.
				 */

			if(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
			{
				PacketNode = PacketHistoryList . lh_Head;

				if(PacketNode -> ln_Succ)
				{
					Work -> WorkBuffer	= PacketNode -> ln_Name;
					Work -> NumChars	= strlen(Work -> WorkBuffer);
					Work -> EditOp		= EO_BIGCHANGE;
				}
			}
			else
			{
				BYTE TakeIt = FALSE;

				if(!PacketNode)
				{
					PacketNode = PacketHistoryList . lh_TailPred;

					if(PacketNode -> ln_Succ)
						TakeIt = TRUE;
				}
				else
				{
					if(PacketNode -> ln_Pred -> ln_Pred)
					{
						PacketNode = PacketNode -> ln_Pred;

						TakeIt = TRUE;
					}
				}

				if(TakeIt)
				{
					/* Jump to previous command
					 * history entry.
					 */

					Work -> WorkBuffer	= PacketNode -> ln_Name;
					Work -> NumChars	= strlen(Work -> WorkBuffer);

					Work -> EditOp = EO_BIGCHANGE;
				}
			}
		}

			/* The user pressed the cursor-down key to
			 * scroll through the command history.
			 */

		if(Work -> IEvent -> ie_Code == CURSORDOWN)
		{
				/* Shift key: jump to last command
				 * history entry.
				 */

			if(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
			{
				if(PacketHistoryList . lh_Head -> ln_Succ)
				{
					PacketNode = PacketHistoryList . lh_TailPred;

					if(PacketNode -> ln_Succ)
						Work -> WorkBuffer = PacketNode -> ln_Name;
					else
						Work -> WorkBuffer = "";

					Work -> EditOp		= EO_BIGCHANGE;
					Work -> NumChars	= strlen(Work -> WorkBuffer);
				}
			}
			else
			{
				if(PacketNode)
				{
					if(PacketNode -> ln_Succ)
					{
						PacketNode = PacketNode -> ln_Succ;

						Work -> WorkBuffer = PacketNode -> ln_Name;
					}
					else
						Work -> WorkBuffer = "";

					Work -> EditOp		= EO_BIGCHANGE;
					Work -> NumChars	= strlen(Work -> WorkBuffer);
				}
			}
		}
	}
}

	/* HandlePacket():
	 *
	 *	Process the input coming through the packet window.
	 */

BYTE
HandlePacket()
{
	struct IntuiMessage	*Massage;
	ULONG			 Class,Code;
	struct Gadget		*Gadget;
	struct FileRequest	*FileRequest;
	UBYTE			 DummyBuffer[256];
	BYTE			 SwapWindow = FALSE;

		/* Are we already shut down? */

	if(PacketWindow)
	{
		if(Massage = (struct IntuiMessage *)GT_GetIMsg(PacketWindow -> UserPort))
		{
			Class	= Massage -> Class;
			Code	= Massage -> Code;
			Gadget	= (struct Gadget *)Massage -> IAddress;

			GT_ReplyIMsg(Massage);

				/* Re-enable the string gadget if necessary. */

			if(Class == IDCMP_RAWKEY)
				if(Code == IECODE_UP_PREFIX|103 && CommandWindow == PacketWindow)
					ActivateGadget(CommandGadget,PacketWindow,NULL);

				/* Handle the menu. */

			if(Class == IDCMP_MENUPICK)
			{
				struct MenuItem *MenuItem;

				while(Code != MENUNULL)
				{
					MenuItem = ItemAddress(PacketMenu,Code);

					switch((ULONG)GTMENUITEM_USERDATA(MenuItem))
					{
						case MEN_QUITPANEL:	Class = IDCMP_CLOSEWINDOW;
									break;

						case MEN_LOADHISTORY:	BlockWindows();

									if(FileRequest = GetFile("Load History","","",DummyBuffer,NULL,FALSE,FALSE,FALSE,"Load"))
									{
										if(GetFileSize(DummyBuffer))
										{
											BPTR SomeFile;

											if(SomeFile = Open(DummyBuffer,MODE_OLDFILE))
											{
												if(PacketLine)
												{
													switch(MyEasyRequest(Window,"The packet history still holds %ld\nlines, do you wish to continue?","Discard History|Append History|Cancel",PacketLine))
													{
														case 1:	ClearPacketHistory();
															break;

														case 2:	break;

														case 0:	Close(SomeFile);
															SomeFile = NULL;
															break;
													}
												}

												if(SomeFile)
												{
													LineRead(NULL,NULL,NULL);

													while(LineRead(SomeFile,DummyBuffer,255))
														AddPacketHistory(DummyBuffer);

													Close(SomeFile);
												}
											}
										}
									}

									ReleaseWindows();
									break;

						case MEN_SAVEHISTORY:	BlockWindows();

									if(!PacketLine)
										MyEasyRequest(Window,"There isn't anything in the\npacket history right now.","Continue");
									else
									{
										if(FileRequest = GetFile("Save History","","",DummyBuffer,NULL,TRUE,FALSE,FALSE,"Save"))
										{
											BPTR SomeFile = NULL;

												/* If the file we are about
												 * to create already exists,
												 * ask the user whether we are
												 * to create, append or skip
												 * the file.
												 */

											if(GetFileSize(DummyBuffer))
											{
												switch(MyEasyRequest(Window,"File %s already exists!","Create New File|Append Data|Cancel",DummyBuffer))
												{
													case 1:	SomeFile = Open(DummyBuffer,MODE_NEWFILE);
														break;

													case 2:	if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
														{
															if(Seek(SomeFile,0,OFFSET_END) == -1)
															{
																Close(SomeFile);

																SomeFile = NULL;
															}
														}
														break;
												}
											}
											else
												SomeFile = Open(DummyBuffer,MODE_NEWFILE);

											if(!SomeFile)
												MyEasyRequest(Window,"Error opening file %s!","Continue",DummyBuffer);
											else
											{
												struct Node *SomeNode;

												SomeNode = PacketHistoryList . lh_Head;

												while(SomeNode -> ln_Succ)
												{
													FPrintf(SomeFile,"%s\n",SomeNode -> ln_Name);

													SomeNode = SomeNode -> ln_Succ;
												}

												Close(SomeFile);
											}

											FreeAslRequest(FileRequest);
										}
									}

									ReleaseWindows();

									break;

						case MEN_CLEARHISTORY:  BlockWindows();

									ClearPacketHistory();

									ReleaseWindows();
									break;

						case MEN_OTHERWINDOW:	SwapWindow = TRUE;
									break;

						default:		break;
					}

					Code = MenuItem -> NextSelect;
				}

				ActivateGadget(PacketGadgetArray[0],PacketWindow,NULL);
			}

				/* Shut down. */

			if(Class == IDCMP_CLOSEWINDOW)
				DeletePacketWindow();

				/* Activate the string gadget as well. */

			if(Class == IDCMP_ACTIVEWINDOW)
				ActivateGadget(PacketGadgetArray[0],PacketWindow,NULL);

			if(Class == IDCMP_NEWSIZE)
			{
				PacketWindow -> Flags |= WFLG_RMBTRAP;

				strcpy(DummyBuffer,PacketInfo -> Buffer);

				RemoveGList(PacketWindow,PacketGadgetList,(UWORD)-1);

				FreeGadgets(PacketGadgetList);

				PacketGadgetList = NULL;

				SetAPen(PacketWindow -> RPort,0);
				RectFill(PacketWindow -> RPort,PacketWindow -> BorderLeft,PacketWindow -> BorderTop,PacketWindow -> Width - PacketWindow -> BorderRight,PacketWindow -> Height - PacketWindow -> BorderBottom);
				RefreshWindowFrame(PacketWindow);

				if(CreateAllGadgets(PacketWindow -> Width,&PacketGadgetArray[0],&PacketGadgetList,VisualInfo,Screen -> WBorTop + Screen -> Font -> ta_YSize + 1))
				{
					PacketInfo = (struct StringInfo *)PacketGadgetArray[0] -> SpecialInfo;

					strcpy(PacketInfo -> Buffer,DummyBuffer);

					AddGList(PacketWindow,PacketGadgetList,(UWORD)-1,(UWORD)-1,NULL);
					RefreshGList(PacketGadgetList,PacketWindow,NULL,(UWORD)-1);
					GT_RefreshWindow(PacketWindow,NULL);

					PacketWindow -> Flags &= ~WFLG_RMBTRAP;

					ActivateGadget(PacketGadgetArray[0],PacketWindow,NULL);
				}
				else
					DeletePacketWindow();
			}

				/* User has entered a string. */

			if(Class == IDCMP_GADGETUP)
			{
					/* Just pressed Right-Amiga? */

				if(!DontActivate)
				{
						/* Is there anything in the buffer at all? */

					if(PacketInfo -> Buffer)
					{
							/* Perform selective history (don't
							 * buffer anything that's already
							 * in the command history.
							 */

						if(PacketNode -> ln_Succ)
						{
							if(strcmp(PacketNode -> ln_Name,PacketInfo -> Buffer))
								AddPacketHistory(PacketInfo -> Buffer);
							else
								PacketNode = NULL;
						}
						else
							AddPacketHistory(PacketInfo -> Buffer);

						strcpy(DummyBuffer,PacketInfo -> Buffer);

							/* Convert alien IBM characters. */

						if(Config . Font == FONT_IBM)
						{
							WORD i;
							UBYTE Char;

							for(i = 0 ; i < strlen(DummyBuffer) ; i++)
							{
								if(Char = IBMConversion[DummyBuffer[i]])
									DummyBuffer[i] = Char;
							}
						}

							/* Execute the command. */

						SerialCommand(DummyBuffer);
					}

						/* Clear the packet window string
						 * gadget.
						 */

					PacketInfo -> Buffer[0] = 0;

					RefreshGList(PacketGadgetList,PacketWindow,NULL,(UWORD)-1);

						/* Send a terminating `CR'. */

					switch(Config . SendCR)
					{
						case CR_IGNORE:	break;

						case CR_ASCR:	SerWrite("\r",1);
								break;

						case CR_ASCRLF:	SerWrite("\r\n",2);
								break;
					}

						/* Re-activate the string gadget. */

					ActivateGadget(PacketGadgetArray[0],PacketWindow,NULL);
				}
				else
					DontActivate = FALSE;
			}

			if(SwapWindow)
				BumpWindow(Window);

			return(TRUE);
		}
	}

	return(FALSE);
}
