Merge branch 'master' of git://git.ucc.asn.au/tpg/acess2
[tpg/acess2.git] / Usermode / Applications / irc_src / input.c
diff --git a/Usermode/Applications/irc_src/input.c b/Usermode/Applications/irc_src/input.c
new file mode 100644 (file)
index 0000000..b99935c
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ */
+#include "input.h"
+#include "window.h"
+#include "server.h"
+#include <readline.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+// === PROTOTYPES ===
+void   Input_FillSelect(int *nfds, fd_set *rfds);
+void   Input_HandleSelect(int nfds, const fd_set *rfds);
+ int   ParseUserCommand(char *String);
+
+// === GLOBALS ===
+tReadline      *gpInput_ReadlineInfo;
+
+// === CODE ===
+void Input_FillSelect(int *nfds, fd_set *rfds)
+{
+       if( !gpInput_ReadlineInfo ) {
+               gpInput_ReadlineInfo = Readline_Init(1);
+       }
+       
+       FD_SET(0, rfds);
+       if(*nfds < 0+1)
+               *nfds = 0+1;
+}
+
+void Input_HandleSelect(int nfds, const fd_set *rfds)
+{
+       // User input
+       if(FD_ISSET(0, rfds))
+       {
+               char    *cmd = Readline_NonBlock(gpInput_ReadlineInfo);
+               if( cmd )
+               {
+                       if( cmd[0] )
+                       {
+                               ParseUserCommand(cmd);
+                       }
+                       free(cmd);
+                       // Prompt
+                       SetCursorPos(giTerminal_Height, 1);
+                       printf("\x1B[2K");      // Clear line
+                       int prompt_len = printf("[%s] ", Window_GetName(NULL));
+                       SetCursorPos(giTerminal_Height, prompt_len+1);
+                       fflush(stdout);
+               }
+       }
+}
+
+void Cmd_join(char *ArgString)
+{
+        int    pos=0;
+       char    *channel_name = GetValue(ArgString, &pos);
+       
+       tServer *srv = Window_GetServer(NULL);
+       
+       if( srv )
+       {
+               Windows_SwitchTo( Window_Create(srv, channel_name) );
+               Redraw_Screen();
+               Server_SendCommand(srv, "JOIN :%s", channel_name);
+       }
+}
+
+void Cmd_quit(char *ArgString)
+{
+       const char *quit_message = ArgString;
+       if( quit_message == NULL || quit_message[0] == '\0' )
+               quit_message = "/quit - Acess2 IRC Client";
+       
+       Servers_CloseAll(quit_message);
+       
+       Exit(NULL);     // NULL = user requested
+}
+
+void Cmd_window(char *ArgString)
+{
+        int    pos = 0;
+       char    *window_id = GetValue(ArgString, &pos);
+        int    window_num = atoi(window_id);
+       
+       if( window_num > 0 )
+       {
+               // Get `window_num`th window
+               tWindow *win = Windows_GetByIndex(window_num-1);
+               if( win )
+               {
+                       Windows_SwitchTo( win );
+               }
+               else
+               {
+                       // Otherwise, silently ignore
+               }
+       }
+       else
+       {
+               window_num = 1;
+               for( tWindow *win; (win = Windows_GetByIndex(window_num-1)); window_num ++ )
+               {
+                       Window_AppendMessage(WINDOW_STATUS, MSG_CLASS_CLIENT, NULL, "%i: %s", window_num, Window_GetName(win));
+               }
+       }
+}
+
+void Cmd_me(char *ArgString)
+{
+       tServer *srv = Window_GetServer(NULL);
+       if( srv && Window_IsChat(NULL) ) {
+               Window_AppendMessage(NULL, MSG_CLASS_ACTION, Server_GetNick(srv), "%s", ArgString);
+               Server_SendCommand(srv, "PRIVMSG %s :\1ACTION %s\1\n", Window_GetName(NULL), ArgString);
+       }
+}
+
+const struct {
+       const char *Name;
+       void    (*Fcn)(char *ArgString);
+} caCommands[] = {
+       {"join", Cmd_join},
+       {"quit", Cmd_quit},
+       {"window", Cmd_window},
+       {"win",    Cmd_window},
+       {"w",      Cmd_window},
+};
+const int ciNumCommands = sizeof(caCommands)/sizeof(caCommands[0]);
+
+/**
+ * \brief Handle a line from the prompt
+ */
+int ParseUserCommand(char *String)
+{
+       if( String[0] == '/' )
+       {
+               char    *command;
+                int    pos = 0;
+               
+               command = GetValue(String, &pos)+1;
+
+               // TODO: Prefix matches
+                int    cmdIdx = -1;
+               for( int i = 0; i < ciNumCommands; i ++ )
+               {
+                       if( strcmp(command, caCommands[i].Name) == 0 ) {
+                               cmdIdx = i;
+                               break;
+                       }
+               }
+               if( cmdIdx != -1 ) {
+                       caCommands[cmdIdx].Fcn(String+pos);
+               }
+               else
+               {
+                       Window_AppendMessage(WINDOW_STATUS, MSG_CLASS_CLIENT, NULL, "Unknown command %s", command);
+               }
+       }
+       else
+       {
+               // Message
+               // - Only send if server is valid and window name is non-empty
+               tServer *srv = Window_GetServer(NULL);
+               if( srv && Window_IsChat(NULL) ) {
+                       Window_AppendMessage(NULL, MSG_CLASS_MESSAGE, Server_GetNick(srv), "%s", String);
+                       Server_SendCommand(srv, "PRIVMSG %s :%s\n", Window_GetName(NULL), String);
+               }
+       }
+       
+       return 0;
+}

UCC git Repository :: git.ucc.asn.au