# HG changeset patch # User Matti Hamalainen # Date 1217740675 -10800 # Node ID 751cff550992c97558d683b525503678af79e9fe # Parent a27ef0e359b9c524a31872c3207bf8c39f1b1a92 Hmm. diff -r a27ef0e359b9 -r 751cff550992 nnchat.c --- a/nnchat.c Sat Aug 02 23:29:50 2008 +0300 +++ b/nnchat.c Sun Aug 03 08:17:55 2008 +0300 @@ -14,7 +14,7 @@ #include #include - +#define SET_MAX_HISTORY (16) #define SET_BUFSIZE (4096) #define SET_ALLOC_SIZE (128) #define SET_DELAY (15) @@ -35,8 +35,7 @@ WINDOW *mainWin = NULL, *statusWin = NULL, *editWin = NULL; - -BOOL setInsertMode = TRUE; +BOOL setPrvMode = FALSE; /* Arguments */ @@ -198,6 +197,30 @@ buf->pos = 0; } +editbuf_t * newBuf(void) +{ + return (editbuf_t *) th_calloc(1, sizeof(editbuf_t)); +} + +void freeBuf(editbuf_t *buf) +{ + th_free(buf); +} + +editbuf_t * copyBuf(editbuf_t *src) +{ + editbuf_t *dst = newBuf(); + + if (dst == NULL) return NULL; + + if (src != NULL) { + memcpy(dst->data, src->data, SET_BUFSIZE); + clearBuf(dst); + } + + return dst; +} + void setBufPos(editbuf_t *buf, ssize_t pos) { /* Check arguments */ @@ -209,7 +232,7 @@ buf->pos = pos; } -void updateStatus(void) +void updateStatus(BOOL insertMode) { char tmpStr[128] = ""; time_t timeStamp; @@ -227,13 +250,13 @@ mvwaddstr(statusWin, 0, 1, tmpStr); waddstr(statusWin, " | "); - wattrset(statusWin, A_BOLD | COLOR_PAIR(11)); + wattrset(statusWin, A_BOLD | COLOR_PAIR(16)); waddstr(statusWin, optUserName); wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); waddstr(statusWin, " | "); wattrset(statusWin, A_BOLD | COLOR_PAIR(11)); - waddstr(statusWin, setInsertMode ? "INS" : "DEL"); + waddstr(statusWin, insertMode ? "INS" : "DEL"); wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); waddstr(statusWin, " | Prv: "); @@ -242,37 +265,32 @@ waddstr(statusWin, setTarget != NULL ? setTarget : "-"); wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); - waddstr(statusWin, " | Port: "); + waddstr(statusWin, " | P/C: "); wattrset(statusWin, A_BOLD | COLOR_PAIR(11)); - snprintf(tmpStr, sizeof(tmpStr), "%d", optPort); + snprintf(tmpStr, sizeof(tmpStr), "%d / #%06x", optPort, optUserColor); waddstr(statusWin, tmpStr); - wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); - waddstr(statusWin, " | Col: "); - wattrset(statusWin, A_BOLD | COLOR_PAIR(11)); - snprintf(tmpStr, sizeof(tmpStr), "%06x", optUserColor); - waddstr(statusWin, tmpStr); - - wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); - snprintf(tmpStr, sizeof(tmpStr), " | %s v%s", - th_prog_name, th_prog_version); - waddstr(statusWin, tmpStr); - wrefresh(statusWin); } -void printEditBuf(editbuf_t *buf) +void printEditBuf(char *str, editbuf_t *buf) { buf->data[buf->len] = 0; werase(editWin); + + wattrset(editWin, A_BOLD); + mvwaddstr(editWin, 0, 0, str); + waddstr(editWin, "> "); + wattrset(editWin, A_NORMAL); + if (buf->pos < buf->len) { - mvwaddnstr(editWin, 0, 0, buf->data, buf->pos); + waddnstr(editWin, buf->data, buf->pos); wattrset(editWin, A_REVERSE); waddch(editWin, buf->data[buf->pos]); wattrset(editWin, A_NORMAL); waddnstr(editWin, buf->data + buf->pos + 1, buf->len - buf->pos - 1); } else { - mvwaddnstr(editWin, 0, 0, buf->data, buf->len); + waddnstr(editWin, buf->data, buf->len); wattrset(editWin, A_REVERSE); waddch(editWin, ' '); wattrset(editWin, A_NORMAL); @@ -854,10 +872,12 @@ if (*buf == 0) { return 1; } else if (!strncmp(buf, "/color ", 7)) { - if ((optUserColor = getColor(buf+7)) < 0) { + int tmpInt; + if ((tmpInt = getColor(buf+7)) < 0) { printMsg("Invalid color value '%s'\n", buf+7); return 1; } + optUserColor = tmpInt; printMsg("Setting color to #%06x\n", optUserColor); sendUserMsg(sock, optUserName2, "%%2FSetFontColor%%20%%2Dcolor%%20%06X", optUserColor); return 0; @@ -884,6 +904,12 @@ th_free(tmpStr); th_free(tmpStr2); return 0; + } else if (!strncmp(buf, "/to ", 4)) { + buf += 4; + th_free(setTarget); + setTarget = th_strdup(buf); + printMsg("Set prv target to '%s'\n", setTarget); + return 0; } else if (!strncmp(buf, "/msg ", 5)) { if (setTarget != NULL) { snprintf(tmpBuf, sizeof(tmpBuf), "/prv -to %s -msg %s", setTarget, buf+5); @@ -892,12 +918,15 @@ printMsg("No target set!\n"); return 1; } - } else if (!strncmp(buf, "/to ", 4)) { - buf += 4; - th_free(setTarget); - setTarget = th_strdup(buf); - printMsg("Set prv target to '%s'\n", setTarget); - return 0; + } else if (setPrvMode) { + if (setTarget != NULL) { + snprintf(tmpBuf, sizeof(tmpBuf), "/prv -to %s -msg %s", setTarget, buf); + buf = tmpBuf; + } else { + printMsg("No target set, exiting prv mode.\n"); + setPrvMode = FALSE; + return 1; + } } { @@ -928,14 +957,19 @@ BOOL argsOK, isError = FALSE, exitProg = FALSE, colorSet = FALSE, - cursesInit = FALSE; + cursesInit = FALSE, + insertMode = TRUE; struct timeval tv; fd_set sockfds; char *tmpStr; - editbuf_t *editBuf = calloc(1, sizeof(editbuf_t)); - + editbuf_t *editBuf = newBuf(); + editbuf_t *histBuf[SET_MAX_HISTORY+2]; + int histPos = 0, histMax = 0; + + memset(histBuf, 0, sizeof(histBuf)); + /* Initialize */ - th_init("NNChat", "Newbie Nudes chat client", "0.4", + th_init("NNChat", "Newbie Nudes chat client", "0.5", "Written and designed by Anonymous Finnish Guy (C) 2008", "This software is freeware, use and distribute as you wish."); th_verbosityLevel = 0; @@ -1045,13 +1079,14 @@ scrollok(mainWin, 1); clearBuf(editBuf); - printEditBuf(editBuf); - updateStatus(); + printEditBuf("", editBuf); + updateStatus(insertMode); cursesInit = TRUE; } - + + /* Enter mainloop */ FD_ZERO(&sockfds); FD_SET(tmpSocket, &sockfds); @@ -1069,7 +1104,7 @@ isError = TRUE; } else if (FD_ISSET(tmpSocket, &tmpfds)) { ssize_t gotBuf; - char tmpBuf[4096]; + char tmpBuf[8192]; gotBuf = recv(tmpSocket, tmpBuf, sizeof(tmpBuf), 0); if (gotBuf < 0) { @@ -1091,7 +1126,7 @@ printMsg("Fatal error with message: %s\n", tmpBuf); isError = TRUE; } - updateStatus(); + updateStatus(insertMode); } } @@ -1110,9 +1145,19 @@ /* Call the user input handler */ if (editBuf->len > 0) { insertBuf(editBuf, editBuf->pos, 0); + + if (histMax > 0) { + freeBuf(histBuf[histMax]); + memmove(&histBuf[2], &histBuf[1], histMax * sizeof(histBuf[0])); + } + histPos = 0; + histBuf[1] = copyBuf(editBuf); + if (histMax < SET_MAX_HISTORY) histMax++; + result = handleUserInput(tmpSocket, editBuf->data, editBuf->len); + clearBuf(editBuf); - + if (result < 0) { printMsg("Fatal error handling user input: %s\n", editBuf->data); isError = TRUE; @@ -1122,11 +1167,41 @@ } break; + case 0x09: /* Tab = switch between PRV */ + if (setPrvMode) + setPrvMode = FALSE; + else { + if (setTarget != NULL) + setPrvMode = TRUE; + } + update = TRUE; + break; + + case KEY_UP: + if (histPos == 0) + histBuf[0] = copyBuf(editBuf); + if (histPos < histMax) { + histPos++; + freeBuf(editBuf); + editBuf = copyBuf(histBuf[histPos]); + update = TRUE; + } + break; + + case KEY_DOWN: + if (histPos > 0) { + histPos--; + freeBuf(editBuf); + editBuf = copyBuf(histBuf[histPos]); + update = TRUE; + } + break; + case 0x109: /* F1 */ - if (setInsertMode) - setInsertMode = FALSE; + if (insertMode) + insertMode = FALSE; else - setInsertMode = TRUE; + insertMode = TRUE; update = TRUE; break; @@ -1188,7 +1263,7 @@ default: if (isprint(c)) { - if (setInsertMode) + if (insertMode) insertBuf(editBuf, editBuf->pos, c); else writeBuf(editBuf, editBuf->pos, c); @@ -1203,18 +1278,21 @@ if (update) { /* Update edit line */ - printEditBuf(editBuf); - updateStatus(); + printEditBuf(setPrvMode ? setTarget : "", editBuf); + updateStatus(insertMode); } } /* !optDaemon */ if (++updateCount > 10) { - updateStatus(); + updateStatus(insertMode); updateCount = 0; } if (!colorSet) { colorSet = TRUE; + printMsg("%s v%s - %s\n", th_prog_name, th_prog_version, th_prog_fullname); + printMsg("%s\n", th_prog_author); + printMsg("%s\n", th_prog_license); sendUserMsg(tmpSocket, optUserName2, "%%2FSetFontColor%%20%%2Dcolor%%20%06X", optUserColor); } }