Mercurial > hg > nnchat
comparison main.c @ 466:796508f828f6
Refactor much of the "windowing" UI code into a new module, ui.[ch]
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 26 May 2012 06:56:18 +0300 |
parents | 35d67bd0613b |
children | 607bd4491e79 |
comparison
equal
deleted
inserted
replaced
465:c3b3b6d89084 | 466:796508f828f6 |
---|---|
3 * Written by Matti 'ccr' Hämäläinen | 3 * Written by Matti 'ccr' Hämäläinen |
4 * (C) Copyright 2008-2012 Tecnic Software productions (TNSP) | 4 * (C) Copyright 2008-2012 Tecnic Software productions (TNSP) |
5 */ | 5 */ |
6 #include "util.h" | 6 #include "util.h" |
7 #include "network.h" | 7 #include "network.h" |
8 #include "ui.h" | |
8 #include "th_args.h" | 9 #include "th_args.h" |
9 #include "th_config.h" | 10 #include "th_config.h" |
10 #include <errno.h> | 11 #include <errno.h> |
11 #include <time.h> | 12 #include <time.h> |
12 #ifdef __WIN32 | 13 #ifdef __WIN32 |
14 #undef MOUSE_MOVED | 15 #undef MOUSE_MOVED |
15 #include <shlwapi.h> | 16 #include <shlwapi.h> |
16 #else | 17 #else |
17 #include <sys/wait.h> | 18 #include <sys/wait.h> |
18 #endif | 19 #endif |
19 #ifdef HAVE_NCURSES_H | |
20 #include <ncurses.h> | |
21 #else | |
22 #include <curses.h> | |
23 #endif | |
24 | 20 |
25 #ifdef __WIN32 | 21 #ifdef __WIN32 |
26 #define SET_CONFIG_FILE "nnchat.txt" | 22 #define SET_CONFIG_FILE "nnchat.txt" |
27 #define SET_DIR_SEPARATOR "\\" | 23 #define SET_DIR_SEPARATOR "\\" |
28 #define SET_DELAY (0) | 24 #define SET_DELAY (0) |
35 #define SET_PROFILE_PREFIX "http://www.newbienudes.com/profile/%s/" | 31 #define SET_PROFILE_PREFIX "http://www.newbienudes.com/profile/%s/" |
36 #define SET_NICK_SEPARATOR ':' | 32 #define SET_NICK_SEPARATOR ':' |
37 | 33 |
38 #define SET_MAX_HISTORY (16) // Command history length | 34 #define SET_MAX_HISTORY (16) // Command history length |
39 #define SET_KEEPALIVE (15*60) // Ping/keepalive period in seconds | 35 #define SET_KEEPALIVE (15*60) // Ping/keepalive period in seconds |
40 #define SET_MAX_WINDOWS (32) | |
41 | 36 |
42 | 37 |
43 /* Options | 38 /* Options |
44 */ | 39 */ |
45 int optPort = 8005, | 40 int optPort = 8005, |
61 FILE *optLogFile = NULL; | 56 FILE *optLogFile = NULL; |
62 BOOL setIgnoreMode = FALSE; | 57 BOOL setIgnoreMode = FALSE; |
63 BOOL optDebug = FALSE; | 58 BOOL optDebug = FALSE; |
64 BOOL optLogEnable = FALSE; | 59 BOOL optLogEnable = FALSE; |
65 | 60 |
66 nn_window_t *chatWindows[SET_MAX_WINDOWS], | |
67 *currWin = NULL; | |
68 WINDOW *mainWin = NULL, | |
69 *statusWin = NULL, | |
70 *editWin = NULL; | |
71 | |
72 qlist_t *setIgnoreList = NULL, | 61 qlist_t *setIgnoreList = NULL, |
73 *setIdleMessages = NULL; | 62 *setIdleMessages = NULL; |
74 nn_userhash_t *nnUsers = NULL; | 63 nn_userhash_t *nnUsers = NULL; |
75 char *setConfigFile = NULL, | 64 char *setConfigFile = NULL, |
76 *setBrowser = NULL; | 65 *setBrowser = NULL; |
203 { | 192 { |
204 THERR("Username '%s' already specified on commandline!\n", optUserNameCmd); | 193 THERR("Username '%s' already specified on commandline!\n", optUserNameCmd); |
205 return FALSE; | 194 return FALSE; |
206 } | 195 } |
207 | 196 |
208 return TRUE; | |
209 } | |
210 | |
211 | |
212 nn_window_t *nnwin_find(const char *id) | |
213 { | |
214 int i; | |
215 | |
216 for (i = 0; i < SET_MAX_WINDOWS; i++) | |
217 if (chatWindows[i] != NULL && | |
218 chatWindows[i]->id != NULL && | |
219 th_strcasecmp(id, chatWindows[i]->id) == 0) | |
220 return chatWindows[i]; | |
221 | |
222 return NULL; | |
223 } | |
224 | |
225 | |
226 BOOL nnwin_open(const char *name, BOOL curwin) | |
227 { | |
228 int i; | |
229 nn_window_t *res; | |
230 if (name == NULL) | |
231 return FALSE; | |
232 | |
233 if ((res = nn_window_new(name)) == NULL) | |
234 return FALSE; | |
235 | |
236 for (i = 1; i < SET_MAX_WINDOWS; i++) | |
237 if (chatWindows[i] == NULL) | |
238 { | |
239 res->num = i; | |
240 chatWindows[i] = res; | |
241 if (curwin) | |
242 currWin = res; | |
243 return TRUE; | |
244 } | |
245 | |
246 return FALSE; | |
247 } | |
248 | |
249 | |
250 void nnwin_close(nn_window_t *win) | |
251 { | |
252 int i; | |
253 if (win == NULL) return; | |
254 | |
255 for (i = 1; i < SET_MAX_WINDOWS; i++) | |
256 if (chatWindows[i] == win) | |
257 { | |
258 chatWindows[i] = NULL; | |
259 nn_window_free(win); | |
260 return; | |
261 } | |
262 } | |
263 | |
264 | |
265 void nnwin_update_statusline(void) | |
266 { | |
267 char tmpStr[128]; | |
268 int i; | |
269 | |
270 if (statusWin == NULL) return; | |
271 | |
272 str_get_timestamp(tmpStr, sizeof(tmpStr), "%H:%M:%S"); | |
273 | |
274 wbkgdset(statusWin, COLOR_PAIR(10)); | |
275 werase(statusWin); | |
276 | |
277 wattrset(statusWin, A_BOLD | COLOR_PAIR(11)); | |
278 mvwaddstr(statusWin, 0, 1, tmpStr); | |
279 | |
280 wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); | |
281 waddstr(statusWin, " | "); | |
282 wattrset(statusWin, A_BOLD | COLOR_PAIR(16)); | |
283 waddstr(statusWin, optUserName); | |
284 wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); | |
285 | |
286 wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); | |
287 waddstr(statusWin, " | "); | |
288 wattrset(statusWin, A_BOLD | COLOR_PAIR(11)); | |
289 snprintf(tmpStr, sizeof(tmpStr), "#%06x", optUserColor); | |
290 waddstr(statusWin, tmpStr); | |
291 | |
292 wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); | |
293 waddstr(statusWin, " | WIN: "); | |
294 snprintf(tmpStr, sizeof(tmpStr), "%d: %s / %d", | |
295 currWin->num + 1, | |
296 currWin->id != NULL ? currWin->id : "MAIN", | |
297 currWin->pos); | |
298 waddstr(statusWin, tmpStr); | |
299 | |
300 wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); | |
301 waddstr(statusWin, " | "); | |
302 wattrset(statusWin, A_BOLD | COLOR_PAIR(11)); | |
303 | |
304 for (i = 0; i < SET_MAX_WINDOWS; i++) | |
305 if (chatWindows[i] != NULL && chatWindows[i]->dirty) | |
306 { | |
307 snprintf(tmpStr, sizeof(tmpStr), "%d ", i + 1); | |
308 waddstr(statusWin, tmpStr); | |
309 } | |
310 | |
311 wrefresh(statusWin); | |
312 } | |
313 | |
314 | |
315 void nnwin_update_editbuf(nn_editbuf_t *buf) | |
316 { | |
317 char *tmp; | |
318 if (editWin == NULL || buf == NULL) return; | |
319 | |
320 buf->data[buf->len] = 0; | |
321 tmp = nn_username_decode(th_strdup(buf->data)); | |
322 | |
323 werase(editWin); | |
324 | |
325 wattrset(editWin, A_NORMAL); | |
326 | |
327 if (buf->pos < buf->len) | |
328 { | |
329 waddnstr(editWin, tmp, buf->pos); | |
330 wattrset(editWin, A_REVERSE); | |
331 waddch(editWin, tmp[buf->pos]); | |
332 wattrset(editWin, A_NORMAL); | |
333 waddnstr(editWin, tmp + buf->pos + 1, buf->len - buf->pos - 1); | |
334 } | |
335 else | |
336 { | |
337 waddnstr(editWin, tmp, buf->len); | |
338 wattrset(editWin, A_REVERSE); | |
339 waddch(editWin, ' '); | |
340 wattrset(editWin, A_NORMAL); | |
341 } | |
342 wrefresh(editWin); | |
343 th_free(tmp); | |
344 } | |
345 | |
346 | |
347 int nnwin_print(WINDOW *win, const char *fmt) | |
348 { | |
349 const char *s = fmt; | |
350 int col = 0; | |
351 | |
352 while (*s) | |
353 { | |
354 if (*s == '½') | |
355 { | |
356 s++; | |
357 if (*s == '½') | |
358 { | |
359 waddch(win, ((unsigned char) *s) | col); | |
360 s++; | |
361 } | |
362 else | |
363 { | |
364 memcpy(&col, s, sizeof(int)); | |
365 s += sizeof(int); | |
366 } | |
367 } | |
368 else | |
369 { | |
370 waddch(win, ((unsigned char) *s) | col); | |
371 s++; | |
372 } | |
373 } | |
374 return 0; | |
375 } | |
376 | |
377 | |
378 #define QPUTCH(ch) th_vputch(&(win->buf), &(win->bufsize), &(win->len), ch) | |
379 | |
380 int nnwin_print_buf(nn_window_t *win, const char *fmt) | |
381 { | |
382 const char *s = fmt; | |
383 int col = 0; | |
384 while (*s) | |
385 { | |
386 if (*s == '½') | |
387 { | |
388 s++; | |
389 if (*s == '½') | |
390 { | |
391 QPUTCH(*s); | |
392 QPUTCH(*s); | |
393 win->chlen++; | |
394 } | |
395 else | |
396 { | |
397 int val = 0; | |
398 while (*s >= '0' && *s <= '9') | |
399 { | |
400 val *= 10; | |
401 val += (*s - '0'); | |
402 s++; | |
403 } | |
404 if (*s != '½') return -1; | |
405 | |
406 if (val < 9) | |
407 col = A_DIM | COLOR_PAIR(val); | |
408 else if (val < 30) | |
409 col = A_BOLD | COLOR_PAIR(val - 9); | |
410 | |
411 QPUTCH('½'); | |
412 | |
413 if (!th_growbuf(&(win->buf), &(win->bufsize), &(win->len), sizeof(int))) | |
414 return -2; | |
415 | |
416 memcpy(win->buf + win->len, &col, sizeof(int)); | |
417 win->len += sizeof(int); | |
418 } | |
419 } | |
420 else if (*s == '\n') | |
421 { | |
422 QPUTCH('\n'); | |
423 QPUTCH(0); | |
424 th_ringbuf_add(win->data, win->buf); | |
425 win->buf = NULL; | |
426 win->chlen = 0; | |
427 win->dirty = TRUE; | |
428 } | |
429 else if (*s != '\r') | |
430 { | |
431 QPUTCH((unsigned char) *s == 255 ? ' ' : *s); | |
432 win->chlen++; | |
433 } | |
434 | |
435 s++; | |
436 } | |
437 | |
438 return 0; | |
439 } | |
440 | |
441 | |
442 BOOL nnwin_update_main(BOOL force) | |
443 { | |
444 int h, offs; | |
445 qringbuf_t *buf; | |
446 | |
447 // Check pointers | |
448 if (mainWin == NULL || currWin == NULL) | |
449 return FALSE; | |
450 | |
451 // Check if update is forced or if the window is dirty | |
452 if (!force && !currWin->dirty) | |
453 return FALSE; | |
454 | |
455 // Compute how many lines from backbuffer fit on the screen | |
456 buf = currWin->data; | |
457 h = getmaxy(mainWin); | |
458 | |
459 // Clear and redraw window | |
460 werase(mainWin); | |
461 scrollok(mainWin, 1); | |
462 for (offs = buf->size - h - currWin->pos; offs >= 0 && offs < buf->size - currWin->pos && offs < buf->size; offs++) | |
463 { | |
464 if (buf->data[offs] != NULL) | |
465 nnwin_print(mainWin, buf->data[offs]); | |
466 } | |
467 | |
468 currWin->dirty = FALSE; | |
469 wrefresh(mainWin); | |
470 return TRUE; | 197 return TRUE; |
471 } | 198 } |
472 | 199 |
473 | 200 |
474 int printFile(FILE *outFile, const char *fmt) | 201 int printFile(FILE *outFile, const char *fmt) |
520 fflush(optLogFile); | 247 fflush(optLogFile); |
521 } | 248 } |
522 | 249 |
523 if (!optDaemon && (flags & LOG_WINDOW)) | 250 if (!optDaemon && (flags & LOG_WINDOW)) |
524 { | 251 { |
525 nn_window_t *tmp = win != NULL ? win : chatWindows[0]; | 252 nn_window_t *tmp = (win != NULL) ? win : nnwin_main_window(); |
526 if (flags & LOG_STAMP) nnwin_print_buf(tmp, tmpStr); | 253 if (flags & LOG_STAMP) nnwin_print_buf(tmp, tmpStr); |
527 nnwin_print_buf(tmp, buf); | 254 nnwin_print_buf(tmp, buf); |
528 } | 255 } |
529 | 256 |
530 th_free(buf); | 257 th_free(buf); |
575 } | 302 } |
576 else | 303 else |
577 errorMessages = tmp; | 304 errorMessages = tmp; |
578 } | 305 } |
579 | 306 |
307 | |
580 void errorMsg(const char *fmt, ...) | 308 void errorMsg(const char *fmt, ...) |
581 { | 309 { |
582 va_list ap; | 310 va_list ap; |
583 | 311 |
584 va_start(ap, fmt); | 312 va_start(ap, fmt); |
585 errorMsgV(fmt, ap); | 313 errorMsgV(fmt, ap); |
586 va_end(ap); | 314 va_end(ap); |
587 } | 315 } |
588 | 316 |
317 | |
589 void errorFunc(struct _nn_conn_t *conn, const char *fmt, va_list ap) | 318 void errorFunc(struct _nn_conn_t *conn, const char *fmt, va_list ap) |
590 { | 319 { |
591 (void) conn; | 320 (void) conn; |
592 errorMsgV(fmt, ap); | 321 errorMsgV(fmt, ap); |
593 } | 322 } |
323 | |
594 | 324 |
595 void messageFunc(struct _nn_conn_t *conn, const char *fmt, va_list ap) | 325 void messageFunc(struct _nn_conn_t *conn, const char *fmt, va_list ap) |
596 { | 326 { |
597 (void) conn; | 327 (void) conn; |
598 printMsgV(NULL, LOG_STAMP | LOG_WINDOW | LOG_FILE, fmt, ap); | 328 printMsgV(NULL, LOG_STAMP | LOG_WINDOW | LOG_FILE, fmt, ap); |
1026 printMsgQ(currWin, "No PRV query by name '%s'.\n", name); | 756 printMsgQ(currWin, "No PRV query by name '%s'.\n", name); |
1027 } | 757 } |
1028 } | 758 } |
1029 else | 759 else |
1030 { | 760 { |
1031 if (currWin != chatWindows[0]) | 761 if (currWin != nnwin_main_window()) |
1032 { | 762 { |
1033 nnwin_close(currWin); | 763 nnwin_close(currWin); |
1034 currWin = chatWindows[0]; | 764 currWin = nnwin_main_window(); |
1035 } | 765 } |
1036 else | 766 else |
1037 { | 767 { |
1038 printMsgQ(currWin, "Usage: /close [username]\n"); | 768 printMsgQ(currWin, "Usage: /close [username]\n"); |
1039 printMsgQ(currWin, "/close without username will close the current PRV window. if any.\n"); | 769 printMsgQ(currWin, "/close without username will close the current PRV window. if any.\n"); |
1049 (void) conn; | 779 (void) conn; |
1050 | 780 |
1051 if (arg[0]) | 781 if (arg[0]) |
1052 { | 782 { |
1053 int val = atoi(arg); | 783 int val = atoi(arg); |
1054 if (val >= 1 && val < SET_MAX_WINDOWS) | 784 nn_window_t *win = nnwin_get(val); |
1055 { | 785 if (win != NULL) |
1056 if (chatWindows[val - 1] != NULL) | 786 currWin = win; |
1057 currWin = chatWindows[val - 1]; | |
1058 } | |
1059 else | 787 else |
1060 { | 788 { |
1061 printMsgQ(currWin, "Invalid window number '%s'\n", arg); | 789 printMsgQ(currWin, "Invalid window number '%s'\n", arg); |
1062 return 1; | 790 return 1; |
1063 } | 791 } |
1294 // Check for commands | 1022 // Check for commands |
1295 if (buf[0] == '/') | 1023 if (buf[0] == '/') |
1296 return nn_handle_command(conn, buf); | 1024 return nn_handle_command(conn, buf); |
1297 | 1025 |
1298 // If current window is not the main room window, send private | 1026 // If current window is not the main room window, send private |
1299 if (currWin != chatWindows[0]) | 1027 if (currWin != nnwin_main_window()) |
1300 { | 1028 { |
1301 if (currWin->id != NULL) | 1029 if (currWin->id != NULL) |
1302 { | 1030 { |
1303 char *msg = th_strdup_printf("/prv -to %s -msg %s", currWin->id, buf); | 1031 char *msg = th_strdup_printf("/prv -to %s -msg %s", currWin->id, buf); |
1304 if (msg == NULL) return -3; | 1032 if (msg == NULL) return -3; |
1327 th_free(tmp); | 1055 th_free(tmp); |
1328 return result ? 0 : -1; | 1056 return result ? 0 : -1; |
1329 } | 1057 } |
1330 | 1058 |
1331 | 1059 |
1332 void nnwin_close_windows(void) | |
1333 { | |
1334 if (mainWin) delwin(mainWin); | |
1335 if (statusWin) delwin(statusWin); | |
1336 if (editWin) delwin(editWin); | |
1337 } | |
1338 | |
1339 | |
1340 BOOL nnwin_initialize_windows(void) | |
1341 { | |
1342 int w, h; | |
1343 | |
1344 getmaxyx(stdscr, h, w); | |
1345 | |
1346 nnwin_close_windows(); | |
1347 | |
1348 mainWin = subwin(stdscr, h - 4, w, 0, 0); | |
1349 statusWin = subwin(stdscr, 1, w, h - 4, 0); | |
1350 editWin = subwin(stdscr, 3, w, h - 3, 0); | |
1351 | |
1352 if (mainWin == NULL || statusWin == NULL || editWin == NULL) | |
1353 return FALSE; | |
1354 | |
1355 return TRUE; | |
1356 } | |
1357 | |
1358 | |
1359 void nnwin_update_all(void) | |
1360 { | |
1361 if (mainWin) redrawwin(mainWin); | |
1362 if (statusWin) redrawwin(statusWin); | |
1363 if (editWin) redrawwin(editWin); | |
1364 } | |
1365 | |
1366 | |
1367 static void nn_tabcomplete_replace(nn_editbuf_t *buf, size_t *pi, const size_t startPos, const size_t endPos, char *c) | 1060 static void nn_tabcomplete_replace(nn_editbuf_t *buf, size_t *pi, const size_t startPos, const size_t endPos, char *c) |
1368 { | 1061 { |
1369 size_t i; | 1062 size_t i; |
1370 | 1063 |
1371 for (i = startPos; i <= endPos; i++) | 1064 for (i = startPos; i <= endPos; i++) |
1576 optLogFile = NULL; | 1269 optLogFile = NULL; |
1577 } | 1270 } |
1578 } | 1271 } |
1579 | 1272 |
1580 | 1273 |
1581 char *promptRequester(WINDOW *win, const char *info, BOOL allowEmpty) | |
1582 { | |
1583 char tmpBuf[512], *ptr; | |
1584 size_t pos; | |
1585 int curVis = curs_set(1); | |
1586 | |
1587 echo(); | |
1588 waddstr(win, info); | |
1589 wgetnstr(win, tmpBuf, sizeof(tmpBuf) - 1); | |
1590 noecho(); | |
1591 if (curVis != ERR) | |
1592 curs_set(curVis); | |
1593 | |
1594 for (pos = strlen(tmpBuf) - 1; pos > 0 && th_isspace(tmpBuf[pos]); pos--) | |
1595 tmpBuf[pos] = 0; | |
1596 | |
1597 ptr = str_trim_left(tmpBuf); | |
1598 | |
1599 if (allowEmpty || strlen(ptr) > 0) | |
1600 return th_strdup(ptr); | |
1601 else | |
1602 return NULL; | |
1603 } | |
1604 | |
1605 | |
1606 void printHelp(void) | 1274 void printHelp(void) |
1607 { | 1275 { |
1608 printMsgQ(currWin, "\n" | 1276 printMsgQ(currWin, "\n" |
1609 "NNChat Help\n" | 1277 "NNChat Help\n" |
1610 "===========\n" | 1278 "===========\n" |
1616 | 1284 |
1617 | 1285 |
1618 int main(int argc, char *argv[]) | 1286 int main(int argc, char *argv[]) |
1619 { | 1287 { |
1620 nn_conn_t *conn = NULL; | 1288 nn_conn_t *conn = NULL; |
1621 int curVis = ERR, updateCount = 0; | 1289 int updateCount = 0; |
1622 BOOL argsOK, isError = FALSE, | 1290 BOOL argsOK, isError = FALSE, |
1623 exitProg = FALSE, | 1291 exitProg = FALSE, |
1624 colorSet = FALSE, | 1292 colorSet = FALSE, |
1625 cursesInit = FALSE, | |
1626 networkInit = FALSE, | 1293 networkInit = FALSE, |
1627 insertMode = TRUE, | 1294 insertMode = TRUE, |
1628 firstUpdate = TRUE; | 1295 firstUpdate = TRUE; |
1629 time_t prevTime; | 1296 time_t prevTime; |
1630 char *tmpStr; | 1297 char *tmpStr; |
1631 nn_editbuf_t *editBuf = nn_editbuf_new(NN_TMPBUF_SIZE); | 1298 nn_editbuf_t *editBuf = nn_editbuf_new(NN_TMPBUF_SIZE); |
1632 nn_editbuf_t *histBuf[SET_MAX_HISTORY+2]; | 1299 nn_editbuf_t *histBuf[SET_MAX_HISTORY+2]; |
1633 int histPos = 0, histMax = 0; | 1300 int histPos = 0, histMax = 0, index; |
1634 | 1301 |
1635 cfgitem_t *tmpcfg; | 1302 cfgitem_t *tmpcfg; |
1636 char *setHomeDir = NULL; | 1303 char *setHomeDir = NULL; |
1637 | 1304 |
1638 memset(histBuf, 0, sizeof(histBuf)); | 1305 memset(histBuf, 0, sizeof(histBuf)); |
1761 goto err_exit; | 1428 goto err_exit; |
1762 } | 1429 } |
1763 else | 1430 else |
1764 networkInit = TRUE; | 1431 networkInit = TRUE; |
1765 | 1432 |
1766 // Initialize NCurses | 1433 // Initialize curses windowing |
1767 if (!optDaemon) | 1434 if (!optDaemon && !nnwin_init(SET_DELAY)) |
1768 { | 1435 goto err_exit; |
1769 if (LINES < 0 || LINES > 1000) LINES = 24; | 1436 |
1770 if (COLS < 0 || COLS > 1000) COLS = 80; | 1437 if (cursesInit) |
1771 initscr(); | 1438 nnwin_update_statusline(optUserName, optUserColor); |
1772 raw(); | |
1773 keypad(stdscr, TRUE); | |
1774 noecho(); | |
1775 meta(stdscr, TRUE); | |
1776 timeout(SET_DELAY); | |
1777 curVis = curs_set(0); | |
1778 | |
1779 if (has_colors()) | |
1780 { | |
1781 start_color(); | |
1782 | |
1783 init_pair( 1, COLOR_RED, COLOR_BLACK); | |
1784 init_pair( 2, COLOR_GREEN, COLOR_BLACK); | |
1785 init_pair( 3, COLOR_YELLOW, COLOR_BLACK); | |
1786 init_pair( 4, COLOR_BLUE, COLOR_BLACK); | |
1787 init_pair( 5, COLOR_MAGENTA, COLOR_BLACK); | |
1788 init_pair( 6, COLOR_CYAN, COLOR_BLACK); | |
1789 init_pair( 7, COLOR_WHITE, COLOR_BLACK); | |
1790 init_pair( 8, COLOR_BLACK, COLOR_BLACK); | |
1791 | |
1792 init_pair(10, COLOR_BLACK, COLOR_RED); | |
1793 init_pair(11, COLOR_WHITE, COLOR_RED); | |
1794 init_pair(12, COLOR_GREEN, COLOR_RED); | |
1795 init_pair(13, COLOR_YELLOW, COLOR_RED); | |
1796 init_pair(14, COLOR_BLUE, COLOR_RED); | |
1797 init_pair(15, COLOR_MAGENTA, COLOR_RED); | |
1798 init_pair(16, COLOR_CYAN, COLOR_RED); | |
1799 } | |
1800 | |
1801 cursesInit = TRUE; | |
1802 | |
1803 if (!nnwin_initialize_windows()) | |
1804 goto err_exit; | |
1805 | |
1806 #ifdef PDCURSES | |
1807 PDC_set_title("NNChat v" NN_VERSION); | |
1808 #endif | |
1809 | |
1810 memset(chatWindows, 0, sizeof(chatWindows)); | |
1811 chatWindows[0] = nn_window_new(NULL); | |
1812 currWin = chatWindows[0]; | |
1813 nnwin_update_statusline(); | |
1814 } | |
1815 | 1439 |
1816 // Check if we have username and password | 1440 // Check if we have username and password |
1817 if (cursesInit && (optUserName == NULL || optPassword == NULL)) | 1441 if (cursesInit && (optUserName == NULL || optPassword == NULL)) |
1818 { | 1442 { |
1819 nnwin_print(editWin, "You can avoid this prompt by issuing '/save' after logging in.\n"); | 1443 nnwin_print(editWin, "You can avoid this prompt by issuing '/save' after logging in.\n"); |
1820 optUserName = promptRequester(editWin, "NN username: ", FALSE); | 1444 optUserName = nnwin_prompt_requester(editWin, "NN username: ", FALSE); |
1821 optPassword = promptRequester(editWin, "NN password: ", TRUE); | 1445 optPassword = nnwin_prompt_requester(editWin, "NN password: ", TRUE); |
1822 } | 1446 } |
1823 | 1447 |
1824 if (optUserName == NULL || optPassword == NULL) | 1448 if (optUserName == NULL || optPassword == NULL) |
1825 { | 1449 { |
1826 errorMsg("Username and/or password not specified.\n"); | 1450 errorMsg("Username and/or password not specified.\n"); |
1907 // Initialize rest of interactive UI code | 1531 // Initialize rest of interactive UI code |
1908 nn_editbuf_clear(editBuf); | 1532 nn_editbuf_clear(editBuf); |
1909 | 1533 |
1910 // First update of screen | 1534 // First update of screen |
1911 nnwin_update_editbuf(editBuf); | 1535 nnwin_update_editbuf(editBuf); |
1912 nnwin_update_statusline(); | 1536 nnwin_update_statusline(optUserName, optUserColor); |
1913 | 1537 |
1914 printMsg(NULL, "%s v%s - %s\n", th_prog_name, th_prog_version, th_prog_fullname); | 1538 printMsg(NULL, "%s v%s - %s\n", th_prog_name, th_prog_version, th_prog_fullname); |
1915 printMsg(NULL, "%s\n", th_prog_author); | 1539 printMsg(NULL, "%s\n", th_prog_author); |
1916 printMsg(NULL, "%s\n", th_prog_license); | 1540 printMsg(NULL, "%s\n", th_prog_license); |
1917 } | 1541 } |
2040 wgetch(stdscr); | 1664 wgetch(stdscr); |
2041 } | 1665 } |
2042 if (c >= 0x31 && c <= 0x39) | 1666 if (c >= 0x31 && c <= 0x39) |
2043 { | 1667 { |
2044 // Chat window switching via Meta/Esc-[1..9] | 1668 // Chat window switching via Meta/Esc-[1..9] |
2045 int win = c - 0x31; | 1669 nn_window_t *win = nnwin_get(c - 0x30); |
2046 if (win < SET_MAX_WINDOWS && chatWindows[win] != NULL) | 1670 if (win != NULL) |
2047 { | 1671 { |
2048 currWin = chatWindows[win]; | 1672 currWin = win; |
2049 update = updateMain = TRUE; | 1673 update = updateMain = TRUE; |
2050 } | 1674 } |
2051 c = ERR; | 1675 c = ERR; |
2052 } | 1676 } |
2053 else | 1677 else |
2076 case KEY_RESIZE: | 1700 case KEY_RESIZE: |
2077 resize_term(0, 0); | 1701 resize_term(0, 0); |
2078 erase(); | 1702 erase(); |
2079 timeout(SET_DELAY); | 1703 timeout(SET_DELAY); |
2080 | 1704 |
2081 if (!nnwin_initialize_windows()) | 1705 if (!nnwin_init_windows()) |
2082 { | 1706 { |
2083 errorMsg("Error resizing curses chatWindows\n"); | 1707 errorMsg("Error resizing curses chatWindows\n"); |
2084 isError = TRUE; | 1708 isError = TRUE; |
2085 } | 1709 } |
2086 update = updateMain = TRUE; | 1710 update = updateMain = TRUE; |
2289 nnwin_update_main(updateMain); | 1913 nnwin_update_main(updateMain); |
2290 | 1914 |
2291 if (update || firstUpdate) | 1915 if (update || firstUpdate) |
2292 { | 1916 { |
2293 // Update edit line | 1917 // Update edit line |
2294 nnwin_update_statusline(); | 1918 nnwin_update_statusline(optUserName, optUserColor); |
2295 nnwin_update_editbuf(editBuf); | 1919 nnwin_update_editbuf(editBuf); |
2296 firstUpdate = FALSE; // a nasty hack ... | 1920 firstUpdate = FALSE; // a nasty hack ... |
2297 } | 1921 } |
2298 | 1922 |
2299 } // cursesInit | 1923 } // cursesInit |
2313 { | 1937 { |
2314 colorSet = TRUE; | 1938 colorSet = TRUE; |
2315 nn_conn_send_msg_v(conn, optUserNameEnc, "%%2FSetFontColor%%20%%2Dcolor%%20%06X", optUserColor); | 1939 nn_conn_send_msg_v(conn, optUserNameEnc, "%%2FSetFontColor%%20%%2Dcolor%%20%06X", optUserColor); |
2316 } | 1940 } |
2317 | 1941 |
2318 nnwin_update_statusline(); | 1942 nnwin_update_statusline(optUserName, optUserColor); |
2319 nnwin_update_editbuf(editBuf); | 1943 nnwin_update_editbuf(editBuf); |
2320 updateCount = 0; | 1944 updateCount = 0; |
2321 } | 1945 } |
2322 | 1946 |
2323 } | 1947 } |
2328 th_free(setHomeDir); | 1952 th_free(setHomeDir); |
2329 th_llist_free_func(setIdleMessages, th_free); | 1953 th_llist_free_func(setIdleMessages, th_free); |
2330 nn_userhash_free(nnUsers); | 1954 nn_userhash_free(nnUsers); |
2331 nn_editbuf_free(editBuf); | 1955 nn_editbuf_free(editBuf); |
2332 | 1956 |
2333 { | 1957 for (index = 0; index <= SET_MAX_HISTORY; index++) |
2334 int i; | 1958 nn_editbuf_free(histBuf[index]); |
2335 for (i = 0; i <= SET_MAX_HISTORY; i++) | 1959 |
2336 nn_editbuf_free(histBuf[i]); | 1960 nnwin_shutdown(); |
2337 | |
2338 for (i = 0; i < SET_MAX_WINDOWS; i++) | |
2339 nn_window_free(chatWindows[i]); | |
2340 } | |
2341 | 1961 |
2342 #ifdef __WIN32 | 1962 #ifdef __WIN32 |
2343 if (errorMessages) | 1963 if (errorMessages) |
2344 { | 1964 { |
2345 char *tmp; | 1965 char *tmp; |
2347 tmp = promptRequester(editWin, "Press enter to quit.\n", FALSE); | 1967 tmp = promptRequester(editWin, "Press enter to quit.\n", FALSE); |
2348 th_free(tmp); | 1968 th_free(tmp); |
2349 } | 1969 } |
2350 #endif | 1970 #endif |
2351 | 1971 |
2352 if (cursesInit) | |
2353 { | |
2354 if (curVis != ERR) | |
2355 curs_set(curVis); | |
2356 nnwin_close_windows(); | |
2357 endwin(); | |
2358 THMSG(1, "NCurses deinitialized.\n"); | |
2359 } | |
2360 | 1972 |
2361 #ifndef __WIN32 | 1973 #ifndef __WIN32 |
2362 if (errorMessages) | 1974 if (errorMessages) |
2363 THERR("%s", errorMessages); | 1975 THERR("%s", errorMessages); |
2364 #endif | 1976 #endif |