blob: 03a951a0eccdc39e5235a390b211d648000c725e [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 *
oliverschmidt33bf9362005-04-28 20:57:36 +000033 * $Id: irc.c,v 1.8 2005/04/28 20:57:36 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
adamdunkels5a2df1c2004-09-01 19:11:42 +000045#include <string.h>
46
adamdunkels44cce8c2004-09-09 21:05:24 +000047#define LOG_WIDTH IRC_CONF_WIDTH
48#define LOG_HEIGHT IRC_CONF_HEIGHT
49/*
adamdunkels28c6f902004-09-05 07:13:30 +000050#define LOG_WIDTH 78
adamdunkels999e3722004-09-03 08:23:56 +000051#define LOG_HEIGHT 21
adamdunkels44cce8c2004-09-09 21:05:24 +000052*/
adamdunkels5a2df1c2004-09-01 19:11:42 +000053EK_EVENTHANDLER(eventhandler, ev, data);
54EK_PROCESS(p, "IRC client", EK_PRIO_NORMAL,
55 eventhandler, NULL, NULL);
56static ek_id_t id = EK_ID_NONE;
57
58static struct ctk_window window;
59static char log[LOG_WIDTH * LOG_HEIGHT];
adamdunkels28c6f902004-09-05 07:13:30 +000060static char line[LOG_WIDTH*2];
adamdunkels5a2df1c2004-09-01 19:11:42 +000061static struct ctk_label loglabel =
62 {CTK_LABEL(0, 0, LOG_WIDTH, LOG_HEIGHT, log)};
adamdunkels28c6f902004-09-05 07:13:30 +000063static struct ctk_textentry lineedit =
64 {CTK_TEXTENTRY(0, LOG_HEIGHT, LOG_WIDTH - 2, 1, line, sizeof(line) - 1)};
adamdunkels5a2df1c2004-09-01 19:11:42 +000065
66static struct ctk_window setupwindow;
67#define SETUPWINDOW_WIDTH 18
68#define SETUPWINDOW_HEIGHT 9
69#define MAX_SERVERLEN 32
70#define MAX_NICKLEN 16
71static u16_t serveraddr[2];
adamdunkels28c6f902004-09-05 07:13:30 +000072static char server[MAX_SERVERLEN + 1];
73static char nick[MAX_NICKLEN + 1];
adamdunkels5a2df1c2004-09-01 19:11:42 +000074static struct ctk_label serverlabel =
75 {CTK_LABEL(1, 1, 11, 1, "IRC server: ")};
76static struct ctk_textentry serverentry =
adamdunkels28c6f902004-09-05 07:13:30 +000077 {CTK_TEXTENTRY(0, 2, 16, 1, server, MAX_SERVERLEN)};
adamdunkels5a2df1c2004-09-01 19:11:42 +000078
79static struct ctk_label nicklabel =
80 {CTK_LABEL(1, 4, 13, 1, "IRC nickname: ")};
81static struct ctk_textentry nickentry =
adamdunkels28c6f902004-09-05 07:13:30 +000082 {CTK_TEXTENTRY(0, 5, 16, 1, nick, MAX_NICKLEN)};
adamdunkels5a2df1c2004-09-01 19:11:42 +000083
adamdunkels5a2df1c2004-09-01 19:11:42 +000084static struct ctk_button connectbutton =
adamdunkels999e3722004-09-03 08:23:56 +000085 {CTK_BUTTON(0, 7, 7, "Connect")};
86static struct ctk_button quitbutton =
87 {CTK_BUTTON(12, 7, 4, "Quit")};
adamdunkels5a2df1c2004-09-01 19:11:42 +000088
89/*static char nick[] = "asdf";
90 static char server[] = "efnet.demon.co.uk";*/
91
92static struct ircc_state s;
93
94/*---------------------------------------------------------------------------*/
95LOADER_INIT_FUNC(irc_init, arg)
96{
97 arg_free(arg);
98
99 if(id == EK_ID_NONE) {
100 id = ek_start(&p);
101 }
102}
103/*---------------------------------------------------------------------------*/
104static void
105quit(void)
106{
adamdunkels999e3722004-09-03 08:23:56 +0000107 ctk_window_close(&window);
108 ctk_window_close(&setupwindow);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000109 ek_exit();
110 id = EK_ID_NONE;
111 LOADER_UNLOAD();
112}
113/*---------------------------------------------------------------------------*/
114void
115ircc_text_output(struct ircc_state *s, char *text1, char *text2)
116{
117 char *ptr;
adamdunkels28c6f902004-09-05 07:13:30 +0000118 int len;
adamdunkels999e3722004-09-03 08:23:56 +0000119
adamdunkels5a2df1c2004-09-01 19:11:42 +0000120 if(text1 == NULL) {
121 text1 = "";
122 }
123
124 if(text2 == NULL) {
125 text2 = "";
126 }
127
128 /* Scroll previous entries upwards */
129 memcpy(log, &log[LOG_WIDTH], LOG_WIDTH * (LOG_HEIGHT - 1));
130
131 ptr = &log[LOG_WIDTH * (LOG_HEIGHT - 1)];
132 len = strlen(text1);
133
134 memset(ptr, 0, LOG_WIDTH);
135 strncpy(ptr, text1, LOG_WIDTH);
adamdunkels28c6f902004-09-05 07:13:30 +0000136 if(len < LOG_WIDTH) {
137 ptr += len;
138 *ptr = ':';
139 ++len;
140 if(LOG_WIDTH - len > 0) {
141 strncpy(ptr + 1, text2, LOG_WIDTH - len);
142 }
143 } else {
144 len = 0;
adamdunkels5a2df1c2004-09-01 19:11:42 +0000145 }
146
adamdunkels28c6f902004-09-05 07:13:30 +0000147 if(strlen(text2) > LOG_WIDTH - len) {
adamdunkels999e3722004-09-03 08:23:56 +0000148 memcpy(log, &log[LOG_WIDTH], LOG_WIDTH * (LOG_HEIGHT - 1));
149 strncpy(&log[LOG_WIDTH * (LOG_HEIGHT - 1)],
adamdunkels28c6f902004-09-05 07:13:30 +0000150 text2 + LOG_WIDTH - len, LOG_WIDTH);
adamdunkels999e3722004-09-03 08:23:56 +0000151 }
adamdunkels5a2df1c2004-09-01 19:11:42 +0000152 CTK_WIDGET_REDRAW(&loglabel);
153
154}
155/*---------------------------------------------------------------------------*/
156static void
157parse_line(void)
158{
159 int i;
160 for(i = 0; i < strlen(line); ++i) {
161 line[i] &= 0x7f;
162 }
163
164
165 if(line[0] == '/') {
adamdunkels999e3722004-09-03 08:23:56 +0000166 if(strncmp(&line[1], "join", 4) == 0) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000167 ircc_join(&s, &line[6]);
168 ircc_text_output(&s, "Join", &line[6]);
adamdunkels999e3722004-09-03 08:23:56 +0000169 } else if(strncmp(&line[1], "list", 4) == 0) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000170 ircc_list(&s);
171 ircc_text_output(&s, "Channel list", "");
adamdunkels999e3722004-09-03 08:23:56 +0000172 } else if(strncmp(&line[1], "part", 4) == 0) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000173 ircc_part(&s);
174 ircc_text_output(&s, "Leaving channel", "");
adamdunkels999e3722004-09-03 08:23:56 +0000175 } else if(strncmp(&line[1], "quit", 4) == 0) {
176 ircc_quit(&s);
adamdunkels44cce8c2004-09-09 21:05:24 +0000177 } else if(strncmp(&line[1], "me", 2) == 0) {
178 petsciiconv_toascii(&line[4], strlen(&line[4]));
179 ircc_actionmsg(&s, &line[4]);
180 ircc_text_output(&s, "*", &line[4]);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000181 } else {
182 ircc_text_output(&s, &line[1], "Not implemented");
183 ircc_sent(&s);
184 }
185 } else {
adamdunkels28c6f902004-09-05 07:13:30 +0000186 petsciiconv_toascii(line, sizeof(line) - 1);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000187 ircc_msg(&s, &line[0]);
188 ircc_text_output(&s, nick, line);
189 }
190
191}
192/*---------------------------------------------------------------------------*/
193void
194ircc_sent(struct ircc_state *s)
195{
oliverschmidt33bf9362005-04-28 20:57:36 +0000196 struct ctk_widget *focused;
197
adamdunkels28c6f902004-09-05 07:13:30 +0000198 /* ctk_textedit_init(&lineedit);*/
199 CTK_TEXTENTRY_CLEAR(&lineedit);
oliverschmidt33bf9362005-04-28 20:57:36 +0000200 focused = window.focused;
adamdunkels44cce8c2004-09-09 21:05:24 +0000201 CTK_WIDGET_FOCUS(&window, &lineedit);
oliverschmidt33bf9362005-04-28 20:57:36 +0000202 CTK_WIDGET_REDRAW(focused);
203 CTK_WIDGET_REDRAW(&lineedit);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000204}
205/*---------------------------------------------------------------------------*/
206EK_EVENTHANDLER(eventhandler, ev, data)
207{
208 ctk_arch_key_t c;
209 u16_t *ipaddr;
210
211 if(ev == EK_EVENT_INIT) {
adamdunkels28c6f902004-09-05 07:13:30 +0000212 /* ctk_textedit_init(&lineedit);*/
213 CTK_TEXTENTRY_CLEAR(&lineedit);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000214 memset(log, 0, sizeof(log));
215 ctk_window_new(&window, LOG_WIDTH, LOG_HEIGHT + 1, "IRC");
216 CTK_WIDGET_ADD(&window, &loglabel);
adamdunkels28c6f902004-09-05 07:13:30 +0000217 /* ctk_textedit_add(&window, &lineedit); */
218 CTK_WIDGET_ADD(&window, &lineedit);
219 CTK_WIDGET_FOCUS(&window, &lineedit);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000220
221 ctk_window_new(&setupwindow, SETUPWINDOW_WIDTH, SETUPWINDOW_HEIGHT,
222 "IRC setup");
223
224 CTK_WIDGET_ADD(&setupwindow, &serverlabel);
225 CTK_WIDGET_ADD(&setupwindow, &serverentry);
226 CTK_WIDGET_ADD(&setupwindow, &nicklabel);
227 CTK_WIDGET_ADD(&setupwindow, &nickentry);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000228 CTK_WIDGET_ADD(&setupwindow, &connectbutton);
adamdunkels999e3722004-09-03 08:23:56 +0000229 CTK_WIDGET_ADD(&setupwindow, &quitbutton);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000230
oliverschmidtb86b0652005-04-24 13:37:42 +0000231 CTK_WIDGET_FOCUS(&setupwindow, &serverentry);
232
adamdunkels5a2df1c2004-09-01 19:11:42 +0000233 ctk_window_open(&setupwindow);
234
adamdunkels28c6f902004-09-05 07:13:30 +0000235 } else if(ev == EK_EVENT_REQUEST_EXIT) {
236 quit();
237 } else if(ev == ctk_signal_window_close) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000238 quit();
239 } else if(ev == tcpip_event) {
240 ircc_appcall(data);
241 } else if(ev == ctk_signal_widget_activate) {
242 if(data == (ek_data_t)&lineedit) {
243 parse_line();
244 } else if(data == (ek_data_t)&quitbutton) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000245 quit();
246 } else if(data == (ek_data_t)&connectbutton) {
247 ctk_window_close(&setupwindow);
248 ctk_window_open(&window);
249 ipaddr = serveraddr;
adamdunkels999e3722004-09-03 08:23:56 +0000250 if(uiplib_ipaddrconv(server, (u8_t *)serveraddr) == 0) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000251 ipaddr = resolv_lookup(server);
252 if(ipaddr == NULL) {
253 resolv_query(server);
254 } else {
255 uip_ipaddr_copy(serveraddr, ipaddr);
256 }
257 }
258 if(ipaddr != NULL) {
259
260 ircc_connect(&s, server, serveraddr, nick);
261 }
262 }
263 } else if(ev == resolv_event_found) {
264
265 ipaddr = resolv_lookup(server);
266 if(ipaddr == NULL) {
267 ircc_text_output(&s, server, "hostname not found");
268 } else {
269 uip_ipaddr_copy(serveraddr, ipaddr);
270 ircc_connect(&s, server, serveraddr, nick);
271 }
272
273 } else if(ev == ctk_signal_keypress) {
274 c = (ctk_arch_key_t)data;
275 if(c == CH_ENTER) {
276 parse_line();
277 } else {
adamdunkels28c6f902004-09-05 07:13:30 +0000278 /* ctk_textedit_eventhandler(&lineedit, ev, data);*/
279 CTK_WIDGET_FOCUS(&window, &lineedit);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000280 }
281 }
282}
283/*---------------------------------------------------------------------------*/
284void
285ircc_closed(struct ircc_state *s)
286{
287 ircc_text_output(s, server, "connection closed");
288}
289/*---------------------------------------------------------------------------*/
290void
291ircc_connected(struct ircc_state *s)
292{
293 ircc_text_output(s, server, "connected");
294}
295/*---------------------------------------------------------------------------*/