|
|
@@ -13,6 +13,7 @@ |
|
|
|
#include <signal.h> |
|
|
|
#include <time.h> |
|
|
|
#include <errno.h> |
|
|
|
#include <ctype.h> |
|
|
|
|
|
|
|
#include <sys/ioctl.h> |
|
|
|
#include <sys/types.h> |
|
|
@@ -33,12 +34,16 @@ |
|
|
|
#define C_A 1 /* BOL */ |
|
|
|
#define C_B 2 /* BOL */ |
|
|
|
#define C_E 5 /* EOL */ |
|
|
|
#define C_U 21 /* CLR TO BOL */ |
|
|
|
#define C_H 8 /* BACKSPACE */ |
|
|
|
#define C_L 12 /* REFRESH */ |
|
|
|
#define C_U 21 /* CLR TO BOL */ |
|
|
|
#define C_W 23 /* DELETE PREVWORD */ |
|
|
|
#define C_L 12 /* Signal SIGWINCH */ |
|
|
|
#define C_R 18 /* hah not going to implement that */ |
|
|
|
|
|
|
|
#define C_T 20 /* scroll up */ |
|
|
|
#define C_N 14 /* scroll down */ |
|
|
|
|
|
|
|
#define UP 258 |
|
|
|
#define DOWN 259 |
|
|
|
#define LEFT 260 |
|
|
@@ -64,8 +69,8 @@ void fillline(int y, int xstart, char c) { |
|
|
|
|
|
|
|
#define TITLE(str) do { mvprintw(0,0,str); fillline(0,strlen(str),'-'); } while (0) |
|
|
|
|
|
|
|
void hardrefresh(void) { |
|
|
|
mvprintw(g_y - 2, 0, "max screen %d; max ours %d", (g_y - 3) * SENDMAX, RECVMAX); |
|
|
|
void decoration(void) { |
|
|
|
/* mvprintw(g_y - 2, 0, "max screen %d; max ours %d", (g_y - 3) * SENDMAX, RECVMAX); */ |
|
|
|
TITLE("-- MOONTALK "); |
|
|
|
fillline(g_y - 3, 0, '-'); |
|
|
|
} |
|
|
@@ -90,7 +95,7 @@ void init_screen(int x) { |
|
|
|
nodelay(stdscr, TRUE); |
|
|
|
ESCDELAY = 0; |
|
|
|
clear(); |
|
|
|
hardrefresh(); |
|
|
|
decoration(); |
|
|
|
g_hardrefresh = 1; |
|
|
|
|
|
|
|
signal(SIGWINCH, init_screen); |
|
|
@@ -99,7 +104,7 @@ void init_screen(int x) { |
|
|
|
void stop(void) { |
|
|
|
int sockfd = g_sockfd; |
|
|
|
endwin(); |
|
|
|
printf("stopping now. maybe you forgot torify?\n"); |
|
|
|
printf("stopping now.\n"); |
|
|
|
if (sockfd > -1) { close(sockfd); } |
|
|
|
g_sockfd = -1; |
|
|
|
} |
|
|
@@ -167,15 +172,14 @@ size_t lastline(char * buf, size_t len) { |
|
|
|
} |
|
|
|
|
|
|
|
void clearline(int y) { |
|
|
|
int x = g_x; |
|
|
|
int oldy, oldx; |
|
|
|
getyx(stdscr, oldy, oldx); |
|
|
|
move(y, x); |
|
|
|
move(y, 0); |
|
|
|
clrtoeol(); |
|
|
|
move(oldy, oldx); |
|
|
|
} |
|
|
|
|
|
|
|
#define UPDATE_TIME() do { \ |
|
|
|
#define UPDATE_TIME() do { \ |
|
|
|
t = time(NULL); \ |
|
|
|
tm = gmtime(&t); \ |
|
|
|
strftime(sendbuf, TIMESTRMAX, TIMESTR, tm); \ |
|
|
@@ -222,21 +226,21 @@ int main (int argc, char ** argv) { |
|
|
|
sockfd = init_connection(serv, port); |
|
|
|
|
|
|
|
char raw[SENDMAX + RECVMAX]; |
|
|
|
char * sendbuf = raw, * recvbuf = raw + SENDMAX; |
|
|
|
char * sendbuf = raw, * recvbuf = raw + SENDMAX, * off = recvbuf; |
|
|
|
size_t sendminlen; |
|
|
|
size_t sendlen = sendminlen, recvlen = 1; |
|
|
|
size_t sendlen = sendminlen, recvlen = 1, offlen = (g_y - 4) * 255; |
|
|
|
|
|
|
|
time_t t; |
|
|
|
struct tm * tm; |
|
|
|
useconds_t frame = 25; |
|
|
|
useconds_t frame = 30; |
|
|
|
useconds_t interval = 1000000 / frame; |
|
|
|
int32_t ct = 0; |
|
|
|
int lc, off; |
|
|
|
/* int lc, off; */ |
|
|
|
int hardrefresh = 0, inputrefresh = 1; |
|
|
|
int ch; |
|
|
|
int ret; |
|
|
|
|
|
|
|
sendminlen = TIMESTRMAX; |
|
|
|
UPDATE_TIME(); |
|
|
|
|
|
|
|
memcpy(sendbuf + sendminlen, name, strlen(name)); |
|
|
|
sendminlen += strlen(name); |
|
|
@@ -244,56 +248,102 @@ int main (int argc, char ** argv) { |
|
|
|
sendminlen += 2; |
|
|
|
sendlen = sendminlen; |
|
|
|
|
|
|
|
hardrefresh(); |
|
|
|
decoration(); |
|
|
|
mvaddnstr(g_y - 1, 0, sendbuf, sendlen); |
|
|
|
|
|
|
|
while (1) { |
|
|
|
nextloop: |
|
|
|
hardrefresh |= g_hardrefresh; |
|
|
|
/* update */ |
|
|
|
if (ct % (frame) == 0) { |
|
|
|
if (ct % (frame) == 0 || inputrefresh) { |
|
|
|
UPDATE_TIME(); |
|
|
|
mvaddnstr(g_y - 1, 0, sendbuf, sendlen); |
|
|
|
} |
|
|
|
/* recv */ |
|
|
|
if (ct % (frame * 2) == 0) { |
|
|
|
ret = recv(sockfd, recvbuf + recvlen, RECVMAX - recvlen, MSG_DONTWAIT); |
|
|
|
if (ret > 0 || g_hardrefresh) { |
|
|
|
ret = recv(sockfd, recvbuf + recvlen - 1, RECVMAX - recvlen + 1, MSG_DONTWAIT); |
|
|
|
mvprintw(g_y - 2, 150, "ct:%d:%d:called", ct, ret); |
|
|
|
if (ret > -1) { |
|
|
|
recvlen += ret; |
|
|
|
lc = countlines(recvbuf, recvlen); |
|
|
|
off = lc - g_y - 4; |
|
|
|
off = getoff(recvbuf, recvlen, (off > 0) * off, '\n'); |
|
|
|
mvaddnstr(1, 0, recvbuf + off, recvlen - off); |
|
|
|
g_hardrefresh = 0; |
|
|
|
|
|
|
|
mvprintw(g_y - 2, 50, "rendstat ct:%d:%d:%ld", ct, ret, recvlen); |
|
|
|
if (ret > 0 && recvbuf[recvlen-1] == '\n') { |
|
|
|
mvprintw(g_y - 2, 0, "newline at %ld", recvlen-1); |
|
|
|
} |
|
|
|
mvprintw(g_y - 2, 130, "ct:%d:rendered", ct); |
|
|
|
hardrefresh = 1; |
|
|
|
} |
|
|
|
} |
|
|
|
if (hardrefresh) { |
|
|
|
mvprintw(g_y - 2, 100, "ct:%d:REFRESH INVOKED", ct); |
|
|
|
mvaddnstr(1, 0, off, offlen); |
|
|
|
hardrefresh = 0; |
|
|
|
g_hardrefresh = 0; |
|
|
|
} |
|
|
|
/* send */ |
|
|
|
while ((ch = getch()) != -1) { |
|
|
|
if (ch == '\n') { |
|
|
|
if (sendlen == sendminlen) { continue; } |
|
|
|
UPDATE_TIME(); |
|
|
|
sendbuf[sendlen++] = '\n'; /* terminator */ |
|
|
|
send(sockfd, sendbuf, sendlen, 0); |
|
|
|
memcpy(recvbuf + recvlen, sendbuf, (sendlen + recvlen < RECVMAX) * sendlen); |
|
|
|
recvlen += sendlen; |
|
|
|
mvaddnstr(1, 0, recvbuf, recvlen); |
|
|
|
if (sendlen == sendminlen) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
if (sendlen + 1 < SENDMAX) |
|
|
|
{ sendbuf[sendlen++] = '\n'; } |
|
|
|
if (send(sockfd, sendbuf, sendlen, 0) > 0) { |
|
|
|
memcpy(recvbuf + recvlen - 1, sendbuf, (sendlen + recvlen - 1 < RECVMAX) * sendlen); |
|
|
|
recvlen += sendlen; |
|
|
|
hardrefresh = 1; |
|
|
|
} else { |
|
|
|
mvprintw(g_y - 2, 0, "message failed: %s", strerror(errno)); |
|
|
|
} |
|
|
|
mvaddch(g_y - 1, sendminlen, ' '); |
|
|
|
inputrefresh = 1; |
|
|
|
clearline(g_y - 1); |
|
|
|
sendlen = sendminlen; |
|
|
|
} |
|
|
|
else if (ch == C_D) { |
|
|
|
exit(0); |
|
|
|
else if ((ch > 31 && ch < 127)) { |
|
|
|
if (sendlen + 1 < SENDMAX) |
|
|
|
{ sendbuf[sendlen++] = ch; } |
|
|
|
mvaddnstr(g_y - 1, 0, sendbuf, sendlen); |
|
|
|
} |
|
|
|
else if (ch == BACKSPACE) { |
|
|
|
else if (ch == BACKSPACE || ch == C_H) { |
|
|
|
inputrefresh = 1; |
|
|
|
clearline(g_y - 1); |
|
|
|
if (sendlen - 1 >= sendminlen) |
|
|
|
{ mvaddch(g_y - 1, --sendlen, ' '); } |
|
|
|
mvaddnstr(g_y - 1, 0, sendbuf, sendlen); |
|
|
|
move(g_y - 1, sendlen); |
|
|
|
goto nextloop; |
|
|
|
} |
|
|
|
else if (ch > 31 && ch < 127) { |
|
|
|
if (sendlen + 1 < SENDMAX) |
|
|
|
{ sendbuf[sendlen++] = ch; } |
|
|
|
mvaddnstr(g_y - 1, 0, sendbuf, sendlen); |
|
|
|
else if (ch == C_T) { |
|
|
|
while (*off != '\n') { --off; } |
|
|
|
if (*off == '\n') { ++off; } |
|
|
|
hardrefresh = 1; |
|
|
|
} |
|
|
|
else if (ch == C_N) { |
|
|
|
while (*off != '\n') { ++off; } |
|
|
|
if (*off == '\n') { ++off; } |
|
|
|
hardrefresh = 1; |
|
|
|
} |
|
|
|
else if (ch == C_W) { |
|
|
|
while (sendlen > sendminlen && ispunct(sendbuf[sendlen - 1])) { --sendlen; } |
|
|
|
while (sendlen > sendminlen && isspace(sendbuf[sendlen - 1])) { --sendlen; } |
|
|
|
while (sendlen > sendminlen && isalnum(sendbuf[sendlen - 1])) { --sendlen; } |
|
|
|
inputrefresh = 1; |
|
|
|
clearline(g_y - 1); |
|
|
|
goto nextloop; |
|
|
|
} |
|
|
|
else if (ch == C_L) { |
|
|
|
clear(); |
|
|
|
decoration(); |
|
|
|
hardrefresh = 1; |
|
|
|
ct = 0; |
|
|
|
goto nextloop; |
|
|
|
} |
|
|
|
else if (ch == C_D) { |
|
|
|
exit(0); |
|
|
|
} |
|
|
|
} |
|
|
|
/* frame update */ |
|
|
|
move(g_y - 1, sendlen); |
|
|
|
++ct; |
|
|
|
refresh(); |
|
|
|