home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Chat.c
- **
- ** Chat support code
- **
- ** Copyright © 1990-1996 by Olaf `Olsen' Barthel
- ** All Rights Reserved
- **
- ** :ts=4
- */
-
- #ifndef _GLOBAL_H
- #include "Global.h"
- #endif
-
- /* Maximum number of characters to enter per line */
-
- #define CHAT_LINE_SIZE 512
-
- /* Local data */
-
- STATIC struct List *ChatList;
- STATIC struct Node *ChatNode;
- STATIC STRPTR ChatBuffer,
- ChatUndo,
- ChatWork,
- ChatTemp;
- STATIC ULONG ChatPosition;
- STATIC Object *ChatGadget;
- STATIC BOOL ChatWasActive;
-
- /* HideChatGadget():
- *
- * Remove the chat gadget, but don't free the buffers.
- */
-
- VOID
- HideChatGadget()
- {
- if(ChatGadget)
- {
- GetAttr(STRINGA_BufferPos,ChatGadget,&ChatPosition);
-
- RemoveGList(Window,(struct Gadget *)ChatGadget,1);
-
- DisposeObject(ChatGadget);
-
- ChatGadget = NULL;
- }
- }
-
- /* DeleteChatGadget():
- *
- * Remove the chat gadget, also take care of the buffers.
- */
-
- VOID
- DeleteChatGadget()
- {
- HideChatGadget();
-
- FreeVecPooled(ChatBuffer);
- ChatBuffer = NULL;
-
- DeleteList(ChatList);
- ChatList = NULL;
- }
-
- /* UpdateChatGadget():
- *
- * Redraw the chat gadget imagery.
- */
-
- VOID
- UpdateChatGadget()
- {
- if(ChatGadget)
- {
- struct RastPort *RPort;
- LONG Left,Right,Top;
-
- RPort = Window->RPort;
-
- /* Draw the separator bar */
-
- if(StatusWindow || Config->ScreenConfig->StatusLine == STATUSLINE_DISABLED)
- Top = UserFontHeight;
- else
- Top = StatusDisplayHeight + UserFontHeight;
-
- Top = Window->Height - (Window->BorderBottom + Top + 2);
- Left = Window->BorderLeft;
- Right = Window->Width - (Window->BorderRight + 1);
-
- SetAPen(RPort,Pens[SHADOWPEN]);
- RectFill(RPort,Left,Top,Right,Top);
-
- Top++;
-
- SetAPen(RPort,Pens[SHINEPEN]);
- RectFill(RPort,Left,Top,Right,Top);
-
- /* Redraw the gadget */
-
- RefreshGList((struct Gadget *)ChatGadget,Window,NULL,1);
- }
- }
-
- /* ActivateChat(BOOL Reactivate):
- *
- * Activate the chat gadget.
- */
-
- VOID
- ActivateChat(BOOL Reactivate)
- {
- if(ChatGadget)
- {
- if(Reactivate)
- Reactivate = ChatWasActive;
- else
- Reactivate = TRUE;
-
- if(Reactivate)
- ActivateGadget((struct Gadget *)ChatGadget,Window,NULL);
- }
- }
-
- /* CreateChatGadget():
- *
- * Create the chat gadget and add it to the main window.
- */
-
- BOOL
- CreateChatGadget()
- {
- ChatWasActive = TRUE;
-
- /* Allocate the history list */
-
- if(!ChatList)
- {
- if(!(ChatList = CreateList()))
- return(FALSE);
-
- ChatNode = NULL;
- }
-
- /* Allocate the undo/work/editing buffers */
-
- if(!ChatBuffer)
- {
- if(!(ChatBuffer = (STRPTR)AllocVecPooled(5 * CHAT_LINE_SIZE,MEMF_ANY | MEMF_CLEAR)))
- {
- DeleteChatGadget();
-
- return(FALSE);
- }
- else
- {
- ChatUndo = ChatBuffer + CHAT_LINE_SIZE;
- ChatWork = ChatUndo + CHAT_LINE_SIZE;
- ChatTemp = ChatWork + CHAT_LINE_SIZE;
- }
- }
-
- /* Finally create the gadget */
-
- if(!ChatGadget)
- {
- STATIC struct Hook ChatHook;
-
- LONG Bottom = Window->BorderBottom + UserFontHeight - 1;
-
- InitHook(&ChatHook,(HOOKFUNC)CommonEditRoutine,NULL);
-
- if(!StatusWindow && Config->ScreenConfig->StatusLine != STATUSLINE_DISABLED && !Config->ScreenConfig->SplitStatus)
- Bottom += StatusDisplayHeight;
-
- if(!(ChatGadget = NewObject(NULL,STRGCLASS,
- GA_Left, Window->BorderLeft,
- GA_Height, UserFontHeight,
- GA_RelBottom, -Bottom,
- GA_RelWidth, -(Window->BorderLeft + Window->BorderRight),
- GA_TabCycle, FALSE,
- GA_ID, CHAT_GadgetID,
- GA_RelVerify, TRUE,
- GA_Immediate, TRUE,
- STRINGA_TextVal, ChatBuffer,
- STRINGA_MaxChars, CHAT_LINE_SIZE-1,
- STRINGA_Buffer, ChatBuffer,
- STRINGA_BufferPos, ChatPosition,
- STRINGA_UndoBuffer, ChatUndo,
- STRINGA_WorkBuffer, ChatWork,
- STRINGA_NoFilterMode, TRUE,
- STRINGA_EditHook, &ChatHook,
-
- /* NOTE: This should really look like below, */
- /* according to the BOOPSI documentation. */
- /* Even worse, the pen numbers are in reality */
- /* truncated to a maximum of colour # 15. */
-
- /* STRINGA_Pens, ((LONG)Pens[BACKGROUNDPEN] << 16) | Pens[TEXTPEN], */
- /* STRINGA_ActivePens, ((LONG)Pens[BACKGROUNDPEN] << 16) | Pens[TEXTPEN], */
-
- STRINGA_Pens, (Pens[BACKGROUNDPEN] << 8) | Pens[TEXTPEN],
- STRINGA_ActivePens, (Pens[BACKGROUNDPEN] << 8) | Pens[TEXTPEN],
- TAG_DONE)))
- {
- DeleteChatGadget();
-
- return(FALSE);
- }
- else
- AddGList(Window,(struct Gadget *)ChatGadget,(UWORD)~0,1,NULL);
- }
-
- return(TRUE);
- }
-
- /* HandleChatGadget(UWORD GadgetCode):
- *
- * Process the input forwarded by the chat line gadget.
- */
-
- VOID
- HandleChatGadget(UWORD GadgetCode)
- {
- BOOL Activate,NeedChange,AddIt;
- UWORD Code,Qualifier;
-
- Activate = TRUE;
- NeedChange = FALSE;
- Code = GadgetCode & 0xFF;
- Qualifier = GadgetCode >> 8;
-
- switch(Qualifier)
- {
- case 0xFF:
-
- switch(Code)
- {
- case CONTROL_('S'):
- case CONTROL_('Q'):
-
- ChatTemp[0] = Code;
- SendInputTextBuffer(ChatTemp,1,TRUE,TRUE);
- break;
-
- case '\r':
-
- LimitedStrcpy(CHAT_LINE_SIZE,ChatTemp,ChatBuffer);
-
- /* Add the line unless it is already in the history list. */
-
- AddIt = TRUE;
-
- if(ChatNode)
- {
- if(!Stricmp(ChatNode->ln_Name,ChatTemp))
- AddIt = FALSE;
- }
-
- if(AddIt)
- {
- struct Node *Node;
-
- if(Node = CreateNode(ChatTemp))
- AddTail(ChatList,Node);
- }
-
- ChatNode = NULL;
- NeedChange = TRUE;
-
- LimitedStrcat(CHAT_LINE_SIZE,ChatTemp,"\\r");
- SerialCommand(ChatTemp);
- break;
-
- case '\n':
-
- Activate = FALSE;
- break;
- }
-
- break;
-
- default:
-
- /* Clear the history list when pressing Amiga+Del/Amiga+Backspace */
-
- if((Qualifier & (AMIGARIGHT | AMIGALEFT)) && (Code == DEL_CODE || Code == BACKSPACE_CODE))
- {
- FreeList(ChatList);
-
- ChatNode = NULL;
-
- NeedChange = TRUE;
-
- break;
- }
-
- /* This looks like a function key. Send the corresponding macro. */
-
- if(Code >= F01_CODE && Code <= F10_CODE)
- {
- STRPTR String;
- LONG Index;
-
- Index = Code - F01_CODE;
-
- /* Pick the right macro */
-
- if(Qualifier & CONTROL_KEY)
- String = MacroKeys->Keys[3][Index];
- else
- {
- if(Qualifier & ALT_KEY)
- String = MacroKeys->Keys[2][Index];
- else
- {
- if(Qualifier & SHIFT_KEY)
- String = MacroKeys->Keys[1][Index];
- else
- String = MacroKeys->Keys[0][Index];
- }
- }
-
- /* Anything to do? */
-
- if(String[0])
- {
- /* This should really insert the macro at the current
- * cursor position, but due to some strange reasons
- * we can't get the position reliably.
- */
-
- LimitedStrcpy(CHAT_LINE_SIZE,ChatTemp,ChatBuffer);
- LimitedStrcat(CHAT_LINE_SIZE,ChatTemp,String);
-
- SetGadgetAttrs((struct Gadget *)ChatGadget,Window,NULL,
- STRINGA_TextVal, ChatTemp,
- STRINGA_BufferPos, strlen(ChatTemp),
- TAG_DONE);
- }
-
- break;
- }
-
- /* The user pressed the cursor-up key to
- * scroll through the command history.
- */
-
- if(Code == CURSORUP)
- {
- /* Shift key: jump to first command
- * history entry.
- */
-
- if(Qualifier & SHIFT_KEY)
- {
- NeedChange = TRUE;
-
- if(!IsListEmpty(ChatList))
- ChatNode = ChatList->lh_Head;
- else
- ChatNode = NULL;
- }
- else
- {
- if(ChatNode)
- {
- if(ChatNode->ln_Pred->ln_Pred)
- {
- NeedChange = TRUE;
-
- ChatNode = ChatNode->ln_Pred;
- }
- }
- else
- {
- if(!IsListEmpty(ChatList))
- {
- NeedChange = TRUE;
-
- ChatNode = ChatList->lh_TailPred;
- }
- }
- }
- }
-
- /* The user pressed the cursor-down key to
- * scroll through the command history.
- */
-
- if(Code == CURSORDOWN)
- {
- NeedChange = TRUE;
-
- /* Shift key: jump to last command
- * history entry.
- */
-
- if(Qualifier & SHIFT_KEY)
- {
- if(!IsListEmpty(ChatList))
- ChatNode = ChatList->lh_TailPred;
- else
- ChatNode = NULL;
- }
- else
- {
- if(ChatNode)
- {
- if(ChatNode->ln_Succ->ln_Succ)
- ChatNode = ChatNode->ln_Succ;
- else
- ChatNode = NULL;
- }
- }
- }
-
- break;
- }
-
- /* Check if we have to update the string gadget contents. */
-
- if(NeedChange)
- {
- SetGadgetAttrs((struct Gadget *)ChatGadget,Window,NULL,
- STRINGA_TextVal,ChatNode ? ChatNode->ln_Name : "",
- TAG_DONE);
- }
-
- ChatWasActive = Activate;
-
- if(Activate)
- ActivateGadget((struct Gadget *)ChatGadget,Window,NULL);
- }
-
- /* MarkChatGadgetAsActive():
- *
- * Remember that the chat gadget was activated.
- */
-
- VOID
- MarkChatGadgetAsActive()
- {
- ChatWasActive = TRUE;
- }
-