# HG changeset patch # User Matti Hamalainen # Date 1307751502 -10800 # Node ID cc2a1d837e7b93c4f03993e586ed7f498616df9d # Parent f1049f487987fc4c2eff274010c4f6cc853e8376 Window / buffer functionality works now. Queries work (with few minor glitches). diff -r f1049f487987 -r cc2a1d837e7b nnchat.c --- a/nnchat.c Sat Jun 11 02:44:55 2011 +0300 +++ b/nnchat.c Sat Jun 11 03:18:22 2011 +0300 @@ -41,8 +41,10 @@ typedef struct { qringbuf_t *data; /* "Backbuffer" data for this window */ int pos; /* Current position in the window, 0 = real time */ + BOOL dirty; + char *id; /* Chatter ID, NULL = main window */ - BOOL dirty; + int num; /* Window number */ char *buf; size_t len, bufsize; @@ -60,12 +62,10 @@ *optPassword = NULL, *optPasswordCmd = NULL, *optLogFilename = NULL, - *setTarget = NULL, *optSite = "NN"; char optNickSep = ':'; BOOL optDaemon = FALSE; FILE *optLogFile = NULL; -BOOL setPrvMode = FALSE; BOOL setIgnoreMode = FALSE; BOOL optDebug = FALSE; BOOL optLogEnable = FALSE; @@ -203,7 +203,7 @@ } -nn_window_t *nn_window_new() +nn_window_t *nn_window_new(const char *id) { nn_window_t *res = th_calloc(1, sizeof(nn_window_t)); @@ -214,6 +214,8 @@ th_free(res); return NULL; } + res->id = th_strdup(id); + res->num = 0; return res; } @@ -243,9 +245,47 @@ } -void updateStatus(BOOL insertMode) +BOOL openWindow(const char *name, BOOL curwin) +{ + int i; + nn_window_t *res; + if (name == NULL) + return FALSE; + + if ((res = nn_window_new(name)) == NULL) + return FALSE; + + for (i = 1; i < SET_MAX_WINDOWS; i++) + if (chatWindows[i] == NULL) { + res->num = i; + chatWindows[i] = res; + if (curwin) + currWin = res; + return TRUE; + } + + return FALSE; +} + + +void closeWindow(nn_window_t *win) +{ + int i; + if (win == NULL) return; + + for (i = 1; i < SET_MAX_WINDOWS; i++) + if (chatWindows[i] == win) { + chatWindows[i] = NULL; + nn_window_free(win); + return; + } +} + + +void updateStatus(void) { char tmpStr[128]; + int i; if (statusWin == NULL) return; @@ -263,27 +303,32 @@ waddstr(statusWin, optUserName); wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); + wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); waddstr(statusWin, " | "); wattrset(statusWin, A_BOLD | COLOR_PAIR(11)); - waddstr(statusWin, insertMode ? "INS" : "DEL"); - + snprintf(tmpStr, sizeof(tmpStr), "#%06x", optUserColor); + waddstr(statusWin, tmpStr); + wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); - waddstr(statusWin, " | Prv: "); - - wattrset(statusWin, A_BOLD | COLOR_PAIR(11)); - waddstr(statusWin, setTarget != NULL ? setTarget : "-"); + waddstr(statusWin, " | WIN: "); + snprintf(tmpStr, sizeof(tmpStr), "%d: %s", currWin->num + 1, currWin->id ? currWin->id : "MAIN"); + waddstr(statusWin, tmpStr); wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); - waddstr(statusWin, " | P/C: "); + waddstr(statusWin, " | "); wattrset(statusWin, A_BOLD | COLOR_PAIR(11)); - snprintf(tmpStr, sizeof(tmpStr), "%d / #%06x", optPort, optUserColor); - waddstr(statusWin, tmpStr); + + for (i = 0; i < SET_MAX_WINDOWS; i++) + if (chatWindows[i] != NULL && chatWindows[i]->dirty) { + snprintf(tmpStr, sizeof(tmpStr), "%d ", i + 1); + waddstr(statusWin, tmpStr); + } wrefresh(statusWin); } -void printEditBuf(const char *str, nn_editbuf_t *buf) +void printEditBuf(nn_editbuf_t *buf) { char *tmp; if (editWin == NULL || buf == NULL) return; @@ -293,9 +338,6 @@ werase(editWin); - wattrset(editWin, A_BOLD); - mvwaddstr(editWin, 0, 0, str); - waddstr(editWin, "> "); wattrset(editWin, A_NORMAL); if (buf->pos < buf->len) { @@ -538,7 +580,7 @@ { const char *msg = "", *p = str; BOOL isMine, isIgnored = FALSE; - char *s, *t, *h, *userName; + char *s, *t, *userName; (void) conn; @@ -577,25 +619,37 @@ goto done; t = nn_strip_tags(s + 1); - if (!strncmp(t, "BPRV", 4)) { - h = nn_decode_str2(t + 1); - if (!isIgnored && setTarget == NULL && !strncmp(h, "PRV from ", 9)) { - char *q; - setTarget = th_strdup(h + 9); - for (q = setTarget; *q && *q != ':'; q++); - *q = 0; - printMsg(NULL, "PRV target autoset to '%s'\n", setTarget); + if (!strncmp(t, "BPRV ", 5)) { + char *name, *tmp, *msg; + + if (!strncmp(t, "BPRV from ", 10)) { + name = nn_decode_str2(t + 10); + isMine = FALSE; + } else { + name = nn_decode_str2(t + 8); + isMine = TRUE; } - printMsgQ(NULL, isIgnored, "½11½%s½0½\n", h); + + for (tmp = name; *tmp && *tmp != ':'; tmp++); + if (tmp[0] != 0 && tmp[1] == ' ') + msg = tmp + 2; + else + msg = ""; + *tmp = 0; + + isIgnored = setIgnoreMode && checkIgnoreList(name); + + printMsgQ(nn_find_window(name), isIgnored, "½5½<½%d½%s½5½>½0½ %s\n", isMine ? 14 : 15, isMine ? optUserName : name, msg); } else { /* It's an action (/me) */ - h = nn_decode_str2(t); + char *h = nn_decode_str2(t); printMsgQ(NULL, isIgnored, "½9½* %s½0½\n", h); + th_free(h); } - th_free(h); th_free(t); } else { /* It's a normal message */ + char *h; t = nn_strip_tags(s); h = nn_decode_str2(t); printMsgQ(NULL, isIgnored, "½5½<½%d½%s½5½>½0½ %s\n", isMine ? 14 : 15, userName, h); @@ -801,17 +855,34 @@ else if (!strncasecmp(buf, "/query", 6)) { char *name = trimLeft(buf + 6); if (strlen(name) > 0) { -// qlist_t *user = th_llist_find_func(setIgnoreList, name, compareUsername); - printMsg(currWin, "Opening query for '%s'.\n", name); - + nn_user_t *user = nn_user_find(nnUsers, name); + if (user != NULL) { + printMsg(currWin, "Opening PRV query for '%s'.\n", user->name); + if (openWindow(user->name, TRUE)) + printMsg(currWin, "In PRV query with '%s'.\n", user->name); + } } else { + printMsg(currWin, "Usage: /query username\n"); + printMsg(currWin, "To close a PRV query, use /close [username]\n"); + printMsg(currWin, "/close without username will close the current PRV window (if any).\n"); } return 0; } - else if (!strncasecmp(buf, "/win", 4)) { - char *name = trimLeft(buf + 4); + else if (!strncasecmp(buf, "/close", 6)) { + char *name = trimLeft(buf + 6); if (strlen(name) > 0) { + nn_user_t *user = nn_user_find(nnUsers, name); + if (user != NULL) { + nn_window_t *win = nn_find_window(user->name); + closeWindow(win); + } else { + printMsg(currWin, "No PRV query by name '%s'.\n", name); + } } else { + if (currWin != chatWindows[0]) { + closeWindow(currWin); + currWin = chatWindows[0]; + } } return 0; } @@ -874,36 +945,21 @@ #endif return 0; } - else if (!strncasecmp(buf, "/to", 3)) { - char *name = trimLeft(buf + 3); - /* Set private messaging target */ - th_free(setTarget); - if (strlen(name) > 0) { - setTarget = th_strdup(trimLeft(buf + 3)); - printMsg(NULL, "Set prv target to '%s'\n", setTarget); - } else { - setTarget = NULL; - printMsg(NULL, "Cleared prv target.\n"); - } - return 0; - } else if (!strncasecmp(buf, "/who", 4)) { /* Alias /who to /listallusers */ snprintf(tmpBuf, sizeof(tmpBuf), "/listallusers"); buf = tmpBuf; } - else if (setPrvMode) { - /* Private chat mode, send as PRV */ - if (setTarget != NULL) { - snprintf(tmpBuf, sizeof(tmpBuf), "/prv -to %s -msg %s", setTarget, buf); + else if (currWin != chatWindows[0]) { + if (currWin->id != NULL) { + snprintf(tmpBuf, sizeof(tmpBuf), "/prv -to %s -msg %s", currWin->id, buf); buf = tmpBuf; } else { printMsg(NULL, "No target set, exiting prv mode.\n"); - setPrvMode = FALSE; return 1; } } - + /* Send double-encoded */ tmpStr = nn_dblencode_str(nn_username_decode(buf)); if (tmpStr == 0) return -2; @@ -1310,9 +1366,9 @@ goto err_exit; memset(chatWindows, 0, sizeof(chatWindows)); - chatWindows[0] = nn_window_new(); + chatWindows[0] = nn_window_new(NULL); currWin = chatWindows[0]; - updateStatus(insertMode); + updateStatus(); } /* Check if we have username and password */ @@ -1385,8 +1441,8 @@ nn_editbuf_clear(editBuf); /* First update of screen */ - printEditBuf("", editBuf); - updateStatus(insertMode); + printEditBuf(editBuf); + updateStatus(); printMsg(NULL, "%s v%s - %s\n", th_prog_name, th_prog_version, th_prog_fullname); printMsg(NULL, "%s\n", th_prog_author); @@ -1465,7 +1521,17 @@ /* Get the trailing ~ */ if (c != ERR) wgetch(stdscr); - } else { + } + if (c >= 0x31 && c <= 0x39) { + /* Chat window switching via Meta/Esc-[1..9] */ + int win = c - 0x31; + if (win < SET_MAX_WINDOWS && chatWindows[win] != NULL) { + currWin = chatWindows[win]; + update = updateMain = TRUE; + } + c = ERR; + } + else { printMsg(currWin, "Unhandled ESC key sequence 0x%02x\n", c); continue; } @@ -1599,26 +1665,6 @@ printMsg(currWin, "Ignore mode = %s\n", setIgnoreMode ? "ON" : "OFF"); break; - case KEY_F(7): /* F7 = Clear PRV target */ - if (setTarget) { - printMsg(NULL, "Cleared PRV target.\n"); - setPrvMode = FALSE; - th_free(setTarget); - setTarget = NULL; - update = TRUE; - } - break; - - case KEY_F(8): /* F8 = switch between PRV */ - if (setPrvMode) - setPrvMode = FALSE; - else { - if (setTarget != NULL) - setPrvMode = TRUE; - } - update = TRUE; - break; - case 0x03: /* ^C = quit */ case KEY_F(9): /* F9 = Quit */ printMsg(currWin, "Quitting per user request.\n"); @@ -1675,8 +1721,8 @@ if (update || firstUpdate) { /* Update edit line */ - printEditBuf(setPrvMode ? setTarget : "", editBuf); - updateStatus(insertMode); + printEditBuf(editBuf); + updateStatus(); firstUpdate = FALSE; /* a nasty hack ... */ } @@ -1697,7 +1743,7 @@ nn_conn_send_msg(conn, optUserNameEnc, "%%2FSetFontColor%%20%%2Dcolor%%20%06X", optUserColor); } - updateStatus(insertMode); + updateStatus(); updateCount = 0; } @@ -1717,14 +1763,14 @@ nn_window_free(chatWindows[i]); } -//#ifdef __WIN32 +#ifdef __WIN32 if (errorMessages) { char *tmp; wclear(editWin); tmp = promptRequester(editWin, "Press enter to quit.\n", FALSE); th_free(tmp); } -//#endif +#endif if (cursesInit) { if (curVis != ERR)