Mercurial > hg > nnchat
view ui.c @ 475:f7d20fbf821e dev-1_0
Bump version.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 26 May 2012 07:47:15 +0300 |
parents | 796508f828f6 |
children | 56689f94e827 |
line wrap: on
line source
/* * NNChat - Custom chat client for NewbieNudes.com chatrooms * Written by Matti 'ccr' Hämäläinen * (C) Copyright 2008-2012 Tecnic Software productions (TNSP) */ #include "util.h" #include "ui.h" nn_window_t *chatWindows[SET_MAX_WINDOWS], *currWin = NULL; BOOL cursesInit = FALSE; int cursorVisible = ERR; WINDOW *mainWin = NULL, *statusWin = NULL, *editWin = NULL; static nn_window_t *nn_window_new(const char *id) { nn_window_t *res = th_calloc(1, sizeof(nn_window_t)); if (res == NULL) return NULL; res->data = th_ringbuf_new(NN_BACKBUF_LEN, th_free); if (res->data == NULL) { th_free(res); return NULL; } res->id = th_strdup(id); return res; } static void nn_window_free(nn_window_t *win) { if (win != NULL) { th_ringbuf_free(win->data); th_free(win->id); th_free(win); } } nn_window_t *nnwin_main_window() { return chatWindows[0]; } nn_window_t *nnwin_get(const int index) { if (index >= 1 && index <= SET_MAX_WINDOWS) return chatWindows[index - 1]; else return 0; } BOOL nnwin_init(int delay) { if (LINES < 0 || LINES > 1000) LINES = 24; if (COLS < 0 || COLS > 1000) COLS = 80; initscr(); raw(); keypad(stdscr, TRUE); noecho(); meta(stdscr, TRUE); timeout(delay); cursorVisible = curs_set(0); if (has_colors()) { start_color(); init_pair( 1, COLOR_RED, COLOR_BLACK); init_pair( 2, COLOR_GREEN, COLOR_BLACK); init_pair( 3, COLOR_YELLOW, COLOR_BLACK); init_pair( 4, COLOR_BLUE, COLOR_BLACK); init_pair( 5, COLOR_MAGENTA, COLOR_BLACK); init_pair( 6, COLOR_CYAN, COLOR_BLACK); init_pair( 7, COLOR_WHITE, COLOR_BLACK); init_pair( 8, COLOR_BLACK, COLOR_BLACK); init_pair(10, COLOR_BLACK, COLOR_RED); init_pair(11, COLOR_WHITE, COLOR_RED); init_pair(12, COLOR_GREEN, COLOR_RED); init_pair(13, COLOR_YELLOW, COLOR_RED); init_pair(14, COLOR_BLUE, COLOR_RED); init_pair(15, COLOR_MAGENTA, COLOR_RED); init_pair(16, COLOR_CYAN, COLOR_RED); } cursesInit = TRUE; if (!nnwin_init_windows()) return FALSE; #ifdef PDCURSES PDC_set_title("NNChat v" NN_VERSION); #endif memset(chatWindows, 0, sizeof(chatWindows)); chatWindows[0] = nn_window_new(NULL); currWin = chatWindows[0]; return TRUE; } void nnwin_shutdown() { int i; for (i = 0; i < SET_MAX_WINDOWS; i++) nn_window_free(chatWindows[i]); if (cursesInit) { if (cursorVisible != ERR) curs_set(cursorVisible); nnwin_close_windows(); endwin(); THMSG(1, "NCurses deinitialized.\n"); } } nn_window_t *nnwin_find(const char *id) { int i; for (i = 0; i < SET_MAX_WINDOWS; i++) { if (chatWindows[i] != NULL && chatWindows[i]->id != NULL && th_strcasecmp(id, chatWindows[i]->id) == 0) return chatWindows[i]; } return NULL; } BOOL nnwin_open(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 nnwin_close(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 nnwin_update_statusline(char *optUserName, int optUserColor) { char tmpStr[128]; int i; if (statusWin == NULL) return; str_get_timestamp(tmpStr, sizeof(tmpStr), "%H:%M:%S"); wbkgdset(statusWin, COLOR_PAIR(10)); werase(statusWin); wattrset(statusWin, A_BOLD | COLOR_PAIR(11)); mvwaddstr(statusWin, 0, 1, tmpStr); wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); waddstr(statusWin, " | "); wattrset(statusWin, A_BOLD | COLOR_PAIR(16)); 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)); snprintf(tmpStr, sizeof(tmpStr), "#%06x", optUserColor); waddstr(statusWin, tmpStr); wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); waddstr(statusWin, " | WIN: "); snprintf(tmpStr, sizeof(tmpStr), "%d: %s / %d", currWin->num + 1, currWin->id != NULL ? currWin->id : "MAIN", currWin->pos); waddstr(statusWin, tmpStr); wattrset(statusWin, A_BOLD | COLOR_PAIR(13)); waddstr(statusWin, " | "); wattrset(statusWin, A_BOLD | COLOR_PAIR(11)); 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 nnwin_update_editbuf(nn_editbuf_t *buf) { char *tmp; if (editWin == NULL || buf == NULL) return; buf->data[buf->len] = 0; tmp = nn_username_decode(th_strdup(buf->data)); werase(editWin); wattrset(editWin, A_NORMAL); if (buf->pos < buf->len) { waddnstr(editWin, tmp, buf->pos); wattrset(editWin, A_REVERSE); waddch(editWin, tmp[buf->pos]); wattrset(editWin, A_NORMAL); waddnstr(editWin, tmp + buf->pos + 1, buf->len - buf->pos - 1); } else { waddnstr(editWin, tmp, buf->len); wattrset(editWin, A_REVERSE); waddch(editWin, ' '); wattrset(editWin, A_NORMAL); } wrefresh(editWin); th_free(tmp); } int nnwin_print(WINDOW *win, const char *fmt) { const char *s = fmt; int col = 0; while (*s) { if (*s == '½') { s++; if (*s == '½') { waddch(win, ((unsigned char) *s) | col); s++; } else { memcpy(&col, s, sizeof(int)); s += sizeof(int); } } else { waddch(win, ((unsigned char) *s) | col); s++; } } return 0; } #define QPUTCH(ch) th_vputch(&(win->buf), &(win->bufsize), &(win->len), ch) int nnwin_print_buf(nn_window_t *win, const char *fmt) { const char *s = fmt; int col = 0; while (*s) { if (*s == '½') { s++; if (*s == '½') { QPUTCH(*s); QPUTCH(*s); win->chlen++; } else { int val = 0; while (*s >= '0' && *s <= '9') { val *= 10; val += (*s - '0'); s++; } if (*s != '½') return -1; if (val < 9) col = A_DIM | COLOR_PAIR(val); else if (val < 30) col = A_BOLD | COLOR_PAIR(val - 9); QPUTCH('½'); if (!th_growbuf(&(win->buf), &(win->bufsize), &(win->len), sizeof(int))) return -2; memcpy(win->buf + win->len, &col, sizeof(int)); win->len += sizeof(int); } } else if (*s == '\n') { QPUTCH('\n'); QPUTCH(0); th_ringbuf_add(win->data, win->buf); win->buf = NULL; win->chlen = 0; win->dirty = TRUE; } else if (*s != '\r') { QPUTCH((unsigned char) *s == 255 ? ' ' : *s); win->chlen++; } s++; } return 0; } void nnwin_update_all(void) { if (mainWin) redrawwin(mainWin); if (statusWin) redrawwin(statusWin); if (editWin) redrawwin(editWin); } char *nnwin_prompt_requester(WINDOW *win, const char *info, BOOL allowEmpty) { char tmpBuf[512], *ptr; size_t pos; int curSave = curs_set(1); echo(); waddstr(win, info); wgetnstr(win, tmpBuf, sizeof(tmpBuf) - 1); noecho(); if (curSave != ERR) curs_set(curSave); for (pos = strlen(tmpBuf) - 1; pos > 0 && th_isspace(tmpBuf[pos]); pos--) tmpBuf[pos] = 0; ptr = str_trim_left(tmpBuf); if (allowEmpty || strlen(ptr) > 0) return th_strdup(ptr); else return NULL; } BOOL nnwin_update_main(BOOL force) { int h, offs; qringbuf_t *buf; // Check pointers if (mainWin == NULL || currWin == NULL) return FALSE; // Check if update is forced or if the window is dirty if (!force && !currWin->dirty) return FALSE; // Compute how many lines from backbuffer fit on the screen buf = currWin->data; h = getmaxy(mainWin); // Clear and redraw window werase(mainWin); scrollok(mainWin, 1); for (offs = buf->size - h - currWin->pos; offs >= 0 && offs < buf->size - currWin->pos && offs < buf->size; offs++) { if (buf->data[offs] != NULL) nnwin_print(mainWin, buf->data[offs]); } currWin->dirty = FALSE; wrefresh(mainWin); return TRUE; } void nnwin_close_windows(void) { if (mainWin) delwin(mainWin); if (statusWin) delwin(statusWin); if (editWin) delwin(editWin); } BOOL nnwin_init_windows(void) { int w, h; getmaxyx(stdscr, h, w); nnwin_close_windows(); mainWin = subwin(stdscr, h - 4, w, 0, 0); statusWin = subwin(stdscr, 1, w, h - 4, 0); editWin = subwin(stdscr, 3, w, h - 3, 0); if (mainWin == NULL || statusWin == NULL || editWin == NULL) return FALSE; return TRUE; }