Usermode/irc - Rework into multiple files
[tpg/acess2.git] / Usermode / Applications / irc_src / input.c
1 /*
2  */
3 #include "input.h"
4 #include "window.h"
5 #include "server.h"
6 #include <readline.h>
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10  
11 // === PROTOTYPES ===
12 void    Input_FillSelect(int *nfds, fd_set *rfds);
13 void    Input_HandleSelect(int nfds, const fd_set *rfds);
14  int    ParseUserCommand(char *String);
15
16 // === GLOBALS ===
17 tReadline       *gpInput_ReadlineInfo;
18
19 // === CODE ===
20 void Input_FillSelect(int *nfds, fd_set *rfds)
21 {
22         if( !gpInput_ReadlineInfo ) {
23                 gpInput_ReadlineInfo = Readline_Init(1);
24         }
25         
26         FD_SET(0, rfds);
27         if(*nfds < 0+1)
28                 *nfds = 0+1;
29 }
30
31 void Input_HandleSelect(int nfds, const fd_set *rfds)
32 {
33         // User input
34         if(FD_ISSET(0, rfds))
35         {
36                 char    *cmd = Readline_NonBlock(gpInput_ReadlineInfo);
37                 if( cmd )
38                 {
39                         if( cmd[0] )
40                         {
41                                 ParseUserCommand(cmd);
42                         }
43                         free(cmd);
44                         // Prompt
45                         SetCursorPos(giTerminal_Height-1, 1);
46                         printf("\x1B[2K");      // Clear line
47                         printf("[%s]", Window_GetName(NULL));
48                 }
49         }
50 }
51
52 void Cmd_join(char *ArgString)
53 {
54          int    pos=0;
55         char    *channel_name = GetValue(ArgString, &pos);
56         
57         tServer *srv = Window_GetServer(NULL);
58         
59         if( srv )
60         {
61                 Windows_SwitchTo( Window_Create(srv, channel_name) );
62                 Redraw_Screen();
63                 Server_SendCommand(srv, "JOIN :%s", channel_name);
64         }
65 }
66
67 void Cmd_quit(char *ArgString)
68 {
69         const char *quit_message = ArgString;
70         if( quit_message == NULL || quit_message[0] == '\0' )
71                 quit_message = "/quit - Acess2 IRC Client";
72         
73         Servers_CloseAll(quit_message);
74         
75         Exit(NULL);     // NULL = user requested
76 }
77
78 void Cmd_window(char *ArgString)
79 {
80          int    pos = 0;
81         char    *window_id = GetValue(ArgString, &pos);
82          int    window_num = atoi(window_id);
83         
84         if( window_num > 0 )
85         {
86                 // Get `window_num`th window
87                 tWindow *win = Windows_GetByIndex(window_num-1);
88                 if( win )
89                 {
90                         Windows_SwitchTo( win );
91                 }
92                 else
93                 {
94                         // Otherwise, silently ignore
95                 }
96         }
97         else
98         {
99                 window_num = 1;
100                 for( tWindow *win; (win = Windows_GetByIndex(window_num-1)); window_num ++ )
101                 {
102                         Window_AppendMessage(WINDOW_STATUS, MSG_CLASS_CLIENT, NULL, "%i: %s", window_num, Window_GetName(win));
103                 }
104         }
105 }
106
107 const struct {
108         const char *Name;
109         void    (*Fcn)(char *ArgString);
110 } caCommands[] = {
111         {"join", Cmd_join},
112         {"quit", Cmd_quit},
113         {"window", Cmd_window},
114         {"win",    Cmd_window},
115         {"w",      Cmd_window},
116 };
117 const int ciNumCommands = sizeof(caCommands)/sizeof(caCommands[0]);
118
119 /**
120  * \brief Handle a line from the prompt
121  */
122 int ParseUserCommand(char *String)
123 {
124         if( String[0] == '/' )
125         {
126                 char    *command;
127                  int    pos = 0;
128                 
129                 command = GetValue(String, &pos)+1;
130
131                 // TODO: Prefix matches
132                  int    cmdIdx = -1;
133                 for( int i = 0; i < ciNumCommands; i ++ )
134                 {
135                         if( strcmp(command, caCommands[i].Name) == 0 ) {
136                                 cmdIdx = i;
137                                 break;
138                         }
139                 }
140                 if( cmdIdx != -1 ) {
141                         caCommands[cmdIdx].Fcn(String+pos);
142                 }
143                 else
144                 {
145                         Window_AppendMessage(WINDOW_STATUS, MSG_CLASS_CLIENT, NULL, "Unknown command %s", command);
146                 }
147         }
148         else
149         {
150                 // Message
151                 // - Only send if server is valid and window name is non-empty
152                 tServer *srv = Window_GetServer(NULL);
153                 if( srv && Window_IsChat(NULL) ) {
154                         Window_AppendMessage(NULL, MSG_CLASS_MESSAGE, Server_GetNick(srv), "%s", String);
155                         Server_SendCommand(srv, "PRIVMSG %s :%s\n", Window_GetName(NULL), String);
156                 }
157         }
158         
159         return 0;
160 }

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