b99935c05e6560b841884c68a3527c194e0362eb
[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);
46                         printf("\x1B[2K");      // Clear line
47                         int prompt_len = printf("[%s] ", Window_GetName(NULL));
48                         SetCursorPos(giTerminal_Height, prompt_len+1);
49                         fflush(stdout);
50                 }
51         }
52 }
53
54 void Cmd_join(char *ArgString)
55 {
56          int    pos=0;
57         char    *channel_name = GetValue(ArgString, &pos);
58         
59         tServer *srv = Window_GetServer(NULL);
60         
61         if( srv )
62         {
63                 Windows_SwitchTo( Window_Create(srv, channel_name) );
64                 Redraw_Screen();
65                 Server_SendCommand(srv, "JOIN :%s", channel_name);
66         }
67 }
68
69 void Cmd_quit(char *ArgString)
70 {
71         const char *quit_message = ArgString;
72         if( quit_message == NULL || quit_message[0] == '\0' )
73                 quit_message = "/quit - Acess2 IRC Client";
74         
75         Servers_CloseAll(quit_message);
76         
77         Exit(NULL);     // NULL = user requested
78 }
79
80 void Cmd_window(char *ArgString)
81 {
82          int    pos = 0;
83         char    *window_id = GetValue(ArgString, &pos);
84          int    window_num = atoi(window_id);
85         
86         if( window_num > 0 )
87         {
88                 // Get `window_num`th window
89                 tWindow *win = Windows_GetByIndex(window_num-1);
90                 if( win )
91                 {
92                         Windows_SwitchTo( win );
93                 }
94                 else
95                 {
96                         // Otherwise, silently ignore
97                 }
98         }
99         else
100         {
101                 window_num = 1;
102                 for( tWindow *win; (win = Windows_GetByIndex(window_num-1)); window_num ++ )
103                 {
104                         Window_AppendMessage(WINDOW_STATUS, MSG_CLASS_CLIENT, NULL, "%i: %s", window_num, Window_GetName(win));
105                 }
106         }
107 }
108
109 void Cmd_me(char *ArgString)
110 {
111         tServer *srv = Window_GetServer(NULL);
112         if( srv && Window_IsChat(NULL) ) {
113                 Window_AppendMessage(NULL, MSG_CLASS_ACTION, Server_GetNick(srv), "%s", ArgString);
114                 Server_SendCommand(srv, "PRIVMSG %s :\1ACTION %s\1\n", Window_GetName(NULL), ArgString);
115         }
116 }
117
118 const struct {
119         const char *Name;
120         void    (*Fcn)(char *ArgString);
121 } caCommands[] = {
122         {"join", Cmd_join},
123         {"quit", Cmd_quit},
124         {"window", Cmd_window},
125         {"win",    Cmd_window},
126         {"w",      Cmd_window},
127 };
128 const int ciNumCommands = sizeof(caCommands)/sizeof(caCommands[0]);
129
130 /**
131  * \brief Handle a line from the prompt
132  */
133 int ParseUserCommand(char *String)
134 {
135         if( String[0] == '/' )
136         {
137                 char    *command;
138                  int    pos = 0;
139                 
140                 command = GetValue(String, &pos)+1;
141
142                 // TODO: Prefix matches
143                  int    cmdIdx = -1;
144                 for( int i = 0; i < ciNumCommands; i ++ )
145                 {
146                         if( strcmp(command, caCommands[i].Name) == 0 ) {
147                                 cmdIdx = i;
148                                 break;
149                         }
150                 }
151                 if( cmdIdx != -1 ) {
152                         caCommands[cmdIdx].Fcn(String+pos);
153                 }
154                 else
155                 {
156                         Window_AppendMessage(WINDOW_STATUS, MSG_CLASS_CLIENT, NULL, "Unknown command %s", command);
157                 }
158         }
159         else
160         {
161                 // Message
162                 // - Only send if server is valid and window name is non-empty
163                 tServer *srv = Window_GetServer(NULL);
164                 if( srv && Window_IsChat(NULL) ) {
165                         Window_AppendMessage(NULL, MSG_CLASS_MESSAGE, Server_GetNick(srv), "%s", String);
166                         Server_SendCommand(srv, "PRIVMSG %s :%s\n", Window_GetName(NULL), String);
167                 }
168         }
169         
170         return 0;
171 }

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