hirc

IRC client
Log | Files | Refs

commit e8ff69142a73deeb3406ea19cb752cebfc4c7527
parent 03fc2cb2391f4138bed4538bab3ab610045d83bd
Author: hhvn <dev@hhvn.uk>
Date:   Sun, 31 Oct 2021 10:54:30 +0000

ui.c hirc.h hist.c: width aware printing

Diffstat:
Mhirc.h | 3++-
Mhist.c | 2+-
Mui.c | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
3 files changed, 81 insertions(+), 21 deletions(-)

diff --git a/hirc.h b/hirc.h @@ -99,7 +99,8 @@ void ui_draw_buflist(void); int ui_buflist_count(int *ret_servers, int *ret_channels); void ui_buflist_select(int num); int ui_get_pair(short fg, short bg); -int ui_wprintc(WINDOW *window, char *format, ...); +int ui_wprintc(struct Window *window, int lines, char *format, ...); +int ui_strlenc(struct Window *window, char *s, int *lines); void ui_select(struct Server *server, struct Channel *channel); void ui_error_(char *file, int line, char *format, ...); #define ui_error(format, ...) ui_error_(__FILE__, __LINE__, format, __VA_ARGS__); diff --git a/hist.c b/hist.c @@ -100,7 +100,7 @@ hist_add(struct Server *server, struct HistInfo *histinfo, struct Nick *from, // XXX if (options & HIST_SHOW) { - ui_wprintc(windows[Win_main].window, "!%lld :%s %s\n", (long long)new->timestamp, nick_strprefix(new->from), new->raw); + ui_wprintc(&windows[Win_main], 0, "!%lld :%s %s\n", (long long)new->timestamp, nick_strprefix(new->from), new->raw); windows[Win_main].redraw = 1; } diff --git a/ui.c b/ui.c @@ -387,13 +387,14 @@ ui_draw_buflist(void) { } int -ui_wprintc(WINDOW *window, char *format, ...) { +ui_wprintc(struct Window *window, int lines, char *format, ...) { char str[1024], *s; va_list ap; int ret; attr_t curattr; int temp; /* used only for wattr_get, because ncurses is dumb */ + int cc, lc, elc; char colourbuf[2][3]; int colours[2]; int colour = 0; @@ -403,18 +404,21 @@ ui_wprintc(WINDOW *window, char *format, ...) { int italic = 0; va_start(ap, format); - if ((ret = vsnprintf(str, sizeof(str), format, ap)) < 0) { - va_end(ap); + ret = vsnprintf(str, sizeof(str), format, ap); + va_end(ap); + if (ret < 0) return ret; - } - for (s = str; s && *s; s++) { + if (lines < 0) + ui_strlenc(window, str, &elc); + + for (ret = cc = lc = 0, s = str; s && *s; s++) { switch (*s) { case 2: /* ^B */ if (bold) - wattroff(window, A_BOLD); + wattroff(window->window, A_BOLD); else - wattron(window, A_BOLD); + wattron(window->window, A_BOLD); bold = bold ? 0 : 1; break; case 3: /* ^C */ @@ -449,15 +453,15 @@ ui_wprintc(WINDOW *window, char *format, ...) { colours[0] = colourbuf[0][0] ? atoi(colourbuf[0]) : 99; colours[1] = colourbuf[1][0] ? atoi(colourbuf[1]) : 99; - wattr_get(window, &curattr, &temp, NULL); - wattr_set(window, curattr, ui_get_pair(colours[0], colours[1]), NULL); + wattr_get(window->window, &curattr, &temp, NULL); + wattr_set(window->window, curattr, ui_get_pair(colours[0], colours[1]), NULL); colour = 1; break; case 9: /* ^I */ if (italic) - wattroff(window, A_ITALIC); + wattroff(window->window, A_ITALIC); else - wattron(window, A_ITALIC); + wattron(window->window, A_ITALIC); italic = italic ? 0 : 1; break; case 15: /* ^O */ @@ -468,39 +472,94 @@ ui_wprintc(WINDOW *window, char *format, ...) { italic = 0; /* Setting A_NORMAL turns everything off, * without using 5 different attroffs */ - wattrset(window, A_NORMAL); + wattrset(window->window, A_NORMAL); break; case 18: /* ^R */ if (reverse) - wattroff(window, A_REVERSE); + wattroff(window->window, A_REVERSE); else - wattron(window, A_REVERSE); + wattron(window->window, A_REVERSE); reverse = reverse ? 0 : 1; break; case 21: /* ^U */ if (underline) - wattroff(window, A_UNDERLINE); + wattroff(window->window, A_UNDERLINE); else - wattron(window, A_UNDERLINE); + wattron(window->window, A_UNDERLINE); underline = underline ? 0 : 1; break; default: - waddch(window, *s); + cc++; + if (lines > 0 && lc >= lines) + goto end; + if (!lines || lines > 0 || (lines < 0 && lc >= elc + lines)) { + waddch(window->window, *s); + ret++; + } + if (cc == window->w) { + lc++; + cc = 0; + } break; } } +end: colour = 0; bold = 0; underline =0; reverse = 0; italic = 0; - wattrset(window, A_NORMAL); + wattrset(window->window, A_NORMAL); - va_end(ap); return ret; } +int +ui_strlenc(struct Window *window, char *s, int *lines) { + int ret, cc, lc; + + for (ret = cc = lc = 0; s && *s; s++) { + switch (*s) { + case 2: /* ^B */ + case 9: /* ^I */ + case 15: /* ^O */ + case 18: /* ^R */ + case 21: /* ^U */ + break; + case 3: /* ^C */ + if (*s && isdigit(*(s+1))) + s += 1; + if (*s && isdigit(*(s+1))) + s += 1; + if (*s && *(s+1) == ',' && isdigit(*(s+2))) + s += 2; + if (*s && *(s-1) == ',' && isdigit(*(s+1))) + s += 1; + break; + default: + cc++; + ret++; + if (cc == window->w) { + lc++; + cc = 0; + } + break; + } + } + + if (lines) + *lines = lc; + return ret; +} + +void +ui_draw_main(void) { + int y; + + y = windows[Win_main].h - 1; +} + void ui_select(struct Server *server, struct Channel *channel) { selected.channel = channel;