diff --git a/chat.c b/chat.c index c797984..3e34285 100644 --- a/chat.c +++ b/chat.c @@ -2,12 +2,12 @@ * Toxic -- Tox Curses Client */ -#include #include #include #include #include #include +#include #include "../../core/Messenger.h" #include "../../core/network.h" @@ -20,7 +20,7 @@ typedef struct { int friendnum; - char line[MAX_STR_SIZE]; + wchar_t line[MAX_STR_SIZE]; size_t pos; WINDOW *history; WINDOW *linewin; @@ -50,7 +50,6 @@ static void chat_onMessage(ToxWindow *self, Messenger *m, int num, uint8_t *msg, getname(m, num, (uint8_t *) &nick); msg[len - 1] = '\0'; nick[MAX_NAME_LENGTH - 1] = '\0'; - fix_name(msg); fix_name(nick); wattron(ctx->history, COLOR_PAIR(2)); @@ -140,7 +139,43 @@ int string_is_empty(char *string) return rc; } -static void chat_onKey(ToxWindow *self, Messenger *m, int key) +/* convert wide characters to null terminated string */ +static char *wcs_to_char(wchar_t *string) +{ + size_t len = 0; + char *ret = NULL; + + len = wcstombs(NULL, string, 0); + if (len != (size_t) -1) { + len++; + ret = malloc(len); + wcstombs(ret, string, len); + } else { + ret = malloc(2); + ret[0] = ' '; + ret[1] = '\0'; + } + return ret; +} + +/* convert a wide char to null terminated string */ +static char *wc_to_char(wchar_t ch) +{ + int len = 0; + static char ret[MB_LEN_MAX + 1]; + + len = wctomb(ret, ch); + if (len == -1) { + ret[0] = ' '; + ret[1] = '\0'; + } else { + ret[len] = '\0'; + } + + return ret; +} + +static void chat_onKey(ToxWindow *self, Messenger *m, wint_t key) { ChatContext *ctx = (ChatContext *) self->x; struct tm *timeinfo = get_time(); @@ -150,18 +185,18 @@ static void chat_onKey(ToxWindow *self, Messenger *m, int key) getmaxyx(self->window, y2, x2); /* Add printable chars to buffer and print on input space */ - if (isprint(key)) { + if (iswprint(key)) { if (ctx->pos != sizeof(ctx->line) - 1) { - mvwaddch(self->window, y, x, key); + mvwaddstr(self->window, y, x, wc_to_char(key)); ctx->line[ctx->pos++] = key; - ctx->line[ctx->pos] = '\0'; + ctx->line[ctx->pos] = L'\0'; } } /* BACKSPACE key: Remove one character from line */ else if (key == 0x107 || key == 0x8 || key == 0x7f) { if (ctx->pos > 0) { - ctx->line[--ctx->pos] = '\0'; + ctx->line[--ctx->pos] = L'\0'; if (x == 0) mvwdelch(self->window, y - 1, x2 - 1); @@ -172,15 +207,16 @@ static void chat_onKey(ToxWindow *self, Messenger *m, int key) /* RETURN key: Execute command or print line */ else if (key == '\n') { + char *line = wcs_to_char(ctx->line); wclear(ctx->linewin); wmove(self->window, y2 - CURS_Y_OFFSET, 0); wclrtobot(self->window); - if (ctx->line[0] == '/') - execute(self, ctx, m, ctx->line); + if (line[0] == '/') + execute(self, ctx, m, line); else { /* make sure the string has at least non-space character */ - if (!string_is_empty(ctx->line)) { + if (!string_is_empty(line)) { uint8_t selfname[MAX_NAME_LENGTH]; getself_name(m, selfname, sizeof(selfname)); fix_name(selfname); @@ -191,9 +227,9 @@ static void chat_onKey(ToxWindow *self, Messenger *m, int key) wattron(ctx->history, COLOR_PAIR(1)); wprintw(ctx->history, "%s: ", selfname); wattroff(ctx->history, COLOR_PAIR(1)); - wprintw(ctx->history, "%s\n", ctx->line); + wprintw(ctx->history, "%s\n", line); - if (m_sendmessage(m, ctx->friendnum, (uint8_t *) ctx->line, strlen(ctx->line) + 1) == 0) { + if (m_sendmessage(m, ctx->friendnum, (uint8_t *) line, strlen(line) + 1) == 0) { wattron(ctx->history, COLOR_PAIR(3)); wprintw(ctx->history, " * Failed to send message.\n"); wattroff(ctx->history, COLOR_PAIR(3)); @@ -201,8 +237,9 @@ static void chat_onKey(ToxWindow *self, Messenger *m, int key) } } - ctx->line[0] = '\0'; + ctx->line[0] = L'\0'; ctx->pos = 0; + free(line); } } @@ -331,7 +368,7 @@ void execute(ToxWindow *self, ChatContext *ctx, Messenger *m, char *cmd) wprintw(ctx->history, "%s\n", id); } - else if (strcmp(ctx->line, "/close") == 0) { + else if (strcmp(cmd, "/close") == 0) { int f_num = ctx->friendnum; delwin(ctx->linewin); del_window(self); diff --git a/dhtstatus.c b/dhtstatus.c index 6c9f2a8..3330077 100644 --- a/dhtstatus.c +++ b/dhtstatus.c @@ -11,7 +11,7 @@ static void printip(ipbuf buf, IP ip) sprintf((char *)buf, "%u.%u.%u.%u", ip.c[0], ip.c[1], ip.c[2], ip.c[3]); } -static void dhtstatus_onKey(ToxWindow *self, Messenger *m, int key) +static void dhtstatus_onKey(ToxWindow *self, Messenger *m, wint_t key) { switch (key) { case KEY_UP: diff --git a/friendlist.c b/friendlist.c index 2e46f12..72b1da9 100644 --- a/friendlist.c +++ b/friendlist.c @@ -2,7 +2,6 @@ * Toxic -- Tox Curses Client */ -#include #include #include #include @@ -84,7 +83,7 @@ int friendlist_onFriendAdded(Messenger *m, int num) return 0; } -static void friendlist_onKey(ToxWindow *self, Messenger *m, int key) +static void friendlist_onKey(ToxWindow *self, Messenger *m, wint_t key) { if (key == KEY_UP) { if (--num_selected < 0) diff --git a/main.c b/main.c index e5525e9..12b529f 100644 --- a/main.c +++ b/main.c @@ -2,6 +2,7 @@ * Toxic -- Tox Curses Client */ +#define _XOPEN_SOURCE_EXTENDED #include #include #include @@ -9,6 +10,7 @@ #include #include #include +#include #ifdef _win32 #include @@ -40,6 +42,7 @@ static void init_term() { /* Setup terminal */ signal(SIGWINCH, on_window_resize); + setlocale(LC_ALL, ""); initscr(); cbreak(); keypad(stdscr, 1); diff --git a/prompt.c b/prompt.c index e194a90..d210023 100644 --- a/prompt.c +++ b/prompt.c @@ -5,7 +5,6 @@ #include #include #include -#include #include "../../core/Messenger.h" #include "../../core/network.h" @@ -426,7 +425,7 @@ static void execute(ToxWindow *self, Messenger *m, char *u_cmd) wprintw(self->window, "Invalid command.\n"); } -static void prompt_onKey(ToxWindow *self, Messenger *m, int key) +static void prompt_onKey(ToxWindow *self, Messenger *m, wint_t key) { /* Add printable characters to line */ if (isprint(key)) { diff --git a/windows.c b/windows.c index 8fdf4e1..f50bdc2 100644 --- a/windows.c +++ b/windows.c @@ -226,16 +226,18 @@ void draw_active_window(Messenger *m) { ToxWindow *a = active_window; + wint_t ch = 0; + prepare_window(a->window); a->blink = false; draw_bar(); a->onDraw(a, m); /* Handle input */ - int ch = getch(); + get_wch(&ch); if (ch == '\t' || ch == KEY_BTAB) - set_next_window(ch); + set_next_window((int) ch); else if (ch != ERR) a->onKey(a, m, ch); } diff --git a/windows.h b/windows.h index 86917db..227040b 100644 --- a/windows.h +++ b/windows.h @@ -4,9 +4,12 @@ #ifndef _windows_h #define _windows_h +#define _XOPEN_SOURCE_EXTENDED #include #include #include +#include +#include #include "../../core/Messenger.h" #define MAX_WINDOWS_NUM 32 #define MAX_FRIENDS_NUM 100 @@ -23,7 +26,7 @@ typedef struct ToxWindow_ ToxWindow; struct ToxWindow_ { - void(*onKey)(ToxWindow *, Messenger *, int); + void(*onKey)(ToxWindow *, Messenger *, wint_t); void(*onDraw)(ToxWindow *, Messenger *); void(*onInit)(ToxWindow *, Messenger *); void(*onFriendRequest)(ToxWindow *, uint8_t *, uint8_t *, uint16_t);