AmendHub

Download:

jcs

/

wallops

/

amendments

/

5

chatter+irc: Remove debugging, consolidate window setup, more IRC work


jcs made amendment 5 over 2 years ago
--- chatter.c Tue Feb 1 21:13:48 2022 +++ chatter.c Wed Feb 2 17:38:22 2022 @@ -23,7 +23,7 @@ #define NICK_LIST_WIDTH 75 -void chatter_layout(struct chatter *chatter, bool init); +void chatter_layout(struct chatter *chatter, bool init, Rect *init_bounds); void chatter_key_down(struct focusable *focusable, EventRecord *event); void chatter_mouse_down(struct focusable *focusable, EventRecord *event); void chatter_menu(struct focusable *focusable, short menu, short item); @@ -34,14 +34,14 @@ void chatter_atexit(struct focusable *focusable); void chatter_init(const char *server, const unsigned short port, - const char *nick, const char *ident, const char *realname) + const char *nick, const char *ident, const char *realname, + bool show_motd) { struct focusable *focusable; struct chatter *chatter; char title[64]; - Rect bounds = { 0 }, control_bounds = { 0 }; - Rect data_bounds = { 0, 0, 0, 1 }; /* tlbr */ - Point cell_size = { 0 }; + Rect bounds = { 0 }; + short padding = 20; if (_TCPInit() != 0) panic("TCPInit failed"); @@ -53,14 +53,14 @@ chatter_init(const char *server, const unsigned short chatter->irc_nick = xstrdup(nick); chatter->irc_ident = xstrdup(ident); chatter->irc_realname = xstrdup(realname); + chatter->irc_show_motd = show_motd; - bounds.left = 10; - bounds.top = screenBits.bounds.top + 10 + (GetMBarHeight() * 2) - 1; - bounds.right = screenBits.bounds.right - 11; - bounds.bottom = screenBits.bounds.bottom - 11; + bounds.left = padding; + bounds.top = screenBits.bounds.top + padding + + (GetMBarHeight() * 2) - 1; + bounds.right = screenBits.bounds.right - padding - 1; + bounds.bottom = screenBits.bounds.bottom - padding - 1; -bounds.bottom = 150; - snprintf(title, sizeof(title), "%s: Disconnected", PROGRAM_NAME); chatter->win = NewWindow(0L, &bounds, CtoPstr(title), false, documentProc, (WindowPtr)-1L, true, 0); @@ -71,33 +71,11 @@ bounds.bottom = 150; TextFont(applFont); TextSize(CHATTER_FONT_SIZE); - /* initially draw everything off-screen until we chatter_layout() */ - bounds.left = chatter->win->portRect.right + 10; - bounds.top = chatter->win->portRect.top + 10; - bounds.right = bounds.left + 20; - bounds.bottom = bounds.top + 20; - chatter->win_init_bounds = bounds; - - /* input */ - chatter->input_te = TENew(&bounds, &bounds); + bounds.right -= bounds.left; + bounds.bottom -= bounds.top; + bounds.top = bounds.left = 0; + chatter_layout(chatter, true, &bounds); - /* nick list */ - bounds.right = chatter->win->portRect.right + 1; - bounds.left = bounds.right - NICK_LIST_WIDTH; - chatter->nick_list = LNew(&bounds, &data_bounds, cell_size, 0, - chatter->win, true, true, false, true); - if (!chatter->nick_list) - panic("Can't create mailboxes list"); - LAddColumn(1, 0, chatter->nick_list); - (*(chatter->nick_list))->selFlags = lOnlyOne | lNoNilHilite; - - /* messages */ - chatter->messages_te = TEStylNew(&bounds, &bounds); - - /* messages scrollbar */ - chatter->messages_scroller = NewControl(chatter->win, &bounds, "\p", - true, 1, 1, 1, scrollBarProc, 0L); - focusable = xmalloczero(sizeof(struct focusable)); focusable->win = chatter->win; focusable->cookie = chatter; @@ -109,55 +87,83 @@ bounds.bottom = 150; focusable->atexit = chatter_atexit; focusable->menu = chatter_menu; show_focusable(focusable); - chatter_layout(chatter, false); } void -chatter_layout(struct chatter *chatter, bool init) +chatter_layout(struct chatter *chatter, bool init, Rect *init_bounds) { - Rect bounds, win_bounds; + Rect bounds, inset_bounds, win_bounds; + Rect control_bounds = { 0 }; + Rect data_bounds = { 0, 0, 0, 1 }; /* tlbr */ + Point cell_size = { 0 }; + Cell cell = { 0, 0 }; if (init) - win_bounds = chatter->win_init_bounds; + win_bounds = *init_bounds; else win_bounds = chatter->win->portRect; /* input */ bounds.left = 0; - bounds.right = win_bounds.right - SCROLLBAR_WIDTH; + bounds.right = win_bounds.right; bounds.top = win_bounds.bottom - SCROLLBAR_WIDTH; bounds.bottom = win_bounds.bottom; - (*(chatter->input_te))->viewRect = bounds; - InsetRect(&bounds, 3, 1); - (*(chatter->input_te))->destRect = bounds; - TECalText(chatter->input_te); - + if (init) { + inset_bounds = bounds; + InsetRect(&inset_bounds, 3, 1); + chatter->input_te = TENew(&inset_bounds, &bounds); + } else { + (*(chatter->input_te))->viewRect = bounds; + InsetRect(&bounds, 3, 1); + (*(chatter->input_te))->destRect = bounds; + TECalText(chatter->input_te); + } + /* nick list */ bounds.top = 0; - bounds.right = win_bounds.right + 1; + bounds.right = win_bounds.right - SCROLLBAR_WIDTH + 1; bounds.left = bounds.right - NICK_LIST_WIDTH; bounds.bottom = (*(chatter->input_te))->viewRect.top - 2; - (*(chatter->nick_list))->rView = bounds; - LSize(bounds.right - bounds.left + 1, bounds.bottom - bounds.top, - chatter->nick_list); - + if (init) { + chatter->nick_list = LNew(&bounds, &data_bounds, cell_size, 0, + chatter->win, true, true, false, true); + if (!chatter->nick_list) + panic("Can't create mailboxes list"); + LAddColumn(1, 0, chatter->nick_list); + (*(chatter->nick_list))->selFlags = lOnlyOne | lNoNilHilite; + } else { + (*(chatter->nick_list))->rView = bounds; + LSize(bounds.right - bounds.left, bounds.bottom - bounds.top - 10, + chatter->nick_list); + } + /* messages scrollbar */ bounds.top = -1; bounds.right = (*(chatter->nick_list))->rView.left; bounds.left = bounds.right - SCROLLBAR_WIDTH; bounds.bottom = (*(chatter->input_te))->viewRect.top - 1; - (*(chatter->messages_scroller))->contrlRect = bounds; + if (init) + chatter->messages_scroller = NewControl(chatter->win, &bounds, + "\p", true, 1, 1, 1, scrollBarProc, 0L); + else + (*(chatter->messages_scroller))->contrlRect = bounds; /* messages */ bounds.right = (*(chatter->messages_scroller))->contrlRect.left; bounds.left = 0; bounds.top = 0; bounds.bottom = (*(chatter->input_te))->viewRect.top - 2; - (*(chatter->messages_te))->viewRect = bounds; - InsetRect(&bounds, 4, 4); - (*(chatter->messages_te))->destRect = bounds; - TECalText(chatter->messages_te); - + if (init) { + inset_bounds = bounds; + InsetRect(&inset_bounds, 4, 4); + chatter->messages_te = TEStylNew(&inset_bounds, &bounds); + } else { + (*(chatter->messages_te))->viewRect = bounds; + InsetRect(&bounds, 4, 4); + (*(chatter->messages_te))->destRect = bounds; + TECalText(chatter->messages_te); + } + InvalRect(chatter->win->visRgn); } @@ -491,7 +497,7 @@ chatter_printf(struct chatter *chatter, const char *fo void chatter_sync_nick_list(struct chatter *chatter) { - Cell cell = { 0 }; + Cell cell = { 0, 0 }; size_t n, i, j; char nick[32]; short ret; @@ -500,50 +506,47 @@ chatter_sync_nick_list(struct chatter *chatter) LDoDraw(false, chatter->nick_list); LDelRow(0, 0, chatter->nick_list); - if (!chatter->irc_channel) { - LDoDraw(true, chatter->nick_list); - return; - } + if (chatter->irc_channel) { + /* sort nicks by flags descending, then by nick */ + for (i = 0; i < chatter->irc_channel->nusers; i++) { + for (j = 0; j < chatter->irc_channel->nusers - i - 1; j++) { + ret = 0; + if (chatter->irc_channel->users[j].flags == + chatter->irc_channel->users[j + 1].flags) + ret = strnatcasecmp( + chatter->irc_channel->users[j].nick, + chatter->irc_channel->users[j + 1].nick); + else + ret = (chatter->irc_channel->users[j].flags < + chatter->irc_channel->users[j + 1].flags); + + if (ret == 1) { + tnick = chatter->irc_channel->users[j]; + chatter->irc_channel->users[j] = + chatter->irc_channel->users[j + 1]; + chatter->irc_channel->users[j + 1] = tnick; + } + } + } - /* sort nicks by flags descending, then by nick */ - for (i = 0; i < chatter->irc_channel->nusers; i++) { - for (j = 0; j < chatter->irc_channel->nusers - i - 1; j++) { - ret = 0; - if (chatter->irc_channel->users[j].flags == - chatter->irc_channel->users[j + 1].flags) - ret = strnatcasecmp(chatter->irc_channel->users[j].nick, - chatter->irc_channel->users[j + 1].nick); + cell.v = 0; + for (n = 0; n < chatter->irc_channel->nusers; n++) { + if (chatter->irc_channel->users[n].flags == IRC_NICK_FLAG_OP) + j = snprintf(nick, sizeof(nick), "@%s", + chatter->irc_channel->users[n].nick); + else if (chatter->irc_channel->users[n].flags == + IRC_NICK_FLAG_VOICE) + j = snprintf(nick, sizeof(nick), "+%s", + chatter->irc_channel->users[n].nick); else - ret = (chatter->irc_channel->users[j].flags < - chatter->irc_channel->users[j + 1].flags); - - if (ret == 1) { - tnick = chatter->irc_channel->users[j]; - chatter->irc_channel->users[j] = - chatter->irc_channel->users[j + 1]; - chatter->irc_channel->users[j + 1] = tnick; - } + j = snprintf(nick, sizeof(nick), "%s", + chatter->irc_channel->users[n].nick); + LAddRow(1, cell.v, chatter->nick_list); + LSetCell(&nick, j, cell, chatter->nick_list); + cell.v++; } } - - for (n = 0; n < chatter->irc_channel->nusers; n++) { - LAddRow(1, cell.v, chatter->nick_list); - if (chatter->irc_channel->users[n].flags == IRC_NICK_FLAG_OP) { - j = snprintf(nick, sizeof(nick), "@%s", - chatter->irc_channel->users[n].nick); - LSetCell(nick, j, cell, chatter->nick_list); - } else if (chatter->irc_channel->users[n].flags == IRC_NICK_FLAG_VOICE) { - j = snprintf(nick, sizeof(nick), "+%s", - chatter->irc_channel->users[n].nick); - LSetCell(nick, j, cell, chatter->nick_list); - } else - LSetCell(chatter->irc_channel->users[n].nick, - strlen(chatter->irc_channel->users[n].nick), cell, - chatter->nick_list); - cell.v++; - } LDoDraw(true, chatter->nick_list); - InvalRect(&(*(chatter->nick_list))->rView); } --- chatter.h Tue Feb 1 21:28:46 2022 +++ chatter.h Wed Feb 2 17:23:54 2022 @@ -48,12 +48,14 @@ #define CONNECT_NICK_ID 4 #define CONNECT_IDENT_ID 5 #define CONNECT_REALNAME_ID 6 +#define CONNECT_SHOW_MOTD_ID 7 #define STR_SERVER_ID 1000 #define STR_PORT_ID 1001 #define STR_NICK_ID 1002 #define STR_IDENT_ID 1003 #define STR_REALNAME_ID 1004 +#define STR_SHOW_MOTD_ID 1005 #define DEFAULT_SERVER_NAME "irc.libera.chat" #define DEFAULT_PORT "6667" @@ -78,7 +80,6 @@ extern struct focusable *last_focusable; struct chatter { WindowPtr win; - Rect win_init_bounds; TEHandle messages_te; ControlHandle messages_scroller; TEHandle input_te; @@ -90,6 +91,7 @@ struct chatter { char *irc_nick; char *irc_ident; char *irc_realname; + bool irc_show_motd; struct irc_channel *irc_channel; TCPiopb irc_rcv_pb, irc_send_pb, irc_close_pb; TCPStatusPB irc_status_pb; @@ -109,7 +111,7 @@ void show_focusable(struct focusable *focusable); void close_focusable(struct focusable *focusable); void chatter_init(const char *server, const unsigned short port, - const char *nick, const char *ident, const char *realname); + const char *nick, const char *ident, const char *realname, bool show_motd); void chatter_update_titlebar(struct chatter *chatter); size_t chatter_printf(struct chatter *chatter, const char *format, ...); void chatter_sync_nick_list(struct chatter *chatter); --- irc.c Tue Feb 1 21:15:58 2022 +++ irc.c Wed Feb 2 16:32:44 2022 @@ -31,7 +31,7 @@ struct irc_user * irc_parse_user(char *str); bool irc_can_send(struct chatter *chatter); void irc_login(struct chatter *chatter); void irc_process_server(struct chatter *chatter); -void irc_join_channel(struct chatter *chatter, char *channame); +void irc_set_active_channel(struct chatter *chatter, char *channame); void irc_parse_names(struct chatter *chatter, char *line); void @@ -48,7 +48,7 @@ irc_process(struct chatter *chatter) case IRC_STATE_UNINITED: chatter_printf(chatter, "$B*** Welcome to %s$/", PROGRAM_NAME); chatter->irc_state = IRC_STATE_CONNECTING; - irc_init(chatter); + //irc_init(chatter); break; case IRC_STATE_CONNECTED: irc_login(chatter); @@ -455,9 +455,17 @@ done_parsing: chatter_printf(chatter, "$B*** %s ($0%s@%s$B)$0 has joined $B%s$0", user->nick, user->username, user->hostname, msg.dest); if (strcmp(user->nick, chatter->irc_nick) == 0) - irc_join_channel(chatter, msg.dest); + irc_set_active_channel(chatter, msg.dest); return; } + if (strcmp(msg.cmd, "PART") == 0) { + user = irc_parse_user(msg.source); + chatter_printf(chatter, "$B*** %s ($0%s@%s$B)$0 has left $B%s$0", + user->nick, user->username, user->hostname, msg.dest); + if (strcmp(user->nick, chatter->irc_nick) == 0) + irc_set_active_channel(chatter, NULL); + return; + } switch (msg.code) { case 0: goto unknown; @@ -482,6 +490,8 @@ done_parsing: case 375: case 376: /* MOTD */ + if (!chatter->irc_show_motd) + return; goto print_msg; case 311: case 312: @@ -556,11 +566,16 @@ irc_process_input(struct chatter *chatter, char *str) if (strcmp(arg0, "msg") == 0) { arg1 = strsep(&str, " "); + chatter_printf(chatter, "$B[$0msg$B($0%s$B)]$0$/ %s", arg1, + str); irc_printf(chatter, "PRIVMSG %s :%s\r\n", arg1, str); } else if (strcmp(arg0, "join") == 0) { irc_printf(chatter, "JOIN %s\r\n", str); } else if (strcmp(arg0, "part") == 0) { - irc_printf(chatter, "PART %s\r\n", str); + if (str[0] == '\0' && chatter->irc_channel) + irc_printf(chatter, "PART %s\r\n", chatter->irc_channel->name); + else + irc_printf(chatter, "PART %s\r\n", str); } else if (strcmp(arg0, "quit") == 0) { irc_printf(chatter, "QUIT :%s\r\n", str[0] == '\0' ? "&" : str); } else if (strcmp(arg0, "quote") == 0) { @@ -570,17 +585,25 @@ irc_process_input(struct chatter *chatter, char *str) } void -irc_join_channel(struct chatter *chatter, char *channame) +irc_set_active_channel(struct chatter *chatter, char *channame) { struct irc_channel *channel; + + if (chatter->irc_channel) { + if (chatter->irc_channel->users) + free(chatter->irc_channel->users); + free(chatter->irc_channel); + chatter->irc_channel = NULL; + } - channel = xmalloczero(sizeof(struct irc_channel)); - strlcpy(channel->name, channame, sizeof(channel->name)); + if (channame == NULL) + chatter_sync_nick_list(chatter); + else { + channel = xmalloczero(sizeof(struct irc_channel)); + strlcpy(channel->name, channame, sizeof(channel->name)); + chatter->irc_channel = channel; + } - if (chatter->irc_channel) - ; /* TODO: part channel and free */ - - chatter->irc_channel = channel; chatter_update_titlebar(chatter); } @@ -588,7 +611,7 @@ void irc_parse_names(struct chatter *chatter, char *line) { size_t n; - char *space; + char *nick; bool didchannel = false, last = false; struct irc_channel_nick *user; @@ -598,20 +621,16 @@ irc_parse_names(struct chatter *chatter, char *line) /* #wallops :jcs[mac] @jcs */ for (;;) { - if ((space = strchr(line, ' ')) == NULL) { - space = line; - last = true; - } else - space[0] = '\0'; + nick = strsep(&line, " "); if (!didchannel) { - if (strcmp(chatter->irc_channel->name, line) != 0) + if (strcmp(chatter->irc_channel->name, nick) != 0) /* wrong channel */ return; didchannel = true; /* remove leading : on first nick */ - line = space + 2; + line++; continue; } @@ -621,18 +640,17 @@ irc_parse_names(struct chatter *chatter, char *line) chatter->irc_channel->nusers); user = &chatter->irc_channel->users[ chatter->irc_channel->nusers - 1]; - if (line[0] == '@') { + if (nick[0] == '@') { user->flags = IRC_NICK_FLAG_OP; - line++; - } else if (line[0] == '+') { + nick++; + } else if (nick[0] == '+') { user->flags = IRC_NICK_FLAG_VOICE; - line++; + nick++; } else user->flags = 0; - strlcpy(user->nick, line, sizeof(user->nick)); + strlcpy(user->nick, nick, sizeof(user->nick)); - if (last) + if (line == NULL) break; - line = space + 1; } } --- main.c Wed Feb 2 09:32:14 2022 +++ main.c Wed Feb 2 16:28:11 2022 @@ -50,6 +50,8 @@ struct config_field { CONNECT_IDENT_ID, STR_IDENT_ID, DEFAULT_IDENT }, { "Realname", CONFIG_TYPE_STRING, 1, 0, CONNECT_REALNAME_ID, STR_REALNAME_ID, DEFAULT_REALNAME }, + { "Show MOTD", CONFIG_TYPE_SHORT, 0, 1, + CONNECT_SHOW_MOTD_ID, 0, "" }, }; void update_menu(void); @@ -94,7 +96,6 @@ main(void) DrawMenuBar(); show_connect_dialog(); - //chatter_init("irc.libera.chat", 6667, "jcs[mac]", "joshua stein"); for (;;) { SystemTask(); @@ -202,6 +203,7 @@ show_connect_dialog(void) size_t size, n; long port; short hit, itype, ret; + bool show_motd = false; if ((dlg = GetNewDialog(CONNECT_DLOG_ID, nil, (WindowPtr)-1)) == NULL) panic("Can't find connection DLOG %d", CONNECT_DLOG_ID); @@ -288,6 +290,9 @@ verify: case CONNECT_REALNAME_ID: strlcpy((char *)&realname, (char *)txt, sizeof(realname)); break; + case CONNECT_SHOW_MOTD_ID: + show_motd = (atoi((char *)txt) == 1); + break; } if ((h = GetString(cf->res_id)) != NULL) { @@ -307,7 +312,7 @@ verify: DisposeDialog(dlg); chatter_init((char *)&server, port, (char *)&nick, (char *)&ident, - (char *)&realname); + (char *)&realname, show_motd); } short --- tcp.c Tue Oct 5 00:19:37 2021 +++ tcp.c Wed Feb 2 12:54:31 2022 @@ -375,7 +375,7 @@ TCPResolveName(char **name, unsigned long *ipAddress) if (osErr == cacheFault) { /* StrToAddrMarkDone will set done when DNS resolution finishes */ while (!done) - ; + SystemTask(); } if ((aHostInfo.rtnCode == noErr) || (aHostInfo.rtnCode == cacheFault)) {