blob: f348001c999f5c0944a2c4fba2ca01393fcab67d [file] [log] [blame]
adamdunkels999e3722004-09-03 08:23:56 +00001
adamdunkels44cce8c2004-09-09 21:05:24 +00002#include "irc-conf.h"
adamdunkels5a2df1c2004-09-01 19:11:42 +00003#include "contiki.h"
adamdunkels999e3722004-09-03 08:23:56 +00004#include "ircc.h"
5
adamdunkels5a2df1c2004-09-01 19:11:42 +00006#include "ctk.h"
7#include "ctk-textedit.h"
8
adamdunkels28c6f902004-09-05 07:13:30 +00009#include "petsciiconv.h"
10
adamdunkels5a2df1c2004-09-01 19:11:42 +000011#include <string.h>
12
adamdunkels44cce8c2004-09-09 21:05:24 +000013#define LOG_WIDTH IRC_CONF_WIDTH
14#define LOG_HEIGHT IRC_CONF_HEIGHT
15/*
adamdunkels28c6f902004-09-05 07:13:30 +000016#define LOG_WIDTH 78
adamdunkels999e3722004-09-03 08:23:56 +000017#define LOG_HEIGHT 21
adamdunkels44cce8c2004-09-09 21:05:24 +000018*/
adamdunkels5a2df1c2004-09-01 19:11:42 +000019EK_EVENTHANDLER(eventhandler, ev, data);
20EK_PROCESS(p, "IRC client", EK_PRIO_NORMAL,
21 eventhandler, NULL, NULL);
22static ek_id_t id = EK_ID_NONE;
23
24static struct ctk_window window;
25static char log[LOG_WIDTH * LOG_HEIGHT];
adamdunkels28c6f902004-09-05 07:13:30 +000026static char line[LOG_WIDTH*2];
adamdunkels5a2df1c2004-09-01 19:11:42 +000027static struct ctk_label loglabel =
28 {CTK_LABEL(0, 0, LOG_WIDTH, LOG_HEIGHT, log)};
adamdunkels28c6f902004-09-05 07:13:30 +000029static struct ctk_textentry lineedit =
30 {CTK_TEXTENTRY(0, LOG_HEIGHT, LOG_WIDTH - 2, 1, line, sizeof(line) - 1)};
adamdunkels5a2df1c2004-09-01 19:11:42 +000031
32static struct ctk_window setupwindow;
33#define SETUPWINDOW_WIDTH 18
34#define SETUPWINDOW_HEIGHT 9
35#define MAX_SERVERLEN 32
36#define MAX_NICKLEN 16
37static u16_t serveraddr[2];
adamdunkels28c6f902004-09-05 07:13:30 +000038static char server[MAX_SERVERLEN + 1];
39static char nick[MAX_NICKLEN + 1];
adamdunkels5a2df1c2004-09-01 19:11:42 +000040static struct ctk_label serverlabel =
41 {CTK_LABEL(1, 1, 11, 1, "IRC server: ")};
42static struct ctk_textentry serverentry =
adamdunkels28c6f902004-09-05 07:13:30 +000043 {CTK_TEXTENTRY(0, 2, 16, 1, server, MAX_SERVERLEN)};
adamdunkels5a2df1c2004-09-01 19:11:42 +000044
45static struct ctk_label nicklabel =
46 {CTK_LABEL(1, 4, 13, 1, "IRC nickname: ")};
47static struct ctk_textentry nickentry =
adamdunkels28c6f902004-09-05 07:13:30 +000048 {CTK_TEXTENTRY(0, 5, 16, 1, nick, MAX_NICKLEN)};
adamdunkels5a2df1c2004-09-01 19:11:42 +000049
adamdunkels5a2df1c2004-09-01 19:11:42 +000050static struct ctk_button connectbutton =
adamdunkels999e3722004-09-03 08:23:56 +000051 {CTK_BUTTON(0, 7, 7, "Connect")};
52static struct ctk_button quitbutton =
53 {CTK_BUTTON(12, 7, 4, "Quit")};
adamdunkels5a2df1c2004-09-01 19:11:42 +000054
55/*static char nick[] = "asdf";
56 static char server[] = "efnet.demon.co.uk";*/
57
58static struct ircc_state s;
59
60/*---------------------------------------------------------------------------*/
61LOADER_INIT_FUNC(irc_init, arg)
62{
63 arg_free(arg);
64
65 if(id == EK_ID_NONE) {
66 id = ek_start(&p);
67 }
68}
69/*---------------------------------------------------------------------------*/
70static void
71quit(void)
72{
adamdunkels999e3722004-09-03 08:23:56 +000073 ctk_window_close(&window);
74 ctk_window_close(&setupwindow);
adamdunkels5a2df1c2004-09-01 19:11:42 +000075 ek_exit();
76 id = EK_ID_NONE;
77 LOADER_UNLOAD();
78}
79/*---------------------------------------------------------------------------*/
80void
81ircc_text_output(struct ircc_state *s, char *text1, char *text2)
82{
83 char *ptr;
adamdunkels28c6f902004-09-05 07:13:30 +000084 int len;
adamdunkels999e3722004-09-03 08:23:56 +000085
adamdunkels5a2df1c2004-09-01 19:11:42 +000086 if(text1 == NULL) {
87 text1 = "";
88 }
89
90 if(text2 == NULL) {
91 text2 = "";
92 }
93
94 /* Scroll previous entries upwards */
95 memcpy(log, &log[LOG_WIDTH], LOG_WIDTH * (LOG_HEIGHT - 1));
96
97 ptr = &log[LOG_WIDTH * (LOG_HEIGHT - 1)];
98 len = strlen(text1);
99
100 memset(ptr, 0, LOG_WIDTH);
101 strncpy(ptr, text1, LOG_WIDTH);
adamdunkels28c6f902004-09-05 07:13:30 +0000102 if(len < LOG_WIDTH) {
103 ptr += len;
104 *ptr = ':';
105 ++len;
106 if(LOG_WIDTH - len > 0) {
107 strncpy(ptr + 1, text2, LOG_WIDTH - len);
108 }
109 } else {
110 len = 0;
adamdunkels5a2df1c2004-09-01 19:11:42 +0000111 }
112
adamdunkels28c6f902004-09-05 07:13:30 +0000113 if(strlen(text2) > LOG_WIDTH - len) {
adamdunkels999e3722004-09-03 08:23:56 +0000114 memcpy(log, &log[LOG_WIDTH], LOG_WIDTH * (LOG_HEIGHT - 1));
115 strncpy(&log[LOG_WIDTH * (LOG_HEIGHT - 1)],
adamdunkels28c6f902004-09-05 07:13:30 +0000116 text2 + LOG_WIDTH - len, LOG_WIDTH);
adamdunkels999e3722004-09-03 08:23:56 +0000117 }
adamdunkels5a2df1c2004-09-01 19:11:42 +0000118 CTK_WIDGET_REDRAW(&loglabel);
119
120}
121/*---------------------------------------------------------------------------*/
122static void
123parse_line(void)
124{
125 int i;
126 for(i = 0; i < strlen(line); ++i) {
127 line[i] &= 0x7f;
128 }
129
130
131 if(line[0] == '/') {
adamdunkels999e3722004-09-03 08:23:56 +0000132 if(strncmp(&line[1], "join", 4) == 0) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000133 ircc_join(&s, &line[6]);
134 ircc_text_output(&s, "Join", &line[6]);
adamdunkels999e3722004-09-03 08:23:56 +0000135 } else if(strncmp(&line[1], "list", 4) == 0) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000136 ircc_list(&s);
137 ircc_text_output(&s, "Channel list", "");
adamdunkels999e3722004-09-03 08:23:56 +0000138 } else if(strncmp(&line[1], "part", 4) == 0) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000139 ircc_part(&s);
140 ircc_text_output(&s, "Leaving channel", "");
adamdunkels999e3722004-09-03 08:23:56 +0000141 } else if(strncmp(&line[1], "quit", 4) == 0) {
142 ircc_quit(&s);
adamdunkels44cce8c2004-09-09 21:05:24 +0000143 } else if(strncmp(&line[1], "me", 2) == 0) {
144 petsciiconv_toascii(&line[4], strlen(&line[4]));
145 ircc_actionmsg(&s, &line[4]);
146 ircc_text_output(&s, "*", &line[4]);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000147 } else {
148 ircc_text_output(&s, &line[1], "Not implemented");
149 ircc_sent(&s);
150 }
151 } else {
adamdunkels28c6f902004-09-05 07:13:30 +0000152 petsciiconv_toascii(line, sizeof(line) - 1);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000153 ircc_msg(&s, &line[0]);
154 ircc_text_output(&s, nick, line);
155 }
156
157}
158/*---------------------------------------------------------------------------*/
159void
160ircc_sent(struct ircc_state *s)
161{
162 memset(line, 0, sizeof(line));
adamdunkels28c6f902004-09-05 07:13:30 +0000163 /* ctk_textedit_init(&lineedit);*/
164 CTK_TEXTENTRY_CLEAR(&lineedit);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000165 CTK_WIDGET_REDRAW(&lineedit);
adamdunkels44cce8c2004-09-09 21:05:24 +0000166 CTK_WIDGET_FOCUS(&window, &lineedit);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000167}
168/*---------------------------------------------------------------------------*/
169EK_EVENTHANDLER(eventhandler, ev, data)
170{
171 ctk_arch_key_t c;
172 u16_t *ipaddr;
173
174 if(ev == EK_EVENT_INIT) {
adamdunkels28c6f902004-09-05 07:13:30 +0000175 /* ctk_textedit_init(&lineedit);*/
176 CTK_TEXTENTRY_CLEAR(&lineedit);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000177 memset(line, 0, sizeof(line));
178 memset(log, 0, sizeof(log));
179 ctk_window_new(&window, LOG_WIDTH, LOG_HEIGHT + 1, "IRC");
180 CTK_WIDGET_ADD(&window, &loglabel);
adamdunkels28c6f902004-09-05 07:13:30 +0000181 /* ctk_textedit_add(&window, &lineedit); */
182 CTK_WIDGET_ADD(&window, &lineedit);
183 CTK_WIDGET_FOCUS(&window, &lineedit);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000184
185 ctk_window_new(&setupwindow, SETUPWINDOW_WIDTH, SETUPWINDOW_HEIGHT,
186 "IRC setup");
187
188 CTK_WIDGET_ADD(&setupwindow, &serverlabel);
189 CTK_WIDGET_ADD(&setupwindow, &serverentry);
190 CTK_WIDGET_ADD(&setupwindow, &nicklabel);
191 CTK_WIDGET_ADD(&setupwindow, &nickentry);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000192 CTK_WIDGET_ADD(&setupwindow, &connectbutton);
adamdunkels999e3722004-09-03 08:23:56 +0000193 CTK_WIDGET_ADD(&setupwindow, &quitbutton);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000194
195 ctk_window_open(&setupwindow);
196
adamdunkels28c6f902004-09-05 07:13:30 +0000197 } else if(ev == EK_EVENT_REQUEST_EXIT) {
198 quit();
199 } else if(ev == ctk_signal_window_close) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000200 quit();
201 } else if(ev == tcpip_event) {
202 ircc_appcall(data);
203 } else if(ev == ctk_signal_widget_activate) {
204 if(data == (ek_data_t)&lineedit) {
205 parse_line();
206 } else if(data == (ek_data_t)&quitbutton) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000207 quit();
208 } else if(data == (ek_data_t)&connectbutton) {
209 ctk_window_close(&setupwindow);
210 ctk_window_open(&window);
211 ipaddr = serveraddr;
adamdunkels999e3722004-09-03 08:23:56 +0000212 if(uiplib_ipaddrconv(server, (u8_t *)serveraddr) == 0) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000213 ipaddr = resolv_lookup(server);
214 if(ipaddr == NULL) {
215 resolv_query(server);
216 } else {
217 uip_ipaddr_copy(serveraddr, ipaddr);
218 }
219 }
220 if(ipaddr != NULL) {
221
222 ircc_connect(&s, server, serveraddr, nick);
223 }
224 }
225 } else if(ev == resolv_event_found) {
226
227 ipaddr = resolv_lookup(server);
228 if(ipaddr == NULL) {
229 ircc_text_output(&s, server, "hostname not found");
230 } else {
231 uip_ipaddr_copy(serveraddr, ipaddr);
232 ircc_connect(&s, server, serveraddr, nick);
233 }
234
235 } else if(ev == ctk_signal_keypress) {
236 c = (ctk_arch_key_t)data;
237 if(c == CH_ENTER) {
238 parse_line();
239 } else {
adamdunkels28c6f902004-09-05 07:13:30 +0000240 /* ctk_textedit_eventhandler(&lineedit, ev, data);*/
241 CTK_WIDGET_FOCUS(&window, &lineedit);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000242 }
243 }
244}
245/*---------------------------------------------------------------------------*/
246void
247ircc_closed(struct ircc_state *s)
248{
249 ircc_text_output(s, server, "connection closed");
250}
251/*---------------------------------------------------------------------------*/
252void
253ircc_connected(struct ircc_state *s)
254{
255 ircc_text_output(s, server, "connected");
256}
257/*---------------------------------------------------------------------------*/