diff options
Diffstat (limited to 'src/irc.c')
| -rw-r--r-- | src/irc.c | 471 |
1 files changed, 231 insertions, 240 deletions
@@ -1,13 +1,11 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <ctype.h> #include "irc.h" #include "screen.h" #include "edbox.h" #include "numerics.h" -#include "keyclick.h" #include <atari.h> #include <conio.h> @@ -15,6 +13,10 @@ #include "config.h" #include "indic8.h" #include "complete.h" +#include "keytab.h" +#include "kgetc.h" +#include "streq.h" +#include "timers.h" #ifndef VERSION #define VERSION "?????" @@ -24,14 +26,17 @@ char *msg_src, *msg_cmd, *msg_dest, *msg_text; char *msg_args[MAX_MSG_ARGS]; -int msg_argcount; +char msg_argcount; char irc_away = 0; char bell_type; char hide_motd; +char start_latch = 0; +char new_scr_status; +char need_rejoin; +char self_src; static char msgbuf[MAX_MSG] = { 0 }; -static char *msg; /* with source removed */ static int msgbuf_len = 0; static char regged = 0, hilite = 0; @@ -44,6 +49,9 @@ char last_chan[33]; /* without a screen */ static int minutes, last_read_min; +/* see pollkbd.s */ +extern void poll_keyboard(void); + /* static void join_channel(void) { txbuf_set_str2("JOIN ", channel); @@ -52,7 +60,7 @@ static void join_channel(void) { */ static void send_nick(void) { - txbuf_set_str2("NICK ", conf->nick); + txbuf_set_str2("NICK ", config.nick); txbuf_send(); } @@ -64,15 +72,8 @@ static void print_reason(void) { scr_eol_active(); } -static void do_pong(void) { - if(conf->show_ping) - scr_print_server("PING/PONG\n"); - txbuf_set_str2("PONG ", msg_args[0]); - txbuf_send(); -} - static void bold(void) { - scr_print_active("\x02"); + scr_putc_active('\x02'); } static void hilite_bold(void) { @@ -82,29 +83,29 @@ static void hilite_bold(void) { static void do_chan_nick(void) { if(hilite) { bell(); - scr_hilite_active(); + new_scr_status = SCR_HILITE; } hilite_bold(); - scr_print_active("<"); + scr_putc_active('<'); hilite_bold(); scr_print_active(msg_src); if(scr_active == SCR_SERVER) { /* if we don't have a window for it */ - scr_print_active("/"); + scr_putc_active('/'); scr_print_active(msg_dest); } hilite_bold(); - scr_print_active(">"); + scr_putc_active('>'); hilite_bold(); - scr_print_active(" "); + scr_putc_active(' '); } static void do_priv_nick(void) { if(msg_src) { - scr_print_active("*"); + scr_putc_active('*'); scr_print_active(msg_src); scr_print_active("* "); - scr_hilite_active(); + new_scr_status = SCR_HILITE; bell(); } } @@ -113,43 +114,37 @@ static void do_priv_nick(void) { nobody's ping time will ever be more than 9 minutes. anyone that lagged will have been disconnected from the server already. if this assumption turns out to be false, the ping time displayed - will be wrong (module ~9 mins). I don't think it's ever going to be + will be wrong (modulo ~9 mins). I don't think it's ever going to be a real problem. Why do it this way? Because using longs instead of ints bloats the - code by 778 bytes! */ + code by 778 bytes! + note to self: using a div_t and div() seemed like it might make + the compiled code smaller, but it grew by ~50 bytes. avoid. + */ static void print_ping_time(char *p) { static unsigned int now, pingtime; static unsigned int sec, frac; now = read_rtclok(); - pingtime = (unsigned int)atoi(p); + pingtime = (unsigned int)a2uint(p); /* correct for rtclock rollover (every ~9 mins) */ if(now < pingtime) now |= 0x8000; pingtime = now - pingtime; - sec = pingtime / hz; - frac = pingtime % hz; - frac *= 1000; - frac /= (hz * 10); + sec = pingtime / timers.hz; + frac = pingtime % timers.hz; + frac *= 100; + frac /= timers.hz; scr_print_active("*** "); scr_print_active(msg_src); scr_print_active(" lag: "); - itoa(sec, numbuf, 10); - scr_print_active(numbuf); - scr_print_active("."); - itoa(frac, numbuf, 10); - scr_print_active(numbuf); - scr_print_active(" sec"); - - /* - // for debugging: - scr_print_active(" "); - itoa(pingtime, numbuf, 10); - scr_print_active(numbuf); - */ + scr_act_printnum(sec); + scr_putc_active('.'); + scr_act_printnum(frac); + scr_putc_active('s'); } static void do_server_pong(void) { @@ -159,8 +154,12 @@ static void do_server_pong(void) { scr_eol_active(); } +static void print_ctcp(void) { + scr_print_active("*** CTCP "); +} + /* FIXME: this isn't very fast */ -static void do_ctcp(int is_notice) { +static void do_ctcp(char is_notice) { static char *p, *ctcp_type, *resp; resp = 0; @@ -180,9 +179,9 @@ static void do_ctcp(int is_notice) { if(p && streq_i(ctcp_type, "PING")) { print_ping_time(p); } else { - scr_print_active("*** CTCP "); + print_ctcp(); scr_print_active(ctcp_type); - scr_print_active(" response from "); + scr_print_active(" resp from "); scr_print_active(msg_src); if(p) { scr_print_active(": "); @@ -195,15 +194,15 @@ static void do_ctcp(int is_notice) { if(streq_i(ctcp_type, "ACTION")) { scr_print_active("* "); scr_print_active(msg_src); - scr_print_active(" "); + scr_putc_active(' '); scr_print_active(p); scr_eol_active(); return; } - scr_print_active("*** CTCP "); + print_ctcp(); scr_print_active(ctcp_type); - scr_print_active(" request from "); + scr_print_active(" req from "); scr_print_active(msg_src); scr_eol_active(); @@ -219,18 +218,23 @@ static void do_ctcp(int is_notice) { } txbuf_set_str3("NOTICE ", msg_src, " :\x01"); - txbuf_append_str3(ctcp_type, " ", resp); - txbuf_append_str("\x01"); + txbuf_append_str(ctcp_type); + txbuf_append_chr(' '); + txbuf_append_str(resp); + txbuf_append_chr('\x01'); txbuf_send(); } } static void do_privmsg(void) { /* TODO: this shouldn't be case-sensitive */ - if(strstr(msg_text, conf->nick)) + /* + if(strstr(msg_text, config.nick)) hilite = 1; else hilite = 0; + */ + hilite = find_nick(); if(*msg_text == '\x01') { do_ctcp(0); @@ -242,7 +246,10 @@ static void do_privmsg(void) { ind_act_chantext(); } else { do_priv_nick(); - ind_act_pm(); + if(*msg_cmd == 'N') + ind_act_notice(); + else + ind_act_pm(); } scr_print_active(msg_text); @@ -260,23 +267,22 @@ static void do_notice(void) { static void do_join(void) { ind_act_join(); - if(streq_i(conf->nick, msg_src)) { - scr_print_active("You have "); + if(self_src) { + scr_print_active("You"); } else { scr_print_active("\x02=\x02"); scr_print_active(msg_src); - scr_print_active(" has "); } - scr_print_active("joined "); + scr_print_active(" joined "); scr_print_active(msg_dest); scr_eol_active(); } static void do_nick(void) { - /* Do not overwrite conf->nick with bogus data! sometimes when + /* Do not overwrite config.nick with bogus data! sometimes when we get disconnected, upon reconnect we get a partial message. if it's a NICK, missing its destination argument, we end up - blowing away conf->nick, and subsequent reconnect attempts + blowing away config.nick, and subsequent reconnect attempts fail with "USER: not enough parameters". This is purely a band-aid; a proper solution involves rewriting parse_msg() so it knows how many args each msg type needs, and refuses to @@ -285,9 +291,9 @@ static void do_nick(void) { return; // ind_act_none(); - if(streq_i(conf->nick, msg_src)) { + if(self_src) { scr_print_active("You are "); - strncpy(conf->nick, msg_dest, 32); + strncpy(config.nick, msg_dest, 32); } else { scr_print_active(msg_src); scr_print_active(" is "); @@ -309,95 +315,66 @@ static void do_part(void) { scr_print_active(msg_src); scr_print_active(" has left "); scr_print_active(msg_dest); - if(msg_text) { - scr_print_active(": "); - scr_print_active(msg_text); - } - scr_eol_active(); + print_reason(); } static void do_topic(void) { scr_print_active(msg_src); - scr_print_active(" has set the topic of "); + scr_print_active(" sets the "); scr_print_active(msg_dest); - scr_print_active(" to: "); + scr_print_active(" topic to: "); scr_print_active(msg_text); scr_eol_active(); - /* TODO: set topic in the screen! */ } static void do_kick(void) { scr_print_active(msg_src); - scr_print_active(" has kicked "); + scr_print_active(" kicks "); scr_print_active(msg_args[1]); scr_print_active(" from "); scr_print_active(msg_dest); print_reason(); } -static void do_mode(void) { - int i; - if(msg_src) - scr_print_active(msg_src); - else - scr_print_active("Server"); - scr_print_active(" sets mode: "); - for(i = 0; i < msg_argcount; i++) { - scr_print_active(msg_args[i]); - scr_print_active(" "); - } - if(msg_text) scr_print_active(msg_text); - scr_eol_active(); -} - /* numerics call this with arg==1, since arg 0 is always our nick. other commands call with arg==0 to print everything. */ -static void do_catchall(int arg) { +static void do_catchall(char arg) { if(msg_src) { scr_print_active(msg_src); - scr_print_active(" "); + scr_putc_active(' '); } scr_print_active(msg_cmd); for(; arg < msg_argcount; arg++) { - scr_print_active(" "); + scr_putc_active(' '); scr_print_active(msg_args[arg]); } if(msg_text) { - scr_print_active(" "); + scr_putc_active(' '); scr_print_active(msg_text); } scr_eol_active(); } -/* permutes last character (doesn't add one), so for "Bob" you get: - Bo_, Bo1 through Bo9, BoA through BoZ - Gives a total of 36 replacement nicks to try. - Eventually we run out and start repeating, but by then the IRC - server will have disconnected us. - */ -static void permute_nick(void) { - char *last; - - last = conf->nick + strlen(conf->nick) - 1; - - if((*last >= '1' && *last < '9') || (*last >= 'A' && *last < 'Z')) { - (*last)++; +static void do_mode(void) { + if(msg_src) { + scr_print_active(msg_src); + msg_src = 0; /* don't let do_catchall() print it again */ } else { - switch(*last) { - case '_': *last = '1'; break; - case '9': *last = 'A'; break; - default: *last = '_'; break; - } + scr_print_active("Server"); } + scr_print_active(" sets mode:"); + do_catchall(0); } +extern void permute_nick(void); + /* see: https://defs.ircdocs.horse/ */ static void do_forward_chan(void) { - char s; + static char s; if(msg_argcount > 2 && msg_args[1][0] == '#' && msg_args[2][0] == '#') { s = scr_getbyname(msg_args[1]); @@ -408,13 +385,15 @@ static void do_forward_chan(void) { } static void do_numeric(void) { - unsigned int num = atoi(msg_cmd); + static unsigned int num; + + num = a2uint(msg_cmd); switch(num) { /* use the server's idea of what our nick is, in case it got truncated. */ case RPL_WELCOME: - strcpy(conf->nick, msg_args[0]); + strcpy(config.nick, msg_args[0]); regged = 1; do_catchall(1); break; @@ -438,11 +417,13 @@ static void do_numeric(void) { */ case ERR_NICKNAMEINUSE: - do_catchall(0); - if(!regged) { + if(regged) { + scr_activate(scr_current); + } else { permute_nick(); send_nick(); } + do_catchall(1); break; /* don't print these, just noise */ @@ -450,18 +431,20 @@ static void do_numeric(void) { break; case RPL_MOTD: - /* FIXME: this prevents the user using /MOTD on purpose, too */ if(!hide_motd) - do_catchall(0); + do_catchall(1); break; /* don't print, but do trigger rejoin */ case RPL_ENDOFMOTD: case ERR_NOMOTD: hide_motd = 0; - cmd_rejoin_chans(); - if(scr_names[2][0] == '#') - scr_display(2); + if(need_rejoin) { + cmd_rejoin_chans(); + if(scr_names[2][0] == '#') + scr_display(2); + need_rejoin = 0; + } break; case RPL_NAMREPLY: @@ -493,17 +476,32 @@ static void do_numeric(void) { do_forward_chan(); break; + case RPL_AWAY: + scr_print_active(msg_args[1]); + scr_print_active(" is away: "); + scr_print_active(msg_text); + scr_eol_active(); + break; + default: + if(num >= 400 && num < 600) + scr_activate(scr_current); do_catchall(1); break; } } +#if 0 static void invalid_msg(char type) { scr_print(SCR_SERVER, "??? unknown, type "); scr_putc(SCR_SERVER, type); scr_putc(SCR_SERVER, '\n'); } +#endif + +static char cmd_is(char *cmd) { + return streq_i(msg_cmd, cmd); +} void select_screen(void) { char s; @@ -519,7 +517,7 @@ void select_screen(void) { } else { s = scr_getbyname(msg_src); if(!s) { - if(streq_i(msg_cmd, "PRIVMSG")) { /* or maybe NOTICE? */ + if(cmd_is("PRIVMSG")) { /* or maybe NOTICE? */ strncpy(last_pm_nick, msg_src, 32); comp_add_pm_nick(last_pm_nick); s = SCR_PRIV; @@ -532,34 +530,50 @@ void select_screen(void) { } static void dispatch_msg(void) { + self_src = streq_i(config.nick, msg_src); + /* at this point, we know the message source and destination, so: */ + /* FIXME: maybe we know... */ select_screen(); + new_scr_status = SCR_OTHER; - if(streq_i(msg_cmd, "PRIVMSG")) { + if(cmd_is("PRIVMSG")) { + new_scr_status = SCR_ACTIVE; do_privmsg(); - } else if(streq_i(msg_cmd, "NOTICE")) { + } else if(cmd_is("NOTICE")) { do_notice(); - } else if(streq_i(msg_cmd, "JOIN")) { + } else if(cmd_is("JOIN")) { do_join(); - } else if(streq_i(msg_cmd, "NICK")) { + } else if(cmd_is("NICK")) { do_nick(); - } else if(streq_i(msg_cmd, "QUIT")) { + } else if(cmd_is("QUIT")) { do_quit(); - } else if(streq_i(msg_cmd, "PART")) { + } else if(cmd_is("PART")) { do_part(); - } else if(streq_i(msg_cmd, "TOPIC")) { + } else if(cmd_is("TOPIC")) { do_topic(); - } else if(streq_i(msg_cmd, "KICK")) { + } else if(cmd_is("KICK")) { do_kick(); - } else if(streq_i(msg_cmd, "MODE")) { + } else if(cmd_is("MODE")) { do_mode(); - } else if(streq_i(msg_cmd, "PONG")) { - if(*msg_text != 'A') do_server_pong(); - } else if(isdigit(msg_cmd[0])) { + } else if(cmd_is("PONG")) { + if(*msg_text == 'A') { + return; /* do not set screen status */ + } else { + do_server_pong(); + } + } else if(isnum(msg_cmd[0])) { do_numeric(); } else { do_catchall(0); } + + if(scr_active != scr_current) { + if(scr_status[scr_active] < new_scr_status) { + scr_status[scr_active] = new_scr_status; + scr_show_status(scr_current); + } + } } /* msgbuf contains a complete message from the server, whose @@ -568,73 +582,52 @@ static void dispatch_msg(void) { static void parse_msg(void) { char *p; - msg_cmd = msg_text = msg_src = msg_dest = 0; - msg = msgbuf; - /* ignore empty message */ - if(!*msg) return; + if(!*msgbuf) return; - /* - scr_print_active("RAW: "); - scr_print_active(msg); - scr_eol_active(); - */ - - /* if there's a final multiword arg... */ - /* FIXME: channel names can have colons, which breaks this... */ - p = strstr(msg + 1, " :"); /* +1 to skip leading colon in msg source */ - if(p) { - msg_text = p + 2; - *p = 0; - } + msg_cmd = msg_text = msg_src = msg_dest = 0; + memset(msg_args, 0, sizeof(msg_args)); /* first token is either the source (with a :) or a command (without) */ - p = strtok(msg, " "); - if(!p) { - invalid_msg('1'); - return; - } - - if(*p == ':') { - msg_src = p + 1; /* generally :irc.example.com or :nick!user@host */ - msg_cmd = strtok(0, " "); + if(*msgbuf == ':') { + msg_src = msgbuf + 1; /* generally :irc.example.com or :nick!user@host */ + msg_cmd = nextarg(msgbuf); } else { msg_src = 0; /* no source supplied */ - msg_cmd = p; + msg_cmd = msgbuf; } + p = nextarg(msg_cmd); + #if 0 if(!msg_cmd) { invalid_msg('2'); return; } + #endif /* special case for ping, treat as 1 arg, even if it has space and no : */ - if(streq_i(msg_cmd, "PING")) { - msg_argcount = 1; - msg_args[0] = msg_cmd + 6; - do_pong(); + if(cmd_is("PING")) { + txbuf_set_str2("PONG ", msg_cmd + 6); + txbuf_send(); return; - } else { - for(msg_argcount = 0; msg_argcount < MAX_MSG_ARGS; msg_argcount++) { - p = strtok(0, " "); - if(p) { - msg_args[msg_argcount] = p; - /* if any arg is a channel name, use it for the dest */ - if(*p == '#') - msg_dest = p; - } else { - break; - } - } } - /* - if(msg_dest) { - scr_print_current("got here, msg_dest is: "); - scr_print_current(msg_dest); - scr_eol_current(); + for(msg_argcount = 0; msg_argcount < MAX_MSG_ARGS; msg_argcount++) { + if(!p) break; + + if(*p == ':') { + msg_text = p + 1; + break; + } + + msg_args[msg_argcount] = p; + + /* if any arg is a channel name, use it for the dest */ + if(*p == '#') + msg_dest = p; + + p = nextarg(p); } - */ if(!msg_dest) { if(msg_argcount) @@ -644,9 +637,9 @@ static void parse_msg(void) { } if(msg_src) { - if((p = strstr(msg_src, "!"))) { + if((p = strchr(msg_src, '!'))) { *p = '\0'; - } else if(strstr(msg_src, ".")) { + } else if(strchr(msg_src, '.')) { msg_src = 0; } } @@ -662,31 +655,30 @@ static void irc_split_Lines(void) { char *p = rx_buf; for(i = 0; i < rxbuflen; i++) { - msgbuf[msgbuf_len] = *p; - if(*p == CH_EOL) { - // msgbuf[msgbuf_len + 1] = '\0'; - /* do not include the EOL */ - msgbuf[msgbuf_len] = '\0'; - parse_msg(); - msgbuf_len = 0; - } else { - msgbuf_len++; + /* skip ASCII \r character */ + if(*p != 0x0d) { + if(*p == 0x0a) { + /* got ASCII \n */ + msgbuf[msgbuf_len] = '\0'; + parse_msg(); + msgbuf_len = 0; + } else { + msgbuf[msgbuf_len++] = *p; + } } p++; } } -/* TODO: there needs to be a scr_printnum() */ void print_errnum(void) { extern unsigned char err; scr_print_current("Error #"); - itoa(err, numbuf, 10); - scr_print_current(numbuf); + scr_cur_printnum(err); } static void start_minute_timer() { OS.cdtmf4 = 0xff; - OS.cdtmv4 = 60 * hz; + OS.cdtmv4 = timers.one_sec; } static char service_minute_timer() { @@ -716,17 +708,16 @@ static char service_minute_timer() { } else { /* idle >=121 sec, already sent a ping, got nothing back. we timed out. */ - bell(); /* for testing only */ - scr_print_current("Server timed out"); + scr_print_current("Server timed out\n"); return 0; } } -int irc_read(void) { +char irc_read(void) { if(!trip) return 1; last_read_min = minutes; - err = nstatus(conf->url); + err = nstatus(); if(err != 1) { scr_display(SCR_SERVER); @@ -749,7 +740,7 @@ int irc_read(void) { ind_net_rx(); if(rxbuflen > 0) { - err = nread(conf->url, rx_buf, rxbuflen); + err = nread_rxbuf(); if(err != 1) { ind_net_down(); print_errnum(); @@ -774,20 +765,25 @@ void irc_register(void) { /* 2nd arg: local (UNIX) username, just use the nick */ /* 3rd arg: "real" name */ - txbuf_set_str3("USER ", conf->nick, " 0 * :"); - txbuf_append_str(conf->real_name); + txbuf_set_str3("USER ", config.nick, " 0 * :"); + txbuf_append_str(config.real_name); txbuf_send(); send_nick(); } static void scrollback() { - OS.ch = 0xff; + char c; scr_scrollback(); - while(OS.ch == 0xff) + while(!keypress()) irc_read(); - keyclick(); - OS.ch = 0xff; + c = kgetc(); + if(c == '-') { + scr_scrollback_bonus(); + while(!keypress()) + irc_read(); + kgetc(); + } scr_end_scrollback(); } @@ -804,22 +800,23 @@ static void hunt_screen(signed char dir) { scr_display(s); } -static char *get_cur_chan(void) { - if(scr_current == SCR_SERVER && last_chan[0]) - return last_chan; - else if ((scr_current > 1) && (scr_names[scr_current][0] == '#')) +static char *get_cur(void) { + if((scr_current > 1) && (scr_names[scr_current][0] == '#')) return scr_names[scr_current]; else return 0; } +static char *get_cur_chan(void) { + if(scr_current == SCR_SERVER && last_chan[0]) + return last_chan; + else return get_cur(); +} + static char *get_cur_nick(void) { if(scr_current == SCR_PRIV && last_pm_nick[0]) return last_pm_nick; - else if (scr_current > 1 && scr_names[scr_current][0] != '#') - return scr_names[scr_current]; - else - return 0; + else return get_cur(); } static void send2_with_space(char *s1, char *s2) { @@ -857,7 +854,7 @@ static char cur_is_query(void) { /* count backwards here, because the [server] screen is 0, it's the least interesting one. */ -char find_scr_with_status(int status) { +char find_scr_with_status(char status) { signed char i; for(i = MAX_SCREENS - 1; i != -1; i--) { @@ -874,6 +871,8 @@ void switch_to_active() { i = find_scr_with_status(SCR_HILITE); if(i == 0xff) i = find_scr_with_status(SCR_ACTIVE); + if(i == 0xff) + i = find_scr_with_status(SCR_OTHER); if(i != 0xff) { scr_prev = scr_current; scr_display(i); @@ -918,13 +917,14 @@ static void toggle_edbox_only(void) { OS.sdlst = edbox_only_dlist; } -static void start_keystroke(void) { - char i, s; +void start_keystroke(char c) { + char s; - i = cgetc(); + start_latch = 0; + if(c == CH_ESC) return; - if(i >= '1' && i <= '7') { - s = i - '1'; + if(c >= '1' && c <= '7') { + s = c - '1'; if(s != scr_current) { if(scr_status[s] != SCR_UNUSED) { scr_prev = scr_current; @@ -934,32 +934,32 @@ static void start_keystroke(void) { return; } - switch(tolower(i)) { - case CH_CURS_UP: + switch(lcase(c)) { + case XCH_UP: case '-': scrollback(); return; case 0x18: /* ^X */ send_cur_chan_cmd("PART"); /* fall thru */ - case CH_ESC: + case 'x': scr_prev = SCR_PRIV; scr_destroy(scr_current); return; - case CH_CURS_LEFT: + case XCH_LEFT: case '+': scr_prev = scr_current; hunt_screen(-1); return; - case CH_CURS_RIGHT: + case XCH_RIGHT: case '*': scr_prev = scr_current; hunt_screen(1); return; - case CH_TAB: - i = scr_current; + case XCH_TAB: + c = scr_current; scr_display(scr_prev); - scr_prev = i; + scr_prev = c; return; case 'q': if(scr_current == SCR_PRIV && *last_pm_nick) { @@ -1007,29 +1007,17 @@ static void start_keystroke(void) { } } -static void keystroke(void) { - if(OS.ch == 0xff) return; - if(irc_away) { - txbuf_send_str("AWAY"); - irc_away = 0; - } - if(GTIA_READ.consol == 6) { /* start pressed */ - start_keystroke(); - } else { - edbox_keystroke(); - } -} - /* only exits on error (e.g. connection closed, which might be via /QUIT). */ void irc_loop(void) { /* this stuff happens on every connect. */ - hide_motd = conf->hide_motd; + hide_motd = config.hide_motd; msgbuf[0] = msgbuf_len = regged = irc_away = minutes = 0; + need_rejoin = 1; start_minute_timer(); while(1) { ind_check_timer(); - if(conf->atract_away) { + if(config.atract_away) { if(!irc_away && (OS.atract & 0x80)) { irc_away = 1; txbuf_send_str("AWAY :ATRACT mode"); @@ -1038,6 +1026,9 @@ void irc_loop(void) { if(!irc_read() || !service_minute_timer()) { return; } - keystroke(); + OS.cdtmv3 = 0; + do { + poll_keyboard(); + } while(OS.cdtmv3); } } |
