summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xCMakeLists.txt2
-rw-r--r--cmake/FindCursesw.cmake179
-rw-r--r--testing/toxic/CMakeLists.txt4
-rw-r--r--testing/toxic/chat.c74
-rw-r--r--testing/toxic/dhtstatus.c2
-rw-r--r--testing/toxic/friendlist.c20
-rw-r--r--testing/toxic/friendlist.h1
-rw-r--r--testing/toxic/main.c3
-rw-r--r--testing/toxic/prompt.c3
-rw-r--r--testing/toxic/windows.c6
-rw-r--r--testing/toxic/windows.h5
11 files changed, 250 insertions, 49 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 815616a7..132357de 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,7 +19,7 @@ if(APPLE)
19endif() 19endif()
20 20
21if(UNIX) 21if(UNIX)
22 find_package(Curses REQUIRED) 22 find_package(Cursesw REQUIRED)
23endif() 23endif()
24 24
25if(USE_NACL) 25if(USE_NACL)
diff --git a/cmake/FindCursesw.cmake b/cmake/FindCursesw.cmake
new file mode 100644
index 00000000..60f01f39
--- /dev/null
+++ b/cmake/FindCursesw.cmake
@@ -0,0 +1,179 @@
1# - Find the curses include file and library
2#
3# CURSES_FOUND - system has Curses
4# CURSES_INCLUDE_DIR - the Curses include directory
5# CURSES_LIBRARIES - The libraries needed to use Curses
6# CURSES_HAVE_CURSES_H - true if curses.h is available
7# CURSES_HAVE_NCURSES_H - true if ncurses.h is available
8# CURSES_HAVE_NCURSES_NCURSES_H - true if ncurses/ncurses.h is available
9# CURSES_HAVE_NCURSES_CURSES_H - true if ncurses/curses.h is available
10# CURSES_LIBRARY - set for backwards compatibility with 2.4 CMake
11#
12# Set CURSES_NEED_NCURSES to TRUE before the FIND_PACKAGE() command if NCurses
13# functionality is required.
14
15# Set CURSES_NEED_WIDE to TRUE before the FIND_PACKAGE() command if unicode
16# functionality is required
17
18SET(CURSES_NEED_WIDE TRUE)
19
20SET(CURSES_LIBRARY_NAME "curses")
21SET(NCURSES_LIBRARY_NAME "ncurses")
22IF(CURSES_NEED_WIDE)
23 MESSAGE( STATUS "Searching for wide character curses")
24 SET(CURSES_LIBRARY_NAME "cursesw")
25 SET(NCURSES_LIBRARY_NAME "ncursesw")
26ENDIF(CURSES_NEED_WIDE)
27
28FIND_LIBRARY(CURSES_CURSES_LIBRARY "${CURSES_LIBRARY_NAME}")
29# MESSAGE(STATUS "CURSES! " ${CURSES_CURSES_LIBRARY})
30
31FIND_LIBRARY(CURSES_NCURSES_LIBRARY "${NCURSES_LIBRARY_NAME}")
32# MESSAGE(STATUS "NCURSES! " ${CURSES_NCURSES_LIBRARY})
33
34SET(CURSES_USE_NCURSES FALSE)
35
36IF(CURSES_NCURSES_LIBRARY AND NOT CURSES_CURSES_LIBRARY)
37 SET(CURSES_USE_NCURSES TRUE)
38ENDIF(CURSES_NCURSES_LIBRARY AND NOT CURSES_CURSES_LIBRARY)
39
40
41# Not sure the logic is correct here.
42# If NCurses is required, use the function wsyncup() to check if the library
43# has NCurses functionality (at least this is where it breaks on NetBSD).
44# If wsyncup is in curses, use this one.
45# If not, try to find ncurses and check if this has the symbol.
46# Once the ncurses library is found, search the ncurses.h header first, but
47# some web pages also say that even with ncurses there is not always a ncurses.h:
48# http://osdir.com/ml/gnome.apps.mc.devel/2002-06/msg00029.html
49# So at first try ncurses.h, if not found, try to find curses.h under the same
50# prefix as the library was found, if still not found, try curses.h with the
51# default search paths.
52IF(CURSES_CURSES_LIBRARY AND CURSES_NEED_NCURSES)
53 INCLUDE(CheckLibraryExists)
54 CHECK_LIBRARY_EXISTS("${CURSES_CURSES_LIBRARY}"
55 wsyncup "" CURSES_CURSES_HAS_WSYNCUP)
56
57 IF(CURSES_NCURSES_LIBRARY AND NOT CURSES_CURSES_HAS_WSYNCUP)
58 CHECK_LIBRARY_EXISTS("${CURSES_NCURSES_LIBRARY}"
59 wsyncup "" CURSES_NCURSES_HAS_WSYNCUP)
60 IF( CURSES_NCURSES_HAS_WSYNCUP)
61 SET(CURSES_USE_NCURSES TRUE)
62 ENDIF( CURSES_NCURSES_HAS_WSYNCUP)
63 ENDIF(CURSES_NCURSES_LIBRARY AND NOT CURSES_CURSES_HAS_WSYNCUP)
64
65ENDIF(CURSES_CURSES_LIBRARY AND CURSES_NEED_NCURSES)
66
67
68IF(NOT CURSES_USE_NCURSES)
69 FIND_FILE(CURSES_HAVE_CURSES_H curses.h )
70 FIND_FILE(CURSES_HAVE_CURSESW_H cursesw.h )
71 FIND_PATH(CURSES_CURSES_H_PATH curses.h )
72 FIND_PATH(CURSES_CURSESW_H_PATH cursesw.h )
73 GET_FILENAME_COMPONENT(_cursesLibDir "${CURSES_CURSES_LIBRARY}" PATH)
74 GET_FILENAME_COMPONENT(_cursesParentDir "${_cursesLibDir}" PATH)
75
76 # for compatibility with older FindCurses.cmake this has to be in the cache
77 # FORCE must not be used since this would break builds which preload a cache wqith these variables set
78 SET(CURSES_INCLUDE_PATH "${CURSES_CURSES_H_PATH} ${CURSES_CURSESW_H_PATH}"
79 CACHE FILEPATH "The curses include path")
80 SET(CURSES_LIBRARY "${CURSES_CURSES_LIBRARY}"
81 CACHE FILEPATH "The curses library")
82ELSE(NOT CURSES_USE_NCURSES)
83# we need to find ncurses
84 GET_FILENAME_COMPONENT(_cursesLibDir "${CURSES_NCURSES_LIBRARY}" PATH)
85 GET_FILENAME_COMPONENT(_cursesParentDir "${_cursesLibDir}" PATH)
86
87 FIND_FILE(CURSES_HAVE_NCURSES_H ncurses.h)
88 FIND_FILE(CURSES_HAVE_NCURSES_NCURSES_H ncurses/ncurses.h)
89 FIND_FILE(CURSES_HAVE_NCURSES_CURSES_H ncurses/curses.h)
90 FIND_FILE(CURSES_HAVE_CURSES_H curses.h
91 HINTS "${_cursesParentDir}/include")
92
93 FIND_FILE(CURSES_HAVE_NCURSESW_H ncursesw.h)
94 FIND_FILE(CURSES_HAVE_NCURSESW_NCURSES_H ncursesw/ncurses.h)
95 FIND_FILE(CURSES_HAVE_NCURSESW_CURSES_H ncursesw/curses.h)
96 FIND_FILE(CURSES_HAVE_CURSESW_H cursesw.h
97 HINTS "${_cursesParentDir}/include")
98
99 FIND_PATH(CURSES_NCURSES_INCLUDE_PATH curses.h PATH_SUFFIXES ncursesw)
100
101 # for compatibility with older FindCurses.cmake this has to be in the cache
102 # FORCE must not be used since this would break builds which preload
103 # a cache wqith these variables set
104 # only put ncurses include and library into
105 # variables if they are found
106 IF(CURSES_NCURSES_INCLUDE_PATH AND CURSES_NCURSES_LIBRARY)
107
108 SET(CURSES_INCLUDE_PATH "${CURSES_NCURSES_INCLUDE_PATH} ${CURSES_NCURSESW_INCLUDE_PATH}"
109 CACHE FILEPATH "The curses include path")
110 SET(CURSES_LIBRARY "${CURSES_NCURSES_LIBRARY}"
111 CACHE FILEPATH "The curses library")
112 ENDIF(CURSES_NCURSES_INCLUDE_PATH AND CURSES_NCURSES_LIBRARY)
113
114ENDIF(NOT CURSES_USE_NCURSES)
115
116
117
118FIND_LIBRARY(CURSES_EXTRA_LIBRARY cur_colr HINTS "${_cursesLibDir}")
119FIND_LIBRARY(CURSES_EXTRA_LIBRARY cur_colr )
120
121SET(CURSES_FORM_LIBRARY_NAME "form")
122IF(CURSES_NEED_WIDE)
123 SET(CURSES_FORM_LIBRARY_NAME "formw")
124ENDIF(CURSES_NEED_WIDE)
125
126FIND_LIBRARY(CURSES_CURSES_LIBRARY "${CURSES_LIBRARY_NAME}")
127FIND_LIBRARY(CURSES_FORM_LIBRARY "${CURSES_FORM_LIBRARY_NAME}" HINTS "${_cursesLibDir}")
128FIND_LIBRARY(CURSES_FORM_LIBRARY "${CURSES_FORM_LIBRARY_NAME}" )
129
130# for compatibility with older FindCurses.cmake this has to be in the cache
131# FORCE must not be used since this would break builds which preload a cache
132# qith these variables set
133SET(FORM_LIBRARY "${CURSES_FORM_LIBRARY}"
134 CACHE FILEPATH "The curses form library")
135
136# Need to provide the *_LIBRARIES
137SET(CURSES_LIBRARIES ${CURSES_LIBRARY})
138
139IF(CURSES_EXTRA_LIBRARY)
140 SET(CURSES_LIBRARIES ${CURSES_LIBRARIES} ${CURSES_EXTRA_LIBRARY})
141ENDIF(CURSES_EXTRA_LIBRARY)
142
143IF(CURSES_FORM_LIBRARY)
144 SET(CURSES_LIBRARIES ${CURSES_LIBRARIES} ${CURSES_FORM_LIBRARY})
145ENDIF(CURSES_FORM_LIBRARY)
146
147# Proper name is *_INCLUDE_DIR
148SET(CURSES_INCLUDE_DIR ${CURSES_INCLUDE_PATH})
149
150# handle the QUIETLY and REQUIRED arguments and set CURSES_FOUND to TRUE if
151# all listed variables are TRUE
152INCLUDE(FindPackageHandleStandardArgs)
153FIND_PACKAGE_HANDLE_STANDARD_ARGS(Curses DEFAULT_MSG
154 CURSES_LIBRARY CURSES_INCLUDE_PATH)
155
156MARK_AS_ADVANCED(
157 CURSES_INCLUDE_PATH
158 CURSES_LIBRARY
159 CURSES_CURSES_INCLUDE_PATH
160 CURSES_CURSES_LIBRARY
161 CURSES_NCURSES_INCLUDE_PATH
162 CURSES_NCURSES_LIBRARY
163 CURSES_EXTRA_LIBRARY
164 FORM_LIBRARY
165 CURSES_FORM_LIBRARY
166 CURSES_LIBRARIES
167 CURSES_INCLUDE_DIR
168 CURSES_CURSES_HAS_WSYNCUP
169 CURSES_NCURSES_HAS_WSYNCUP
170 CURSES_HAVE_CURSESW_H
171 CURSES_HAVE_CURSES_H
172 CURSES_HAVE_NCURSESW_CURSES_H
173 CURSES_HAVE_NCURSESW_H
174 CURSES_HAVE_NCURSESW_NCURSES_H
175 CURSES_HAVE_NCURSES_CURSES_H
176 CURSES_HAVE_NCURSES_H
177 CURSES_HAVE_NCURSES_NCURSES_H
178 )
179
diff --git a/testing/toxic/CMakeLists.txt b/testing/toxic/CMakeLists.txt
index 9ee7020e..53316afb 100644
--- a/testing/toxic/CMakeLists.txt
+++ b/testing/toxic/CMakeLists.txt
@@ -15,7 +15,9 @@ add_executable(${exe_name}
15 chat.c 15 chat.c
16 configdir.c) 16 configdir.c)
17 17
18include_directories(${CURSES_INCLUDE_DIR})
19
18target_link_libraries(${exe_name} 20target_link_libraries(${exe_name}
19 curses) 21 ${CURSES_LIBRARIES})
20 22
21linkCoreLibraries(${exe_name}) 23linkCoreLibraries(${exe_name})
diff --git a/testing/toxic/chat.c b/testing/toxic/chat.c
index c7979843..c7a0f98e 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
21typedef struct { 21typedef 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,8 +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);
55 53
56 wattron(ctx->history, COLOR_PAIR(2)); 54 wattron(ctx->history, COLOR_PAIR(2));
57 wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); 55 wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
@@ -74,7 +72,6 @@ static void chat_onAction(ToxWindow *self, Messenger *m, int num, uint8_t *actio
74 return; 72 return;
75 73
76 action[len - 1] = '\0'; 74 action[len - 1] = '\0';
77 fix_name(action);
78 75
79 wattron(ctx->history, COLOR_PAIR(2)); 76 wattron(ctx->history, COLOR_PAIR(2));
80 wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); 77 wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
@@ -101,7 +98,6 @@ static void chat_onNickChange(ToxWindow *self, int num, uint8_t *nick, uint16_t
101 wattroff(ctx->history, COLOR_PAIR(2)); 98 wattroff(ctx->history, COLOR_PAIR(2));
102 99
103 nick[len - 1] = '\0'; 100 nick[len - 1] = '\0';
104 fix_name(nick);
105 snprintf(self->title, sizeof(self->title), "[%s (%d)]", nick, num); 101 snprintf(self->title, sizeof(self->title), "[%s (%d)]", nick, num);
106 102
107 wattron(ctx->history, COLOR_PAIR(3)); 103 wattron(ctx->history, COLOR_PAIR(3));
@@ -122,7 +118,7 @@ static void chat_onStatusChange(ToxWindow *self, int num, uint8_t *status, uint1
122 wattroff(ctx->history, COLOR_PAIR(2)); 118 wattroff(ctx->history, COLOR_PAIR(2));
123 119
124 status[len - 1] = '\0'; 120 status[len - 1] = '\0';
125 fix_name(status); 121 snprintf(self->title, sizeof(self->title), "[%s (%d)]", status, num);
126 122
127 wattron(ctx->history, COLOR_PAIR(3)); 123 wattron(ctx->history, COLOR_PAIR(3));
128 wprintw(ctx->history, "* Your partner changed status to '%s'\n", status); 124 wprintw(ctx->history, "* Your partner changed status to '%s'\n", status);
@@ -140,7 +136,43 @@ int string_is_empty(char *string)
140 return rc; 136 return rc;
141} 137}
142 138
143static void chat_onKey(ToxWindow *self, Messenger *m, int key) 139/* convert wide characters to null terminated string */
140static char *wcs_to_char(wchar_t *string)
141{
142 size_t len = 0;
143 char *ret = NULL;
144
145 len = wcstombs(NULL, string, 0);
146 if (len != (size_t) -1) {
147 len++;
148 ret = malloc(len);
149 wcstombs(ret, string, len);
150 } else {
151 ret = malloc(2);
152 ret[0] = ' ';
153 ret[1] = '\0';
154 }
155 return ret;
156}
157
158/* convert a wide char to null terminated string */
159static char *wc_to_char(wchar_t ch)
160{
161 int len = 0;
162 static char ret[MB_LEN_MAX + 1];
163
164 len = wctomb(ret, ch);
165 if (len == -1) {
166 ret[0] = ' ';
167 ret[1] = '\0';
168 } else {
169 ret[len] = '\0';
170 }
171
172 return ret;
173}
174
175static void chat_onKey(ToxWindow *self, Messenger *m, wint_t key)
144{ 176{
145 ChatContext *ctx = (ChatContext *) self->x; 177 ChatContext *ctx = (ChatContext *) self->x;
146 struct tm *timeinfo = get_time(); 178 struct tm *timeinfo = get_time();
@@ -150,18 +182,18 @@ static void chat_onKey(ToxWindow *self, Messenger *m, int key)
150 getmaxyx(self->window, y2, x2); 182 getmaxyx(self->window, y2, x2);
151 183
152 /* Add printable chars to buffer and print on input space */ 184 /* Add printable chars to buffer and print on input space */
153 if (isprint(key)) { 185 if (iswprint(key)) {
154 if (ctx->pos != sizeof(ctx->line) - 1) { 186 if (ctx->pos != sizeof(ctx->line) - 1) {
155 mvwaddch(self->window, y, x, key); 187 mvwaddstr(self->window, y, x, wc_to_char(key));
156 ctx->line[ctx->pos++] = key; 188 ctx->line[ctx->pos++] = key;
157 ctx->line[ctx->pos] = '\0'; 189 ctx->line[ctx->pos] = L'\0';
158 } 190 }
159 } 191 }
160 192
161 /* BACKSPACE key: Remove one character from line */ 193 /* BACKSPACE key: Remove one character from line */
162 else if (key == 0x107 || key == 0x8 || key == 0x7f) { 194 else if (key == 0x107 || key == 0x8 || key == 0x7f) {
163 if (ctx->pos > 0) { 195 if (ctx->pos > 0) {
164 ctx->line[--ctx->pos] = '\0'; 196 ctx->line[--ctx->pos] = L'\0';
165 197
166 if (x == 0) 198 if (x == 0)
167 mvwdelch(self->window, y - 1, x2 - 1); 199 mvwdelch(self->window, y - 1, x2 - 1);
@@ -172,18 +204,18 @@ static void chat_onKey(ToxWindow *self, Messenger *m, int key)
172 204
173 /* RETURN key: Execute command or print line */ 205 /* RETURN key: Execute command or print line */
174 else if (key == '\n') { 206 else if (key == '\n') {
207 char *line = wcs_to_char(ctx->line);
175 wclear(ctx->linewin); 208 wclear(ctx->linewin);
176 wmove(self->window, y2 - CURS_Y_OFFSET, 0); 209 wmove(self->window, y2 - CURS_Y_OFFSET, 0);
177 wclrtobot(self->window); 210 wclrtobot(self->window);
178 211
179 if (ctx->line[0] == '/') 212 if (line[0] == '/')
180 execute(self, ctx, m, ctx->line); 213 execute(self, ctx, m, line);
181 else { 214 else {
182 /* make sure the string has at least non-space character */ 215 /* make sure the string has at least non-space character */
183 if (!string_is_empty(ctx->line)) { 216 if (!string_is_empty(line)) {
184 uint8_t selfname[MAX_NAME_LENGTH]; 217 uint8_t selfname[MAX_NAME_LENGTH];
185 getself_name(m, selfname, sizeof(selfname)); 218 getself_name(m, selfname, sizeof(selfname));
186 fix_name(selfname);
187 219
188 wattron(ctx->history, COLOR_PAIR(2)); 220 wattron(ctx->history, COLOR_PAIR(2));
189 wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); 221 wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
@@ -191,9 +223,9 @@ static void chat_onKey(ToxWindow *self, Messenger *m, int key)
191 wattron(ctx->history, COLOR_PAIR(1)); 223 wattron(ctx->history, COLOR_PAIR(1));
192 wprintw(ctx->history, "%s: ", selfname); 224 wprintw(ctx->history, "%s: ", selfname);
193 wattroff(ctx->history, COLOR_PAIR(1)); 225 wattroff(ctx->history, COLOR_PAIR(1));
194 wprintw(ctx->history, "%s\n", ctx->line); 226 wprintw(ctx->history, "%s\n", line);
195 227
196 if (m_sendmessage(m, ctx->friendnum, (uint8_t *) ctx->line, strlen(ctx->line) + 1) == 0) { 228 if (m_sendmessage(m, ctx->friendnum, (uint8_t *) line, strlen(line) + 1) == 0) {
197 wattron(ctx->history, COLOR_PAIR(3)); 229 wattron(ctx->history, COLOR_PAIR(3));
198 wprintw(ctx->history, " * Failed to send message.\n"); 230 wprintw(ctx->history, " * Failed to send message.\n");
199 wattroff(ctx->history, COLOR_PAIR(3)); 231 wattroff(ctx->history, COLOR_PAIR(3));
@@ -201,8 +233,9 @@ static void chat_onKey(ToxWindow *self, Messenger *m, int key)
201 } 233 }
202 } 234 }
203 235
204 ctx->line[0] = '\0'; 236 ctx->line[0] = L'\0';
205 ctx->pos = 0; 237 ctx->pos = 0;
238 free(line);
206 } 239 }
207} 240}
208 241
@@ -331,7 +364,7 @@ void execute(ToxWindow *self, ChatContext *ctx, Messenger *m, char *cmd)
331 wprintw(ctx->history, "%s\n", id); 364 wprintw(ctx->history, "%s\n", id);
332 } 365 }
333 366
334 else if (strcmp(ctx->line, "/close") == 0) { 367 else if (strcmp(cmd, "/close") == 0) {
335 int f_num = ctx->friendnum; 368 int f_num = ctx->friendnum;
336 delwin(ctx->linewin); 369 delwin(ctx->linewin);
337 del_window(self); 370 del_window(self);
@@ -398,7 +431,6 @@ ToxWindow new_chat(Messenger *m, int friendnum)
398 431
399 uint8_t nick[MAX_NAME_LENGTH] = {0}; 432 uint8_t nick[MAX_NAME_LENGTH] = {0};
400 getname(m, friendnum, (uint8_t *) &nick); 433 getname(m, friendnum, (uint8_t *) &nick);
401 fix_name(nick);
402 434
403 snprintf(ret.title, sizeof(ret.title), "[%s (%d)]", nick, friendnum); 435 snprintf(ret.title, sizeof(ret.title), "[%s (%d)]", nick, friendnum);
404 436
diff --git a/testing/toxic/dhtstatus.c b/testing/toxic/dhtstatus.c
index 6c9f2a80..33300772 100644
--- a/testing/toxic/dhtstatus.c
+++ b/testing/toxic/dhtstatus.c
@@ -11,7 +11,7 @@ static void printip(ipbuf buf, IP ip)
11 sprintf((char *)buf, "%u.%u.%u.%u", ip.c[0], ip.c[1], ip.c[2], ip.c[3]); 11 sprintf((char *)buf, "%u.%u.%u.%u", ip.c[0], ip.c[1], ip.c[2], ip.c[3]);
12} 12}
13 13
14static void dhtstatus_onKey(ToxWindow *self, Messenger *m, int key) 14static void dhtstatus_onKey(ToxWindow *self, Messenger *m, wint_t key)
15{ 15{
16 switch (key) { 16 switch (key) {
17 case KEY_UP: 17 case KEY_UP:
diff --git a/testing/toxic/friendlist.c b/testing/toxic/friendlist.c
index 2e46f124..8fa3b473 100644
--- a/testing/toxic/friendlist.c
+++ b/testing/toxic/friendlist.c
@@ -2,7 +2,6 @@
2 * Toxic -- Tox Curses Client 2 * Toxic -- Tox Curses Client
3 */ 3 */
4 4
5#include <curses.h>
6#include <string.h> 5#include <string.h>
7#include <stdint.h> 6#include <stdint.h>
8#include <ctype.h> 7#include <ctype.h>
@@ -25,21 +24,6 @@ static friend_t friends[MAX_FRIENDS_NUM];
25static int num_friends = 0; 24static int num_friends = 0;
26static int num_selected = 0; 25static int num_selected = 0;
27 26
28void fix_name(uint8_t *name)
29{
30 /* Remove all non alphanumeric characters */
31 uint8_t *p = name;
32 uint8_t *q = name;
33
34 while (*p != 0) {
35 if (isprint(*p))
36 *q++ = *p;
37
38 p++;
39 }
40
41 *q = 0;
42}
43 27
44void friendlist_onMessage(ToxWindow *self, Messenger *m, int num, uint8_t *str, uint16_t len) 28void friendlist_onMessage(ToxWindow *self, Messenger *m, int num, uint8_t *str, uint16_t len)
45{ 29{
@@ -58,7 +42,6 @@ void friendlist_onNickChange(ToxWindow *self, int num, uint8_t *str, uint16_t le
58 42
59 memcpy((char *) &friends[num].name, (char *) str, len); 43 memcpy((char *) &friends[num].name, (char *) str, len);
60 friends[num].name[len] = 0; 44 friends[num].name[len] = 0;
61 fix_name(friends[num].name);
62} 45}
63 46
64void friendlist_onStatusChange(ToxWindow *self, int num, uint8_t *str, uint16_t len) 47void friendlist_onStatusChange(ToxWindow *self, int num, uint8_t *str, uint16_t len)
@@ -68,7 +51,6 @@ void friendlist_onStatusChange(ToxWindow *self, int num, uint8_t *str, uint16_t
68 51
69 memcpy((char *) &friends[num].status, (char *) str, len); 52 memcpy((char *) &friends[num].status, (char *) str, len);
70 friends[num].status[len] = 0; 53 friends[num].status[len] = 0;
71 fix_name(friends[num].status);
72} 54}
73 55
74int friendlist_onFriendAdded(Messenger *m, int num) 56int friendlist_onFriendAdded(Messenger *m, int num)
@@ -84,7 +66,7 @@ int friendlist_onFriendAdded(Messenger *m, int num)
84 return 0; 66 return 0;
85} 67}
86 68
87static void friendlist_onKey(ToxWindow *self, Messenger *m, int key) 69static void friendlist_onKey(ToxWindow *self, Messenger *m, wint_t key)
88{ 70{
89 if (key == KEY_UP) { 71 if (key == KEY_UP) {
90 if (--num_selected < 0) 72 if (--num_selected < 0)
diff --git a/testing/toxic/friendlist.h b/testing/toxic/friendlist.h
index 91b917fd..6f045d4a 100644
--- a/testing/toxic/friendlist.h
+++ b/testing/toxic/friendlist.h
@@ -7,6 +7,5 @@
7ToxWindow new_friendlist(); 7ToxWindow new_friendlist();
8int friendlist_onFriendAdded(Messenger *m, int num); 8int friendlist_onFriendAdded(Messenger *m, int num);
9void disable_chatwin(int f_num); 9void disable_chatwin(int f_num);
10void fix_name(uint8_t *name);
11 10
12#endif /* end of include guard: FRIENDLIST_H_53I41IM */ 11#endif /* end of include guard: FRIENDLIST_H_53I41IM */
diff --git a/testing/toxic/main.c b/testing/toxic/main.c
index e5525e94..12b529fc 100644
--- a/testing/toxic/main.c
+++ b/testing/toxic/main.c
@@ -2,6 +2,7 @@
2 * Toxic -- Tox Curses Client 2 * Toxic -- Tox Curses Client
3 */ 3 */
4 4
5#define _XOPEN_SOURCE_EXTENDED
5#include <curses.h> 6#include <curses.h>
6#include <errno.h> 7#include <errno.h>
7#include <stdio.h> 8#include <stdio.h>
@@ -9,6 +10,7 @@
9#include <stdbool.h> 10#include <stdbool.h>
10#include <stdint.h> 11#include <stdint.h>
11#include <signal.h> 12#include <signal.h>
13#include <locale.h>
12 14
13#ifdef _win32 15#ifdef _win32
14#include <direct.h> 16#include <direct.h>
@@ -40,6 +42,7 @@ static void init_term()
40{ 42{
41 /* Setup terminal */ 43 /* Setup terminal */
42 signal(SIGWINCH, on_window_resize); 44 signal(SIGWINCH, on_window_resize);
45 setlocale(LC_ALL, "");
43 initscr(); 46 initscr();
44 cbreak(); 47 cbreak();
45 keypad(stdscr, 1); 48 keypad(stdscr, 1);
diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c
index 6c762c86..b00dba20 100644
--- a/testing/toxic/prompt.c
+++ b/testing/toxic/prompt.c
@@ -5,7 +5,6 @@
5#include <stdlib.h> 5#include <stdlib.h>
6#include <string.h> 6#include <string.h>
7#include <ctype.h> 7#include <ctype.h>
8#include <curses.h>
9 8
10#include "../../core/Messenger.h" 9#include "../../core/Messenger.h"
11#include "../../core/network.h" 10#include "../../core/network.h"
@@ -434,7 +433,7 @@ static void execute(ToxWindow *self, Messenger *m, char *u_cmd)
434 wprintw(self->window, "Invalid command.\n"); 433 wprintw(self->window, "Invalid command.\n");
435} 434}
436 435
437static void prompt_onKey(ToxWindow *self, Messenger *m, int key) 436static void prompt_onKey(ToxWindow *self, Messenger *m, wint_t key)
438{ 437{
439 /* Add printable characters to line */ 438 /* Add printable characters to line */
440 if (isprint(key)) { 439 if (isprint(key)) {
diff --git a/testing/toxic/windows.c b/testing/toxic/windows.c
index 8fdf4e19..f50bdc2d 100644
--- a/testing/toxic/windows.c
+++ b/testing/toxic/windows.c
@@ -226,16 +226,18 @@ void draw_active_window(Messenger *m)
226{ 226{
227 227
228 ToxWindow *a = active_window; 228 ToxWindow *a = active_window;
229 wint_t ch = 0;
230
229 prepare_window(a->window); 231 prepare_window(a->window);
230 a->blink = false; 232 a->blink = false;
231 draw_bar(); 233 draw_bar();
232 a->onDraw(a, m); 234 a->onDraw(a, m);
233 235
234 /* Handle input */ 236 /* Handle input */
235 int ch = getch(); 237 get_wch(&ch);
236 238
237 if (ch == '\t' || ch == KEY_BTAB) 239 if (ch == '\t' || ch == KEY_BTAB)
238 set_next_window(ch); 240 set_next_window((int) ch);
239 else if (ch != ERR) 241 else if (ch != ERR)
240 a->onKey(a, m, ch); 242 a->onKey(a, m, ch);
241} 243}
diff --git a/testing/toxic/windows.h b/testing/toxic/windows.h
index 86917dbe..227040b9 100644
--- a/testing/toxic/windows.h
+++ b/testing/toxic/windows.h
@@ -4,9 +4,12 @@
4#ifndef _windows_h 4#ifndef _windows_h
5#define _windows_h 5#define _windows_h
6 6
7#define _XOPEN_SOURCE_EXTENDED
7#include <curses.h> 8#include <curses.h>
8#include <stdint.h> 9#include <stdint.h>
9#include <stdbool.h> 10#include <stdbool.h>
11#include <wctype.h>
12#include <wchar.h>
10#include "../../core/Messenger.h" 13#include "../../core/Messenger.h"
11#define MAX_WINDOWS_NUM 32 14#define MAX_WINDOWS_NUM 32
12#define MAX_FRIENDS_NUM 100 15#define MAX_FRIENDS_NUM 100
@@ -23,7 +26,7 @@
23typedef struct ToxWindow_ ToxWindow; 26typedef struct ToxWindow_ ToxWindow;
24 27
25struct ToxWindow_ { 28struct ToxWindow_ {
26 void(*onKey)(ToxWindow *, Messenger *, int); 29 void(*onKey)(ToxWindow *, Messenger *, wint_t);
27 void(*onDraw)(ToxWindow *, Messenger *); 30 void(*onDraw)(ToxWindow *, Messenger *);
28 void(*onInit)(ToxWindow *, Messenger *); 31 void(*onInit)(ToxWindow *, Messenger *);
29 void(*onFriendRequest)(ToxWindow *, uint8_t *, uint8_t *, uint16_t); 32 void(*onFriendRequest)(ToxWindow *, uint8_t *, uint8_t *, uint16_t);