diff options
Diffstat (limited to 'testing/toxic/chat.c')
-rw-r--r-- | testing/toxic/chat.c | 67 |
1 files changed, 52 insertions, 15 deletions
diff --git a/testing/toxic/chat.c b/testing/toxic/chat.c index c7979843..3e342858 100644 --- a/testing/toxic/chat.c +++ b/testing/toxic/chat.c | |||
@@ -2,12 +2,12 @@ | |||
2 | * Toxic -- Tox Curses Client | 2 | * Toxic -- Tox Curses Client |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <curses.h> | ||
6 | #include <stdlib.h> | 5 | #include <stdlib.h> |
7 | #include <string.h> | 6 | #include <string.h> |
8 | #include <stdint.h> | 7 | #include <stdint.h> |
9 | #include <ctype.h> | 8 | #include <ctype.h> |
10 | #include <time.h> | 9 | #include <time.h> |
10 | #include <limits.h> | ||
11 | 11 | ||
12 | #include "../../core/Messenger.h" | 12 | #include "../../core/Messenger.h" |
13 | #include "../../core/network.h" | 13 | #include "../../core/network.h" |
@@ -20,7 +20,7 @@ | |||
20 | 20 | ||
21 | typedef struct { | 21 | typedef struct { |
22 | int friendnum; | 22 | int friendnum; |
23 | char line[MAX_STR_SIZE]; | 23 | wchar_t line[MAX_STR_SIZE]; |
24 | size_t pos; | 24 | size_t pos; |
25 | WINDOW *history; | 25 | WINDOW *history; |
26 | WINDOW *linewin; | 26 | WINDOW *linewin; |
@@ -50,7 +50,6 @@ static void chat_onMessage(ToxWindow *self, Messenger *m, int num, uint8_t *msg, | |||
50 | getname(m, num, (uint8_t *) &nick); | 50 | getname(m, num, (uint8_t *) &nick); |
51 | msg[len - 1] = '\0'; | 51 | msg[len - 1] = '\0'; |
52 | nick[MAX_NAME_LENGTH - 1] = '\0'; | 52 | nick[MAX_NAME_LENGTH - 1] = '\0'; |
53 | fix_name(msg); | ||
54 | fix_name(nick); | 53 | fix_name(nick); |
55 | 54 | ||
56 | wattron(ctx->history, COLOR_PAIR(2)); | 55 | wattron(ctx->history, COLOR_PAIR(2)); |
@@ -140,7 +139,43 @@ int string_is_empty(char *string) | |||
140 | return rc; | 139 | return rc; |
141 | } | 140 | } |
142 | 141 | ||
143 | static void chat_onKey(ToxWindow *self, Messenger *m, int key) | 142 | /* convert wide characters to null terminated string */ |
143 | static char *wcs_to_char(wchar_t *string) | ||
144 | { | ||
145 | size_t len = 0; | ||
146 | char *ret = NULL; | ||
147 | |||
148 | len = wcstombs(NULL, string, 0); | ||
149 | if (len != (size_t) -1) { | ||
150 | len++; | ||
151 | ret = malloc(len); | ||
152 | wcstombs(ret, string, len); | ||
153 | } else { | ||
154 | ret = malloc(2); | ||
155 | ret[0] = ' '; | ||
156 | ret[1] = '\0'; | ||
157 | } | ||
158 | return ret; | ||
159 | } | ||
160 | |||
161 | /* convert a wide char to null terminated string */ | ||
162 | static char *wc_to_char(wchar_t ch) | ||
163 | { | ||
164 | int len = 0; | ||
165 | static char ret[MB_LEN_MAX + 1]; | ||
166 | |||
167 | len = wctomb(ret, ch); | ||
168 | if (len == -1) { | ||
169 | ret[0] = ' '; | ||
170 | ret[1] = '\0'; | ||
171 | } else { | ||
172 | ret[len] = '\0'; | ||
173 | } | ||
174 | |||
175 | return ret; | ||
176 | } | ||
177 | |||
178 | static void chat_onKey(ToxWindow *self, Messenger *m, wint_t key) | ||
144 | { | 179 | { |
145 | ChatContext *ctx = (ChatContext *) self->x; | 180 | ChatContext *ctx = (ChatContext *) self->x; |
146 | struct tm *timeinfo = get_time(); | 181 | struct tm *timeinfo = get_time(); |
@@ -150,18 +185,18 @@ static void chat_onKey(ToxWindow *self, Messenger *m, int key) | |||
150 | getmaxyx(self->window, y2, x2); | 185 | getmaxyx(self->window, y2, x2); |
151 | 186 | ||
152 | /* Add printable chars to buffer and print on input space */ | 187 | /* Add printable chars to buffer and print on input space */ |
153 | if (isprint(key)) { | 188 | if (iswprint(key)) { |
154 | if (ctx->pos != sizeof(ctx->line) - 1) { | 189 | if (ctx->pos != sizeof(ctx->line) - 1) { |
155 | mvwaddch(self->window, y, x, key); | 190 | mvwaddstr(self->window, y, x, wc_to_char(key)); |
156 | ctx->line[ctx->pos++] = key; | 191 | ctx->line[ctx->pos++] = key; |
157 | ctx->line[ctx->pos] = '\0'; | 192 | ctx->line[ctx->pos] = L'\0'; |
158 | } | 193 | } |
159 | } | 194 | } |
160 | 195 | ||
161 | /* BACKSPACE key: Remove one character from line */ | 196 | /* BACKSPACE key: Remove one character from line */ |
162 | else if (key == 0x107 || key == 0x8 || key == 0x7f) { | 197 | else if (key == 0x107 || key == 0x8 || key == 0x7f) { |
163 | if (ctx->pos > 0) { | 198 | if (ctx->pos > 0) { |
164 | ctx->line[--ctx->pos] = '\0'; | 199 | ctx->line[--ctx->pos] = L'\0'; |
165 | 200 | ||
166 | if (x == 0) | 201 | if (x == 0) |
167 | mvwdelch(self->window, y - 1, x2 - 1); | 202 | mvwdelch(self->window, y - 1, x2 - 1); |
@@ -172,15 +207,16 @@ static void chat_onKey(ToxWindow *self, Messenger *m, int key) | |||
172 | 207 | ||
173 | /* RETURN key: Execute command or print line */ | 208 | /* RETURN key: Execute command or print line */ |
174 | else if (key == '\n') { | 209 | else if (key == '\n') { |
210 | char *line = wcs_to_char(ctx->line); | ||
175 | wclear(ctx->linewin); | 211 | wclear(ctx->linewin); |
176 | wmove(self->window, y2 - CURS_Y_OFFSET, 0); | 212 | wmove(self->window, y2 - CURS_Y_OFFSET, 0); |
177 | wclrtobot(self->window); | 213 | wclrtobot(self->window); |
178 | 214 | ||
179 | if (ctx->line[0] == '/') | 215 | if (line[0] == '/') |
180 | execute(self, ctx, m, ctx->line); | 216 | execute(self, ctx, m, line); |
181 | else { | 217 | else { |
182 | /* make sure the string has at least non-space character */ | 218 | /* make sure the string has at least non-space character */ |
183 | if (!string_is_empty(ctx->line)) { | 219 | if (!string_is_empty(line)) { |
184 | uint8_t selfname[MAX_NAME_LENGTH]; | 220 | uint8_t selfname[MAX_NAME_LENGTH]; |
185 | getself_name(m, selfname, sizeof(selfname)); | 221 | getself_name(m, selfname, sizeof(selfname)); |
186 | fix_name(selfname); | 222 | fix_name(selfname); |
@@ -191,9 +227,9 @@ static void chat_onKey(ToxWindow *self, Messenger *m, int key) | |||
191 | wattron(ctx->history, COLOR_PAIR(1)); | 227 | wattron(ctx->history, COLOR_PAIR(1)); |
192 | wprintw(ctx->history, "%s: ", selfname); | 228 | wprintw(ctx->history, "%s: ", selfname); |
193 | wattroff(ctx->history, COLOR_PAIR(1)); | 229 | wattroff(ctx->history, COLOR_PAIR(1)); |
194 | wprintw(ctx->history, "%s\n", ctx->line); | 230 | wprintw(ctx->history, "%s\n", line); |
195 | 231 | ||
196 | if (m_sendmessage(m, ctx->friendnum, (uint8_t *) ctx->line, strlen(ctx->line) + 1) == 0) { | 232 | if (m_sendmessage(m, ctx->friendnum, (uint8_t *) line, strlen(line) + 1) == 0) { |
197 | wattron(ctx->history, COLOR_PAIR(3)); | 233 | wattron(ctx->history, COLOR_PAIR(3)); |
198 | wprintw(ctx->history, " * Failed to send message.\n"); | 234 | wprintw(ctx->history, " * Failed to send message.\n"); |
199 | wattroff(ctx->history, COLOR_PAIR(3)); | 235 | wattroff(ctx->history, COLOR_PAIR(3)); |
@@ -201,8 +237,9 @@ static void chat_onKey(ToxWindow *self, Messenger *m, int key) | |||
201 | } | 237 | } |
202 | } | 238 | } |
203 | 239 | ||
204 | ctx->line[0] = '\0'; | 240 | ctx->line[0] = L'\0'; |
205 | ctx->pos = 0; | 241 | ctx->pos = 0; |
242 | free(line); | ||
206 | } | 243 | } |
207 | } | 244 | } |
208 | 245 | ||
@@ -331,7 +368,7 @@ void execute(ToxWindow *self, ChatContext *ctx, Messenger *m, char *cmd) | |||
331 | wprintw(ctx->history, "%s\n", id); | 368 | wprintw(ctx->history, "%s\n", id); |
332 | } | 369 | } |
333 | 370 | ||
334 | else if (strcmp(ctx->line, "/close") == 0) { | 371 | else if (strcmp(cmd, "/close") == 0) { |
335 | int f_num = ctx->friendnum; | 372 | int f_num = ctx->friendnum; |
336 | delwin(ctx->linewin); | 373 | delwin(ctx->linewin); |
337 | del_window(self); | 374 | del_window(self); |