changeset 30:751cff550992

Hmm.
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 03 Aug 2008 08:17:55 +0300
parents a27ef0e359b9
children 9b429b283786
files nnchat.c
diffstat 1 files changed, 124 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- 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 <time.h>
 #include <ncurses.h>
 
-
+#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);
 		}
 	}