hirc

IRC client
Log | Files | Refs

commit 366ba47f97f33d1e537f46ab04119b6f285af345
parent f19650a88927ff9e2049d3804c6aa16d24d473cb
Author: hhvn <dev@hhvn.uk>
Date:   Thu, 28 Oct 2021 12:57:41 +0100

ui.c hirc.h: parse control codes and draw using attrs

Diffstat:
Mhirc.h | 1+
Mui.c | 109+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 110 insertions(+), 0 deletions(-)

diff --git a/hirc.h b/hirc.h @@ -98,6 +98,7 @@ void ui_draw_nicklist(void); void ui_draw_buflist(void); int ui_buflist_count(int *ret_servers, int *ret_channels); void ui_buflist_select(int num); +int ui_wprintc(WINDOW *window, char *format, ...); 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/ui.c b/ui.c @@ -355,6 +355,115 @@ ui_draw_buflist(void) { len = wprintw(windows[Win_buflist].window, "[S: %02d | C: %02d]", sc, cc); } +int +ui_wprintc(WINDOW *window, char *format, ...) { + char str[1024], *s; + va_list ap; + int ret; + char colourbuf[2][3]; + int colours[2]; + int colour = 0; + int bold = 0; + int underline = 0; + int reverse = 0; + int italic = 0; + + va_start(ap, format); + if ((ret = vsnprintf(str, sizeof(str), format, ap)) < 0) { + va_end(ap); + return ret; + } + + for (s = str; s && *s; s++) { + switch (*s) { + case 2: /* ^B */ + if (bold) + wattroff(window, A_BOLD); + else + wattron(window, A_BOLD); + bold = bold ? 0 : 1; + break; + case 3: /* ^C */ + memset(colourbuf, '\0', sizeof(colourbuf)); + /* This section may look a little confusing, but I didn't know + * what better way I could do it (a loop for two things? ehm). + * + * If you want to understand it, I would start with simulating + * it on a peice of paper, something like this: + * + * { , ,'\0'} ^C01,02 + * { , ,'\0'} + * + * Draw a line over *s each time you advance s. */ + if (*s && isdigit(*(s+1))) { + colourbuf[0][0] = *(s+1); + s += 1; + } + if (*s && isdigit(*(s+1))) { + colourbuf[0][1] = *(s+1); + s += 1; + } + if (*s && *(s+1) == ',' && isdigit(*(s+2))) { + colourbuf[1][0] = *(s+2); + s += 2; + } + if (colourbuf[1][0] && *s && *(s+1) && isdigit(*(s+2))) { + colourbuf[1][1] = *(s+2); + s += 2; + } + + colours[0] = colourbuf[0][0] ? colourmap[atoi(colourbuf[0])] : -1; + colours[1] = colourbuf[1][0] ? colourmap[atoi(colourbuf[1])] : -1; + + init_pair(1, colours[0], colours[1]); + wattron(window, COLOR_PAIR(1)); + colour = 1; + break; + case 9: /* ^I */ + if (italic) + wattroff(window, A_ITALIC); + else + wattron(window, A_ITALIC); + italic = italic ? 0 : 1; + break; + case 15: /* ^O */ + colour = 0; + bold = 0; + underline =0; + reverse = 0; + italic = 0; + /* Setting A_NORMAL turns everything off, + * without using 5 different attroffs */ + wattrset(window, A_NORMAL); + break; + case 18: /* ^R */ + if (reverse) + wattroff(window, A_REVERSE); + else + wattron(window, A_REVERSE); + reverse = reverse ? 0 : 1; + break; + case 21: /* ^U */ + if (underline) + wattroff(window, A_UNDERLINE); + else + wattron(window, A_UNDERLINE); + underline = underline ? 0 : 1; + break; + default: + waddch(window, *s); + break; + } + } + + colour = 0; + bold = 0; + underline =0; + reverse = 0; + italic = 0; + wattrset(window, A_NORMAL); +} + void ui_select(struct Server *server, struct Channel *channel) { selected.channel = channel;