blob: 948c391a5cafadbda901d0226d4c324a743ea51e [file] [log] [blame]
adamdunkelsa2f3c422004-09-12 20:24:53 +00001/*
2 * Copyright (c) 2004, Adam Dunkels.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the Institute nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * This file is part of the Contiki operating system.
30 *
31 * Author: Adam Dunkels <adam@sics.se>
32 *
oliverschmidted605d12005-05-05 23:32:01 +000033 * $Id: irc.c,v 1.9 2005/05/05 23:32:01 oliverschmidt Exp $
adamdunkelsa2f3c422004-09-12 20:24:53 +000034 */
adamdunkels999e3722004-09-03 08:23:56 +000035
adamdunkels44cce8c2004-09-09 21:05:24 +000036#include "irc-conf.h"
adamdunkels5a2df1c2004-09-01 19:11:42 +000037#include "contiki.h"
adamdunkels999e3722004-09-03 08:23:56 +000038#include "ircc.h"
39
adamdunkels5a2df1c2004-09-01 19:11:42 +000040#include "ctk.h"
41#include "ctk-textedit.h"
42
adamdunkels28c6f902004-09-05 07:13:30 +000043#include "petsciiconv.h"
44
oliverschmidted605d12005-05-05 23:32:01 +000045#include "ctk-textentry-cmdline.h"
46
adamdunkels5a2df1c2004-09-01 19:11:42 +000047#include <string.h>
48
adamdunkels44cce8c2004-09-09 21:05:24 +000049#define LOG_WIDTH IRC_CONF_WIDTH
50#define LOG_HEIGHT IRC_CONF_HEIGHT
51/*
adamdunkels28c6f902004-09-05 07:13:30 +000052#define LOG_WIDTH 78
adamdunkels999e3722004-09-03 08:23:56 +000053#define LOG_HEIGHT 21
adamdunkels44cce8c2004-09-09 21:05:24 +000054*/
adamdunkels5a2df1c2004-09-01 19:11:42 +000055EK_EVENTHANDLER(eventhandler, ev, data);
56EK_PROCESS(p, "IRC client", EK_PRIO_NORMAL,
57 eventhandler, NULL, NULL);
58static ek_id_t id = EK_ID_NONE;
59
60static struct ctk_window window;
61static char log[LOG_WIDTH * LOG_HEIGHT];
adamdunkels28c6f902004-09-05 07:13:30 +000062static char line[LOG_WIDTH*2];
adamdunkels5a2df1c2004-09-01 19:11:42 +000063static struct ctk_label loglabel =
64 {CTK_LABEL(0, 0, LOG_WIDTH, LOG_HEIGHT, log)};
adamdunkels28c6f902004-09-05 07:13:30 +000065static struct ctk_textentry lineedit =
oliverschmidted605d12005-05-05 23:32:01 +000066 {CTK_TEXTENTRY_INPUT(0, LOG_HEIGHT, LOG_WIDTH - 2, 1, line, sizeof(line) - 1,
67 ctk_textentry_cmdline_input)};
adamdunkels5a2df1c2004-09-01 19:11:42 +000068
69static struct ctk_window setupwindow;
70#define SETUPWINDOW_WIDTH 18
71#define SETUPWINDOW_HEIGHT 9
72#define MAX_SERVERLEN 32
73#define MAX_NICKLEN 16
74static u16_t serveraddr[2];
adamdunkels28c6f902004-09-05 07:13:30 +000075static char server[MAX_SERVERLEN + 1];
76static char nick[MAX_NICKLEN + 1];
adamdunkels5a2df1c2004-09-01 19:11:42 +000077static struct ctk_label serverlabel =
78 {CTK_LABEL(1, 1, 11, 1, "IRC server: ")};
79static struct ctk_textentry serverentry =
adamdunkels28c6f902004-09-05 07:13:30 +000080 {CTK_TEXTENTRY(0, 2, 16, 1, server, MAX_SERVERLEN)};
adamdunkels5a2df1c2004-09-01 19:11:42 +000081
82static struct ctk_label nicklabel =
83 {CTK_LABEL(1, 4, 13, 1, "IRC nickname: ")};
84static struct ctk_textentry nickentry =
adamdunkels28c6f902004-09-05 07:13:30 +000085 {CTK_TEXTENTRY(0, 5, 16, 1, nick, MAX_NICKLEN)};
adamdunkels5a2df1c2004-09-01 19:11:42 +000086
adamdunkels5a2df1c2004-09-01 19:11:42 +000087static struct ctk_button connectbutton =
adamdunkels999e3722004-09-03 08:23:56 +000088 {CTK_BUTTON(0, 7, 7, "Connect")};
89static struct ctk_button quitbutton =
90 {CTK_BUTTON(12, 7, 4, "Quit")};
adamdunkels5a2df1c2004-09-01 19:11:42 +000091
92/*static char nick[] = "asdf";
93 static char server[] = "efnet.demon.co.uk";*/
94
95static struct ircc_state s;
96
97/*---------------------------------------------------------------------------*/
98LOADER_INIT_FUNC(irc_init, arg)
99{
100 arg_free(arg);
101
102 if(id == EK_ID_NONE) {
103 id = ek_start(&p);
104 }
105}
106/*---------------------------------------------------------------------------*/
107static void
108quit(void)
109{
adamdunkels999e3722004-09-03 08:23:56 +0000110 ctk_window_close(&window);
111 ctk_window_close(&setupwindow);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000112 ek_exit();
113 id = EK_ID_NONE;
114 LOADER_UNLOAD();
115}
116/*---------------------------------------------------------------------------*/
117void
118ircc_text_output(struct ircc_state *s, char *text1, char *text2)
119{
120 char *ptr;
adamdunkels28c6f902004-09-05 07:13:30 +0000121 int len;
adamdunkels999e3722004-09-03 08:23:56 +0000122
adamdunkels5a2df1c2004-09-01 19:11:42 +0000123 if(text1 == NULL) {
124 text1 = "";
125 }
126
127 if(text2 == NULL) {
128 text2 = "";
129 }
130
131 /* Scroll previous entries upwards */
132 memcpy(log, &log[LOG_WIDTH], LOG_WIDTH * (LOG_HEIGHT - 1));
133
134 ptr = &log[LOG_WIDTH * (LOG_HEIGHT - 1)];
135 len = strlen(text1);
136
137 memset(ptr, 0, LOG_WIDTH);
138 strncpy(ptr, text1, LOG_WIDTH);
adamdunkels28c6f902004-09-05 07:13:30 +0000139 if(len < LOG_WIDTH) {
140 ptr += len;
141 *ptr = ':';
142 ++len;
143 if(LOG_WIDTH - len > 0) {
144 strncpy(ptr + 1, text2, LOG_WIDTH - len);
145 }
146 } else {
147 len = 0;
adamdunkels5a2df1c2004-09-01 19:11:42 +0000148 }
149
adamdunkels28c6f902004-09-05 07:13:30 +0000150 if(strlen(text2) > LOG_WIDTH - len) {
adamdunkels999e3722004-09-03 08:23:56 +0000151 memcpy(log, &log[LOG_WIDTH], LOG_WIDTH * (LOG_HEIGHT - 1));
152 strncpy(&log[LOG_WIDTH * (LOG_HEIGHT - 1)],
adamdunkels28c6f902004-09-05 07:13:30 +0000153 text2 + LOG_WIDTH - len, LOG_WIDTH);
adamdunkels999e3722004-09-03 08:23:56 +0000154 }
adamdunkels5a2df1c2004-09-01 19:11:42 +0000155 CTK_WIDGET_REDRAW(&loglabel);
156
157}
158/*---------------------------------------------------------------------------*/
159static void
160parse_line(void)
161{
162 int i;
163 for(i = 0; i < strlen(line); ++i) {
164 line[i] &= 0x7f;
165 }
166
167
168 if(line[0] == '/') {
adamdunkels999e3722004-09-03 08:23:56 +0000169 if(strncmp(&line[1], "join", 4) == 0) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000170 ircc_join(&s, &line[6]);
171 ircc_text_output(&s, "Join", &line[6]);
adamdunkels999e3722004-09-03 08:23:56 +0000172 } else if(strncmp(&line[1], "list", 4) == 0) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000173 ircc_list(&s);
174 ircc_text_output(&s, "Channel list", "");
adamdunkels999e3722004-09-03 08:23:56 +0000175 } else if(strncmp(&line[1], "part", 4) == 0) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000176 ircc_part(&s);
177 ircc_text_output(&s, "Leaving channel", "");
adamdunkels999e3722004-09-03 08:23:56 +0000178 } else if(strncmp(&line[1], "quit", 4) == 0) {
179 ircc_quit(&s);
adamdunkels44cce8c2004-09-09 21:05:24 +0000180 } else if(strncmp(&line[1], "me", 2) == 0) {
181 petsciiconv_toascii(&line[4], strlen(&line[4]));
182 ircc_actionmsg(&s, &line[4]);
183 ircc_text_output(&s, "*", &line[4]);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000184 } else {
185 ircc_text_output(&s, &line[1], "Not implemented");
186 ircc_sent(&s);
187 }
188 } else {
adamdunkels28c6f902004-09-05 07:13:30 +0000189 petsciiconv_toascii(line, sizeof(line) - 1);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000190 ircc_msg(&s, &line[0]);
191 ircc_text_output(&s, nick, line);
192 }
193
194}
195/*---------------------------------------------------------------------------*/
196void
197ircc_sent(struct ircc_state *s)
198{
adamdunkels28c6f902004-09-05 07:13:30 +0000199 /* ctk_textedit_init(&lineedit);*/
200 CTK_TEXTENTRY_CLEAR(&lineedit);
oliverschmidt33bf9362005-04-28 20:57:36 +0000201 CTK_WIDGET_REDRAW(&lineedit);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000202}
203/*---------------------------------------------------------------------------*/
204EK_EVENTHANDLER(eventhandler, ev, data)
205{
206 ctk_arch_key_t c;
207 u16_t *ipaddr;
208
209 if(ev == EK_EVENT_INIT) {
adamdunkels28c6f902004-09-05 07:13:30 +0000210 /* ctk_textedit_init(&lineedit);*/
211 CTK_TEXTENTRY_CLEAR(&lineedit);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000212 memset(log, 0, sizeof(log));
213 ctk_window_new(&window, LOG_WIDTH, LOG_HEIGHT + 1, "IRC");
214 CTK_WIDGET_ADD(&window, &loglabel);
adamdunkels28c6f902004-09-05 07:13:30 +0000215 /* ctk_textedit_add(&window, &lineedit); */
216 CTK_WIDGET_ADD(&window, &lineedit);
217 CTK_WIDGET_FOCUS(&window, &lineedit);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000218
219 ctk_window_new(&setupwindow, SETUPWINDOW_WIDTH, SETUPWINDOW_HEIGHT,
220 "IRC setup");
221
222 CTK_WIDGET_ADD(&setupwindow, &serverlabel);
223 CTK_WIDGET_ADD(&setupwindow, &serverentry);
224 CTK_WIDGET_ADD(&setupwindow, &nicklabel);
225 CTK_WIDGET_ADD(&setupwindow, &nickentry);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000226 CTK_WIDGET_ADD(&setupwindow, &connectbutton);
adamdunkels999e3722004-09-03 08:23:56 +0000227 CTK_WIDGET_ADD(&setupwindow, &quitbutton);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000228
oliverschmidtb86b0652005-04-24 13:37:42 +0000229 CTK_WIDGET_FOCUS(&setupwindow, &serverentry);
230
adamdunkels5a2df1c2004-09-01 19:11:42 +0000231 ctk_window_open(&setupwindow);
232
adamdunkels28c6f902004-09-05 07:13:30 +0000233 } else if(ev == EK_EVENT_REQUEST_EXIT) {
234 quit();
235 } else if(ev == ctk_signal_window_close) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000236 quit();
237 } else if(ev == tcpip_event) {
238 ircc_appcall(data);
239 } else if(ev == ctk_signal_widget_activate) {
240 if(data == (ek_data_t)&lineedit) {
241 parse_line();
242 } else if(data == (ek_data_t)&quitbutton) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000243 quit();
244 } else if(data == (ek_data_t)&connectbutton) {
245 ctk_window_close(&setupwindow);
246 ctk_window_open(&window);
247 ipaddr = serveraddr;
adamdunkels999e3722004-09-03 08:23:56 +0000248 if(uiplib_ipaddrconv(server, (u8_t *)serveraddr) == 0) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000249 ipaddr = resolv_lookup(server);
250 if(ipaddr == NULL) {
251 resolv_query(server);
252 } else {
253 uip_ipaddr_copy(serveraddr, ipaddr);
254 }
255 }
256 if(ipaddr != NULL) {
257
258 ircc_connect(&s, server, serveraddr, nick);
259 }
260 }
261 } else if(ev == resolv_event_found) {
262
263 ipaddr = resolv_lookup(server);
264 if(ipaddr == NULL) {
265 ircc_text_output(&s, server, "hostname not found");
266 } else {
267 uip_ipaddr_copy(serveraddr, ipaddr);
268 ircc_connect(&s, server, serveraddr, nick);
269 }
270
271 } else if(ev == ctk_signal_keypress) {
272 c = (ctk_arch_key_t)data;
273 if(c == CH_ENTER) {
274 parse_line();
275 } else {
adamdunkels28c6f902004-09-05 07:13:30 +0000276 /* ctk_textedit_eventhandler(&lineedit, ev, data);*/
277 CTK_WIDGET_FOCUS(&window, &lineedit);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000278 }
279 }
280}
281/*---------------------------------------------------------------------------*/
282void
283ircc_closed(struct ircc_state *s)
284{
285 ircc_text_output(s, server, "connection closed");
286}
287/*---------------------------------------------------------------------------*/
288void
289ircc_connected(struct ircc_state *s)
290{
291 ircc_text_output(s, server, "connected");
292}
293/*---------------------------------------------------------------------------*/