diff options
-rw-r--r-- | cmake/FindLIBCONFIG.cmake | 7 | ||||
-rw-r--r-- | core/DHT.c | 2 | ||||
-rw-r--r-- | core/Messenger.c | 88 | ||||
-rw-r--r-- | core/Messenger.h | 38 | ||||
-rw-r--r-- | core/friend_requests.c | 2 | ||||
-rw-r--r-- | core/ping.c | 19 | ||||
-rw-r--r-- | docs/install.rst | 2 | ||||
-rw-r--r-- | testing/nTox.c | 6 | ||||
-rw-r--r-- | testing/nTox_win32.c | 26 | ||||
-rw-r--r-- | testing/toxic/chat.c | 22 | ||||
-rw-r--r-- | testing/toxic/friendlist.c | 62 | ||||
-rw-r--r-- | testing/toxic/main.c | 170 | ||||
-rw-r--r-- | testing/toxic/prompt.c | 94 | ||||
-rw-r--r-- | testing/toxic/windows.h | 8 |
14 files changed, 369 insertions, 177 deletions
diff --git a/cmake/FindLIBCONFIG.cmake b/cmake/FindLIBCONFIG.cmake index d5018240..b3ae4d11 100644 --- a/cmake/FindLIBCONFIG.cmake +++ b/cmake/FindLIBCONFIG.cmake | |||
@@ -5,7 +5,12 @@ | |||
5 | # LIBCONFIG_FOUND | 5 | # LIBCONFIG_FOUND |
6 | # | 6 | # |
7 | 7 | ||
8 | FIND_PATH(LIBCONFIG_INCLUDE_DIR NAMES libconfig.h) | 8 | if (UNIX) |
9 | find_package(PkgConfig QUIET) | ||
10 | pkg_check_modules(_LIBCONFIG QUIET libconfig) | ||
11 | endif () | ||
12 | |||
13 | FIND_PATH(LIBCONFIG_INCLUDE_DIR NAMES libconfig.h HINTS ${_LIBCONFIG_INCLUDEDIR}) | ||
9 | 14 | ||
10 | FIND_LIBRARY(LIBCONFIG_LIBRARY NAMES config) | 15 | FIND_LIBRARY(LIBCONFIG_LIBRARY NAMES config) |
11 | 16 | ||
@@ -933,7 +933,7 @@ static int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type) | |||
933 | static int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source) | 933 | static int handle_NATping(uint8_t * packet, uint32_t length, IP_Port source) |
934 | { | 934 | { |
935 | if (length < crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + ENCRYPTION_PADDING | 935 | if (length < crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + ENCRYPTION_PADDING |
936 | && length > MAX_DATA_SIZE + ENCRYPTION_PADDING) | 936 | || length > MAX_DATA_SIZE + ENCRYPTION_PADDING) |
937 | return 1; | 937 | return 1; |
938 | 938 | ||
939 | /* check if request is for us. */ | 939 | /* check if request is for us. */ |
diff --git a/core/Messenger.c b/core/Messenger.c index 57d485bb..d8bf3413 100644 --- a/core/Messenger.c +++ b/core/Messenger.c | |||
@@ -35,6 +35,7 @@ typedef struct { | |||
35 | uint8_t *userstatus; | 35 | uint8_t *userstatus; |
36 | uint16_t userstatus_length; | 36 | uint16_t userstatus_length; |
37 | uint8_t userstatus_sent; | 37 | uint8_t userstatus_sent; |
38 | USERSTATUS_KIND userstatus_kind; | ||
38 | uint16_t info_size; /* length of the info */ | 39 | uint16_t info_size; /* length of the info */ |
39 | } Friend; | 40 | } Friend; |
40 | 41 | ||
@@ -45,6 +46,7 @@ static uint16_t self_name_length; | |||
45 | 46 | ||
46 | static uint8_t *self_userstatus; | 47 | static uint8_t *self_userstatus; |
47 | static uint16_t self_userstatus_len; | 48 | static uint16_t self_userstatus_len; |
49 | static USERSTATUS_KIND self_userstatus_kind; | ||
48 | 50 | ||
49 | #define MAX_NUM_FRIENDS 256 | 51 | #define MAX_NUM_FRIENDS 256 |
50 | 52 | ||
@@ -98,12 +100,12 @@ int getclient_id(int friend_id, uint8_t *client_id) | |||
98 | * return FAERR_NOMESSAGE if no message (message length must be >= 1 byte) | 100 | * return FAERR_NOMESSAGE if no message (message length must be >= 1 byte) |
99 | * return FAERR_OWNKEY if user's own key | 101 | * return FAERR_OWNKEY if user's own key |
100 | * return FAERR_ALREADYSENT if friend request already sent or already a friend | 102 | * return FAERR_ALREADYSENT if friend request already sent or already a friend |
101 | * return FAERR_UNKNOWN for unknown error | 103 | * return FAERR_UNKNOWN for unknown error |
102 | */ | 104 | */ |
103 | int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length) | 105 | int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length) |
104 | { | 106 | { |
105 | if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES | 107 | if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES |
106 | - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES | 108 | - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES |
107 | + crypto_box_ZEROBYTES)) | 109 | + crypto_box_ZEROBYTES)) |
108 | return FAERR_TOOLONG; | 110 | return FAERR_TOOLONG; |
109 | if (length < 1) | 111 | if (length < 1) |
@@ -123,6 +125,7 @@ int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length) | |||
123 | memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE); | 125 | memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE); |
124 | friendlist[i].userstatus = calloc(1, 1); | 126 | friendlist[i].userstatus = calloc(1, 1); |
125 | friendlist[i].userstatus_length = 1; | 127 | friendlist[i].userstatus_length = 1; |
128 | friendlist[i].userstatus_kind = USERSTATUS_KIND_OFFLINE; | ||
126 | memcpy(friendlist[i].info, data, length); | 129 | memcpy(friendlist[i].info, data, length); |
127 | friendlist[i].info_size = length; | 130 | friendlist[i].info_size = length; |
128 | 131 | ||
@@ -205,7 +208,7 @@ int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length) | |||
205 | return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, temp, length + 1); | 208 | return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, temp, length + 1); |
206 | } | 209 | } |
207 | 210 | ||
208 | /* send a name packet to friendnumber | 211 | /* send a name packet to friendnumber |
209 | length is the length with the NULL terminator*/ | 212 | length is the length with the NULL terminator*/ |
210 | static int m_sendname(int friendnumber, uint8_t * name, uint16_t length) | 213 | static int m_sendname(int friendnumber, uint8_t * name, uint16_t length) |
211 | { | 214 | { |
@@ -247,14 +250,14 @@ int setname(uint8_t * name, uint16_t length) | |||
247 | } | 250 | } |
248 | 251 | ||
249 | /* get our nickname | 252 | /* get our nickname |
250 | put it in name | 253 | put it in name |
251 | name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes. | 254 | name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes. |
252 | return the length of the name */ | 255 | return the length of the name */ |
253 | uint16_t getself_name(uint8_t *name) | 256 | uint16_t getself_name(uint8_t *name) |
254 | { | 257 | { |
255 | memcpy(name, self_name, self_name_length); | 258 | memcpy(name, self_name, self_name_length); |
256 | return self_name_length; | 259 | return self_name_length; |
257 | } | 260 | } |
258 | 261 | ||
259 | /* get name of friendnumber | 262 | /* get name of friendnumber |
260 | put it in name | 263 | put it in name |
@@ -269,10 +272,13 @@ int getname(int friendnumber, uint8_t * name) | |||
269 | return 0; | 272 | return 0; |
270 | } | 273 | } |
271 | 274 | ||
272 | int m_set_userstatus(uint8_t *status, uint16_t length) | 275 | int m_set_userstatus(USERSTATUS_KIND kind, uint8_t *status, uint16_t length) |
273 | { | 276 | { |
274 | if (length > MAX_USERSTATUS_LENGTH) | 277 | if (length > MAX_USERSTATUS_LENGTH) |
275 | return -1; | 278 | return -1; |
279 | if (kind != USERSTATUS_KIND_RETAIN) { | ||
280 | self_userstatus_kind = kind; | ||
281 | } | ||
276 | uint8_t *newstatus = calloc(length, 1); | 282 | uint8_t *newstatus = calloc(length, 1); |
277 | memcpy(newstatus, status, length); | 283 | memcpy(newstatus, status, length); |
278 | free(self_userstatus); | 284 | free(self_userstatus); |
@@ -285,6 +291,20 @@ int m_set_userstatus(uint8_t *status, uint16_t length) | |||
285 | return 0; | 291 | return 0; |
286 | } | 292 | } |
287 | 293 | ||
294 | int m_set_userstatus_kind(USERSTATUS_KIND kind) { | ||
295 | if (kind >= USERSTATUS_KIND_INVALID) { | ||
296 | return -1; | ||
297 | } | ||
298 | if (kind == USERSTATUS_KIND_RETAIN) { | ||
299 | return 0; | ||
300 | } | ||
301 | self_userstatus_kind = kind; | ||
302 | uint32_t i; | ||
303 | for (i = 0; i < numfriends; ++i) | ||
304 | friendlist[i].userstatus_sent = 0; | ||
305 | return 0; | ||
306 | } | ||
307 | |||
288 | /* return the size of friendnumber's user status | 308 | /* return the size of friendnumber's user status |
289 | guaranteed to be at most MAX_USERSTATUS_LENGTH */ | 309 | guaranteed to be at most MAX_USERSTATUS_LENGTH */ |
290 | int m_get_userstatus_size(int friendnumber) | 310 | int m_get_userstatus_size(int friendnumber) |
@@ -305,11 +325,33 @@ int m_copy_userstatus(int friendnumber, uint8_t * buf, uint32_t maxlen) | |||
305 | return 0; | 325 | return 0; |
306 | } | 326 | } |
307 | 327 | ||
328 | int m_copy_self_userstatus(uint8_t * buf, uint32_t maxlen) | ||
329 | { | ||
330 | memset(buf, 0, maxlen); | ||
331 | memcpy(buf, self_userstatus, MIN(maxlen, MAX_USERSTATUS_LENGTH) - 1); | ||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | USERSTATUS_KIND m_get_userstatus_kind(int friendnumber) { | ||
336 | if (friendnumber >= numfriends || friendnumber < 0) | ||
337 | return USERSTATUS_KIND_INVALID; | ||
338 | USERSTATUS_KIND uk = friendlist[friendnumber].userstatus_kind; | ||
339 | if (uk >= USERSTATUS_KIND_INVALID) { | ||
340 | uk = USERSTATUS_KIND_ONLINE; | ||
341 | } | ||
342 | return uk; | ||
343 | } | ||
344 | |||
345 | USERSTATUS_KIND m_get_self_userstatus_kind(void) { | ||
346 | return self_userstatus_kind; | ||
347 | } | ||
348 | |||
308 | static int send_userstatus(int friendnumber, uint8_t * status, uint16_t length) | 349 | static int send_userstatus(int friendnumber, uint8_t * status, uint16_t length) |
309 | { | 350 | { |
310 | uint8_t *thepacket = malloc(length + 1); | 351 | uint8_t *thepacket = malloc(length + 2); |
311 | memcpy(thepacket + 1, status, length); | 352 | memcpy(thepacket + 2, status, length); |
312 | thepacket[0] = PACKET_ID_USERSTATUS; | 353 | thepacket[0] = PACKET_ID_USERSTATUS; |
354 | thepacket[1] = self_userstatus_kind; | ||
313 | int written = write_cryptpacket(friendlist[friendnumber].crypt_connection_id, thepacket, length + 1); | 355 | int written = write_cryptpacket(friendlist[friendnumber].crypt_connection_id, thepacket, length + 1); |
314 | free(thepacket); | 356 | free(thepacket); |
315 | return written; | 357 | return written; |
@@ -327,6 +369,11 @@ static int set_friend_userstatus(int friendnumber, uint8_t * status, uint16_t le | |||
327 | return 0; | 369 | return 0; |
328 | } | 370 | } |
329 | 371 | ||
372 | static void set_friend_userstatus_kind(int friendnumber, USERSTATUS_KIND k) | ||
373 | { | ||
374 | friendlist[friendnumber].userstatus_kind = k; | ||
375 | } | ||
376 | |||
330 | /* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); | 377 | /* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); |
331 | static uint8_t friend_request_isset = 0; */ | 378 | static uint8_t friend_request_isset = 0; */ |
332 | /* set the function that will be executed when a friend request is received. */ | 379 | /* set the function that will be executed when a friend request is received. */ |
@@ -353,9 +400,9 @@ void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t)) | |||
353 | friend_namechange_isset = 1; | 400 | friend_namechange_isset = 1; |
354 | } | 401 | } |
355 | 402 | ||
356 | static void (*friend_statuschange)(int, uint8_t *, uint16_t); | 403 | static void (*friend_statuschange)(int, USERSTATUS_KIND, uint8_t *, uint16_t); |
357 | static uint8_t friend_statuschange_isset = 0; | 404 | static uint8_t friend_statuschange_isset = 0; |
358 | void m_callback_userstatus(void (*function)(int, uint8_t *, uint16_t)) | 405 | void m_callback_userstatus(void (*function)(int, USERSTATUS_KIND, uint8_t *, uint16_t)) |
359 | { | 406 | { |
360 | friend_statuschange = function; | 407 | friend_statuschange = function; |
361 | friend_statuschange_isset = 1; | 408 | friend_statuschange_isset = 1; |
@@ -366,7 +413,7 @@ void m_callback_userstatus(void (*function)(int, uint8_t *, uint16_t)) | |||
366 | int initMessenger(void) | 413 | int initMessenger(void) |
367 | { | 414 | { |
368 | new_keys(); | 415 | new_keys(); |
369 | m_set_userstatus((uint8_t*)"Online", sizeof("Online")); | 416 | m_set_userstatus(USERSTATUS_KIND_ONLINE, (uint8_t*)"Online", sizeof("Online")); |
370 | initNetCrypto(); | 417 | initNetCrypto(); |
371 | IP ip; | 418 | IP ip; |
372 | ip.i = 0; | 419 | ip.i = 0; |
@@ -438,12 +485,17 @@ static void doFriends(void) | |||
438 | break; | 485 | break; |
439 | } | 486 | } |
440 | case PACKET_ID_USERSTATUS: { | 487 | case PACKET_ID_USERSTATUS: { |
441 | uint8_t *status = calloc(MIN(len - 1, MAX_USERSTATUS_LENGTH), 1); | 488 | if (len > 2) { |
442 | memcpy(status, temp + 1, MIN(len - 1, MAX_USERSTATUS_LENGTH)); | 489 | uint8_t *status = calloc(MIN(len - 2, MAX_USERSTATUS_LENGTH), 1); |
443 | if (friend_statuschange_isset) | 490 | memcpy(status, temp + 2, MIN(len - 2, MAX_USERSTATUS_LENGTH)); |
444 | friend_statuschange(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH)); | 491 | if (friend_statuschange_isset) |
445 | set_friend_userstatus(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH)); | 492 | friend_statuschange(i, temp[1], status, MIN(len - 2, MAX_USERSTATUS_LENGTH)); |
446 | free(status); | 493 | set_friend_userstatus(i, status, MIN(len - 2, MAX_USERSTATUS_LENGTH)); |
494 | free(status); | ||
495 | } else if (friend_statuschange_isset) { | ||
496 | friend_statuschange(i, temp[1], friendlist[i].userstatus, friendlist[i].userstatus_length); | ||
497 | } | ||
498 | set_friend_userstatus_kind(i, temp[1]); | ||
447 | break; | 499 | break; |
448 | } | 500 | } |
449 | case PACKET_ID_MESSAGE: { | 501 | case PACKET_ID_MESSAGE: { |
diff --git a/core/Messenger.h b/core/Messenger.h index 20b38caa..8940aadd 100644 --- a/core/Messenger.h +++ b/core/Messenger.h | |||
@@ -60,6 +60,22 @@ extern "C" { | |||
60 | /* don't assume MAX_USERSTATUS_LENGTH will stay at 128, it may be increased | 60 | /* don't assume MAX_USERSTATUS_LENGTH will stay at 128, it may be increased |
61 | to an absurdly large number later */ | 61 | to an absurdly large number later */ |
62 | 62 | ||
63 | /* USERSTATUS_KIND | ||
64 | * Represents the different kinds of userstatus | ||
65 | * someone can have. | ||
66 | * More on this later... */ | ||
67 | |||
68 | typedef enum { | ||
69 | USERSTATUS_KIND_RETAIN = (uint8_t)0, /* This is a special value that must not be returned by | ||
70 | * m_get_userstatus_kind. You can pass it into m_set_userstatus | ||
71 | * to keep the current USERSTATUS_KIND. */ | ||
72 | USERSTATUS_KIND_ONLINE, /* Recommended representation: Green. */ | ||
73 | USERSTATUS_KIND_AWAY, /* Recommended representation: Orange, or yellow. */ | ||
74 | USERSTATUS_KIND_BUSY, /* Recommended representation: Red. */ | ||
75 | USERSTATUS_KIND_OFFLINE, /* Recommended representation: Grey, semi-transparent. */ | ||
76 | USERSTATUS_KIND_INVALID, | ||
77 | } USERSTATUS_KIND; | ||
78 | |||
63 | /* | 79 | /* |
64 | * add a friend | 80 | * add a friend |
65 | * set the data that will be sent along with friend request | 81 | * set the data that will be sent along with friend request |
@@ -70,7 +86,7 @@ extern "C" { | |||
70 | * return -2 if no message (message length must be >= 1 byte) | 86 | * return -2 if no message (message length must be >= 1 byte) |
71 | * return -3 if user's own key | 87 | * return -3 if user's own key |
72 | * return -4 if friend request already sent or already a friend | 88 | * return -4 if friend request already sent or already a friend |
73 | * return -5 for unknown error | 89 | * return -5 for unknown error |
74 | */ | 90 | */ |
75 | int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length); | 91 | int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length); |
76 | 92 | ||
@@ -114,7 +130,7 @@ int m_sendmessage(int friendnumber, uint8_t *message, uint32_t length); | |||
114 | int setname(uint8_t *name, uint16_t length); | 130 | int setname(uint8_t *name, uint16_t length); |
115 | 131 | ||
116 | /* get our nickname | 132 | /* get our nickname |
117 | put it in name | 133 | put it in name |
118 | return the length of the name*/ | 134 | return the length of the name*/ |
119 | uint16_t getself_name(uint8_t *name); | 135 | uint16_t getself_name(uint8_t *name); |
120 | 136 | ||
@@ -128,7 +144,8 @@ int getname(int friendnumber, uint8_t *name); | |||
128 | /* set our user status | 144 | /* set our user status |
129 | you are responsible for freeing status after | 145 | you are responsible for freeing status after |
130 | returns 0 on success, -1 on failure */ | 146 | returns 0 on success, -1 on failure */ |
131 | int m_set_userstatus(uint8_t *status, uint16_t length); | 147 | int m_set_userstatus(USERSTATUS_KIND kind, uint8_t *status, uint16_t length); |
148 | int m_set_userstatus_kind(USERSTATUS_KIND kind); | ||
132 | 149 | ||
133 | /* return the length of friendnumber's user status, | 150 | /* return the length of friendnumber's user status, |
134 | including null | 151 | including null |
@@ -136,8 +153,17 @@ int m_set_userstatus(uint8_t *status, uint16_t length); | |||
136 | int m_get_userstatus_size(int friendnumber); | 153 | int m_get_userstatus_size(int friendnumber); |
137 | 154 | ||
138 | /* copy friendnumber's userstatus into buf, truncating if size is over maxlen | 155 | /* copy friendnumber's userstatus into buf, truncating if size is over maxlen |
139 | get the size you need to allocate from m_get_userstatus_size */ | 156 | get the size you need to allocate from m_get_userstatus_size |
157 | The self variant will copy our own userstatus. */ | ||
140 | int m_copy_userstatus(int friendnumber, uint8_t *buf, uint32_t maxlen); | 158 | int m_copy_userstatus(int friendnumber, uint8_t *buf, uint32_t maxlen); |
159 | int m_copy_self_userstatus(uint8_t *buf, uint32_t maxlen); | ||
160 | |||
161 | /* Return one of USERSTATUS_KIND values, except USERSTATUS_KIND_RETAIN. | ||
162 | * Values unknown to your application should be represented as USERSTATUS_KIND_ONLINE. | ||
163 | * As above, the self variant will return our own USERSTATUS_KIND. | ||
164 | * If friendnumber is invalid, this shall return USERSTATUS_KIND_INVALID. */ | ||
165 | USERSTATUS_KIND m_get_userstatus_kind(int friendnumber); | ||
166 | USERSTATUS_KIND m_get_self_userstatus_kind(void); | ||
141 | 167 | ||
142 | /* set the function that will be executed when a friend request is received. | 168 | /* set the function that will be executed when a friend request is received. |
143 | function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ | 169 | function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ |
@@ -153,9 +179,9 @@ void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t)); | |||
153 | void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t)); | 179 | void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t)); |
154 | 180 | ||
155 | /* set the callback for user status changes | 181 | /* set the callback for user status changes |
156 | function(int friendnumber, uint8_t *newstatus, uint16_t length) | 182 | function(int friendnumber, USERSTATUS_KIND kind, uint8_t *newstatus, uint16_t length) |
157 | you are not responsible for freeing newstatus */ | 183 | you are not responsible for freeing newstatus */ |
158 | void m_callback_userstatus(void (*function)(int, uint8_t *, uint16_t)); | 184 | void m_callback_userstatus(void (*function)(int, USERSTATUS_KIND, uint8_t *, uint16_t)); |
159 | 185 | ||
160 | /* run this at startup | 186 | /* run this at startup |
161 | returns 0 if no connection problems | 187 | returns 0 if no connection problems |
diff --git a/core/friend_requests.c b/core/friend_requests.c index f1ffb8d0..5550b662 100644 --- a/core/friend_requests.c +++ b/core/friend_requests.c | |||
@@ -104,7 +104,7 @@ static int request_recieved(uint8_t * client_id) | |||
104 | int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) | 104 | int friendreq_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) |
105 | { | 105 | { |
106 | if (packet[0] == 32) { | 106 | if (packet[0] == 32) { |
107 | if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && | 107 | if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING || |
108 | length > MAX_DATA_SIZE + ENCRYPTION_PADDING) | 108 | length > MAX_DATA_SIZE + ENCRYPTION_PADDING) |
109 | return 1; | 109 | return 1; |
110 | if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {// check if request is for us. | 110 | if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {// check if request is for us. |
diff --git a/core/ping.c b/core/ping.c index 3f70b26d..6a1fbb7e 100644 --- a/core/ping.c +++ b/core/ping.c | |||
@@ -18,9 +18,9 @@ | |||
18 | #define PING_TIMEOUT 5 // 5s | 18 | #define PING_TIMEOUT 5 // 5s |
19 | 19 | ||
20 | typedef struct { | 20 | typedef struct { |
21 | IP_Port ipp; | 21 | IP_Port ipp; |
22 | uint64_t id; | 22 | uint64_t id; |
23 | uint64_t timestamp; | 23 | uint64_t timestamp; |
24 | } pinged_t; | 24 | } pinged_t; |
25 | 25 | ||
26 | static pinged_t pings[PING_NUM_MAX]; | 26 | static pinged_t pings[PING_NUM_MAX]; |
@@ -30,7 +30,6 @@ static clientid_t* self_id = (clientid_t*) &self_public_key; | |||
30 | 30 | ||
31 | extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c | 31 | extern uint8_t self_secret_key[crypto_box_SECRETKEYBYTES]; // DHT.c |
32 | 32 | ||
33 | |||
34 | void init_ping() | 33 | void init_ping() |
35 | { | 34 | { |
36 | num_pings = 0; | 35 | num_pings = 0; |
@@ -42,7 +41,7 @@ static bool is_timeout(uint64_t time) | |||
42 | return (time + PING_TIMEOUT) < now(); | 41 | return (time + PING_TIMEOUT) < now(); |
43 | } | 42 | } |
44 | 43 | ||
45 | static void remove_timeouts() // O(n) | 44 | static void remove_timeouts() // O(n) |
46 | { | 45 | { |
47 | size_t i, id; | 46 | size_t i, id; |
48 | size_t new_pos = pos_pings; | 47 | size_t new_pos = pos_pings; |
@@ -62,8 +61,8 @@ static void remove_timeouts() // O(n) | |||
62 | } | 61 | } |
63 | } | 62 | } |
64 | 63 | ||
65 | num_pings = new_num; | 64 | num_pings = new_num; |
66 | pos_pings = new_pos % PING_NUM_MAX; | 65 | pos_pings = new_pos % PING_NUM_MAX; |
67 | } | 66 | } |
68 | 67 | ||
69 | uint64_t add_ping(IP_Port ipp) // O(n) | 68 | uint64_t add_ping(IP_Port ipp) // O(n) |
@@ -89,12 +88,12 @@ uint64_t add_ping(IP_Port ipp) // O(n) | |||
89 | return pings[p].id; | 88 | return pings[p].id; |
90 | } | 89 | } |
91 | 90 | ||
92 | bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) | 91 | bool is_pinging(IP_Port ipp, uint64_t ping_id) // O(n) TODO: replace this with something else. |
93 | { | 92 | { |
94 | size_t i, id; | ||
95 | |||
96 | if (ipp.ip.i == 0 && ping_id == 0) | 93 | if (ipp.ip.i == 0 && ping_id == 0) |
97 | return false; | 94 | return false; |
95 | |||
96 | size_t i, id; | ||
98 | 97 | ||
99 | remove_timeouts(); | 98 | remove_timeouts(); |
100 | 99 | ||
diff --git a/docs/install.rst b/docs/install.rst index c5fea5d1..9b6e2f29 100644 --- a/docs/install.rst +++ b/docs/install.rst | |||
@@ -6,7 +6,7 @@ Linux | |||
6 | 6 | ||
7 | First, install the build dependencies :: | 7 | First, install the build dependencies :: |
8 | 8 | ||
9 | bash apt-get install build-essential libtool autotools-dev automake libconfig-dev ncurses-dev cmake checkinstall | 9 | sudo apt-get install build-essential libtool autotools-dev automake libconfig-dev ncurses-dev cmake checkinstall |
10 | 10 | ||
11 | .. note :: ``libconfig-dev`` should be >= 1.4. | 11 | .. note :: ``libconfig-dev`` should be >= 1.4. |
12 | 12 | ||
diff --git a/testing/nTox.c b/testing/nTox.c index fe91b1fa..63d0c32e 100644 --- a/testing/nTox.c +++ b/testing/nTox.c | |||
@@ -228,7 +228,7 @@ void line_eval(char *line) | |||
228 | status[i-3] = line[i]; | 228 | status[i-3] = line[i]; |
229 | } | 229 | } |
230 | status[i-3] = 0; | 230 | status[i-3] = 0; |
231 | m_set_userstatus(status, strlen((char*)status) + 1); | 231 | m_set_userstatus(USERSTATUS_KIND_ONLINE, status, strlen((char*)status) + 1); |
232 | char numstring[100]; | 232 | char numstring[100]; |
233 | sprintf(numstring, "[i] changed status to %s", (char*)status); | 233 | sprintf(numstring, "[i] changed status to %s", (char*)status); |
234 | new_lines(numstring); | 234 | new_lines(numstring); |
@@ -364,7 +364,7 @@ void print_nickchange(int friendnumber, uint8_t *string, uint16_t length) | |||
364 | } | 364 | } |
365 | } | 365 | } |
366 | 366 | ||
367 | void print_statuschange(int friendnumber, uint8_t *string, uint16_t length) | 367 | void print_statuschange(int friendnumber, USERSTATUS_KIND kind, uint8_t *string, uint16_t length) |
368 | { | 368 | { |
369 | char name[MAX_NAME_LENGTH]; | 369 | char name[MAX_NAME_LENGTH]; |
370 | if(getname(friendnumber, (uint8_t*)name) != -1) { | 370 | if(getname(friendnumber, (uint8_t*)name) != -1) { |
@@ -392,7 +392,7 @@ void load_key(char *path) | |||
392 | } | 392 | } |
393 | Messenger_load(data, size); | 393 | Messenger_load(data, size); |
394 | 394 | ||
395 | } else { | 395 | } else { |
396 | //else save new keys | 396 | //else save new keys |
397 | int size = Messenger_size(); | 397 | int size = Messenger_size(); |
398 | uint8_t data[size]; | 398 | uint8_t data[size]; |
diff --git a/testing/nTox_win32.c b/testing/nTox_win32.c index f3c7a188..dbbd0f6e 100644 --- a/testing/nTox_win32.c +++ b/testing/nTox_win32.c | |||
@@ -18,7 +18,7 @@ | |||
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | 20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include "nTox_win32.h" | 24 | #include "nTox_win32.h" |
@@ -86,7 +86,7 @@ void print_nickchange(int friendnumber, uint8_t *string, uint16_t length) | |||
86 | printf(msg); | 86 | printf(msg); |
87 | } | 87 | } |
88 | 88 | ||
89 | void print_statuschange(int friendnumber, uint8_t *string, uint16_t length) | 89 | void print_statuschange(int friendnumber, USERSTATUS_KIND kind, uint8_t *string, uint16_t length) |
90 | { | 90 | { |
91 | char name[MAX_NAME_LENGTH]; | 91 | char name[MAX_NAME_LENGTH]; |
92 | getname(friendnumber, (uint8_t*)name); | 92 | getname(friendnumber, (uint8_t*)name); |
@@ -95,7 +95,7 @@ void print_statuschange(int friendnumber, uint8_t *string, uint16_t length) | |||
95 | printf(msg); | 95 | printf(msg); |
96 | } | 96 | } |
97 | 97 | ||
98 | void load_key() | 98 | void load_key() |
99 | { | 99 | { |
100 | FILE *data_file = NULL; | 100 | FILE *data_file = NULL; |
101 | data_file = fopen("data","r"); | 101 | data_file = fopen("data","r"); |
@@ -130,7 +130,7 @@ void add_friend() | |||
130 | int i; | 130 | int i; |
131 | char temp_id[128]; | 131 | char temp_id[128]; |
132 | 132 | ||
133 | for (i = 0; i < 128; i++) | 133 | for (i = 0; i < 128; i++) |
134 | temp_id[i] = line[i+3]; | 134 | temp_id[i] = line[i+3]; |
135 | 135 | ||
136 | int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo")); | 136 | int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo")); |
@@ -141,7 +141,7 @@ void add_friend() | |||
141 | printf(numstring); | 141 | printf(numstring); |
142 | ++maxnumfriends; | 142 | ++maxnumfriends; |
143 | } | 143 | } |
144 | else if (num == -1) | 144 | else if (num == -1) |
145 | printf("\n[i] Message is too long.\n\n"); | 145 | printf("\n[i] Message is too long.\n\n"); |
146 | 146 | ||
147 | else if (num == -2) | 147 | else if (num == -2) |
@@ -180,7 +180,7 @@ void list_friends() | |||
180 | char name[MAX_NAME_LENGTH]; | 180 | char name[MAX_NAME_LENGTH]; |
181 | getname(i, (uint8_t*)name); | 181 | getname(i, (uint8_t*)name); |
182 | 182 | ||
183 | if (m_friendstatus(i) == 4) | 183 | if (m_friendstatus(i) == 4) |
184 | printf("[%d] %s\n", i, (uint8_t*)name); | 184 | printf("[%d] %s\n", i, (uint8_t*)name); |
185 | } | 185 | } |
186 | 186 | ||
@@ -213,7 +213,7 @@ void message_friend() | |||
213 | 213 | ||
214 | for (i = 0; i < len; i++) { | 214 | for (i = 0; i < len; i++) { |
215 | 215 | ||
216 | if (line[i+3] != ' ') | 216 | if (line[i+3] != ' ') |
217 | numstring[i] = line[i+3]; | 217 | numstring[i] = line[i+3]; |
218 | 218 | ||
219 | else { | 219 | else { |
@@ -243,7 +243,7 @@ void change_nickname() | |||
243 | 243 | ||
244 | for (i = 3; i < len; i++) { | 244 | for (i = 3; i < len; i++) { |
245 | 245 | ||
246 | if (line[i] == 0 || line[i] == '\n') | 246 | if (line[i] == 0 || line[i] == '\n') |
247 | break; | 247 | break; |
248 | 248 | ||
249 | name[i-3] = line[i]; | 249 | name[i-3] = line[i]; |
@@ -268,7 +268,7 @@ void change_status(int savetofile) | |||
268 | size_t len = strlen(line); | 268 | size_t len = strlen(line); |
269 | 269 | ||
270 | for (i = 3; i < len; i++) { | 270 | for (i = 3; i < len; i++) { |
271 | if (line[i] == 0 || line[i] == '\n') | 271 | if (line[i] == 0 || line[i] == '\n') |
272 | break; | 272 | break; |
273 | 273 | ||
274 | status[i-3] = line[i]; | 274 | status[i-3] = line[i]; |
@@ -350,7 +350,7 @@ void line_eval(char* line) | |||
350 | accept_friend_request(line); | 350 | accept_friend_request(line); |
351 | } | 351 | } |
352 | /* EXIT */ | 352 | /* EXIT */ |
353 | else if (inpt_command == 'q') { | 353 | else if (inpt_command == 'q') { |
354 | strcpy(line, "---Offline"); | 354 | strcpy(line, "---Offline"); |
355 | change_status(0); | 355 | change_status(0); |
356 | exit(EXIT_SUCCESS); | 356 | exit(EXIT_SUCCESS); |
@@ -398,7 +398,7 @@ int main(int argc, char *argv[]) | |||
398 | nameloaded = 1; | 398 | nameloaded = 1; |
399 | printf("%s\n", name); | 399 | printf("%s\n", name); |
400 | fclose(name_file); | 400 | fclose(name_file); |
401 | } | 401 | } |
402 | 402 | ||
403 | FILE* status_file = NULL; | 403 | FILE* status_file = NULL; |
404 | status_file = fopen("statusfile.txt", "r"); | 404 | status_file = fopen("statusfile.txt", "r"); |
@@ -424,7 +424,7 @@ int main(int argc, char *argv[]) | |||
424 | { | 424 | { |
425 | if(self_public_key[i] < (PUB_KEY_BYTES/2)) | 425 | if(self_public_key[i] < (PUB_KEY_BYTES/2)) |
426 | strcpy(idstring1[i],"0"); | 426 | strcpy(idstring1[i],"0"); |
427 | else | 427 | else |
428 | strcpy(idstring1[i], ""); | 428 | strcpy(idstring1[i], ""); |
429 | sprintf(idstring2[i], "%hhX",self_public_key[i]); | 429 | sprintf(idstring2[i], "%hhX",self_public_key[i]); |
430 | } | 430 | } |
@@ -442,7 +442,7 @@ int main(int argc, char *argv[]) | |||
442 | int resolved_address = resolve_addr(argv[1]); | 442 | int resolved_address = resolve_addr(argv[1]); |
443 | if (resolved_address != 0) | 443 | if (resolved_address != 0) |
444 | bootstrap_ip_port.ip.i = resolved_address; | 444 | bootstrap_ip_port.ip.i = resolved_address; |
445 | else | 445 | else |
446 | exit(1); | 446 | exit(1); |
447 | 447 | ||
448 | DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3])); | 448 | DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3])); |
diff --git a/testing/toxic/chat.c b/testing/toxic/chat.c index ff7a1667..7262e722 100644 --- a/testing/toxic/chat.c +++ b/testing/toxic/chat.c | |||
@@ -25,6 +25,8 @@ typedef struct { | |||
25 | 25 | ||
26 | } ChatContext; | 26 | } ChatContext; |
27 | 27 | ||
28 | extern int w_active; | ||
29 | extern void del_window(ToxWindow *w, int f_num); | ||
28 | extern void fix_name(uint8_t* name); | 30 | extern void fix_name(uint8_t* name); |
29 | void print_help(ChatContext* self); | 31 | void print_help(ChatContext* self); |
30 | void execute(ToxWindow* self, ChatContext* ctx, char* cmd); | 32 | void execute(ToxWindow* self, ChatContext* ctx, char* cmd); |
@@ -32,7 +34,7 @@ void execute(ToxWindow* self, ChatContext* ctx, char* cmd); | |||
32 | static void chat_onMessage(ToxWindow* self, int num, uint8_t* msg, uint16_t len) { | 34 | static void chat_onMessage(ToxWindow* self, int num, uint8_t* msg, uint16_t len) { |
33 | ChatContext* ctx = (ChatContext*) self->x; | 35 | ChatContext* ctx = (ChatContext*) self->x; |
34 | uint8_t nick[MAX_NAME_LENGTH] = {0}; | 36 | uint8_t nick[MAX_NAME_LENGTH] = {0}; |
35 | 37 | ||
36 | time_t now; | 38 | time_t now; |
37 | time(&now); | 39 | time(&now); |
38 | struct tm * timeinfo; | 40 | struct tm * timeinfo; |
@@ -50,7 +52,7 @@ static void chat_onMessage(ToxWindow* self, int num, uint8_t* msg, uint16_t len) | |||
50 | fix_name(nick); | 52 | fix_name(nick); |
51 | 53 | ||
52 | wattron(ctx->history, COLOR_PAIR(2)); | 54 | wattron(ctx->history, COLOR_PAIR(2)); |
53 | 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); |
54 | wattroff(ctx->history, COLOR_PAIR(2)); | 56 | wattroff(ctx->history, COLOR_PAIR(2)); |
55 | wattron(ctx->history, COLOR_PAIR(4)); | 57 | wattron(ctx->history, COLOR_PAIR(4)); |
56 | wprintw(ctx->history, "%s: ", nick); | 58 | wprintw(ctx->history, "%s: ", nick); |
@@ -58,6 +60,8 @@ static void chat_onMessage(ToxWindow* self, int num, uint8_t* msg, uint16_t len) | |||
58 | wprintw(ctx->history, "%s\n", msg); | 60 | wprintw(ctx->history, "%s\n", msg); |
59 | 61 | ||
60 | self->blink = true; | 62 | self->blink = true; |
63 | beep(); | ||
64 | flash(); | ||
61 | } | 65 | } |
62 | 66 | ||
63 | static void chat_onNickChange(ToxWindow* self, int num, uint8_t* nick, uint16_t len) { | 67 | static void chat_onNickChange(ToxWindow* self, int num, uint8_t* nick, uint16_t len) { |
@@ -116,7 +120,7 @@ static void chat_onKey(ToxWindow* self, int key) { | |||
116 | if(!string_is_empty(ctx->line)) { | 120 | if(!string_is_empty(ctx->line)) { |
117 | /* make sure the string has at least non-space character */ | 121 | /* make sure the string has at least non-space character */ |
118 | wattron(ctx->history, COLOR_PAIR(2)); | 122 | wattron(ctx->history, COLOR_PAIR(2)); |
119 | wprintw(ctx->history, "%02d:%02d:%02d ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); | 123 | wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); |
120 | wattroff(ctx->history, COLOR_PAIR(2)); | 124 | wattroff(ctx->history, COLOR_PAIR(2)); |
121 | wattron(ctx->history, COLOR_PAIR(1)); | 125 | wattron(ctx->history, COLOR_PAIR(1)); |
122 | wprintw(ctx->history, "you: ", ctx->line); | 126 | wprintw(ctx->history, "you: ", ctx->line); |
@@ -161,7 +165,7 @@ void execute(ToxWindow* self, ChatContext* ctx, char* cmd) | |||
161 | return; | 165 | return; |
162 | } | 166 | } |
163 | msg++; | 167 | msg++; |
164 | m_set_userstatus((uint8_t*) msg, strlen(msg)+1); | 168 | m_set_userstatus(USERSTATUS_KIND_RETAIN, (uint8_t*) msg, strlen(msg)+1); |
165 | wprintw(ctx->history, "Status set to: %s\n", msg); | 169 | wprintw(ctx->history, "Status set to: %s\n", msg); |
166 | } | 170 | } |
167 | else if (!strncmp(cmd, "/nick ", strlen("/nick "))) { | 171 | else if (!strncmp(cmd, "/nick ", strlen("/nick "))) { |
@@ -185,6 +189,12 @@ void execute(ToxWindow* self, ChatContext* ctx, char* cmd) | |||
185 | } | 189 | } |
186 | wprintw(ctx->history, "Your ID: %s\n", id); | 190 | wprintw(ctx->history, "Your ID: %s\n", id); |
187 | } | 191 | } |
192 | else if (strcmp(ctx->line, "/close") == 0) { | ||
193 | w_active = 0; // Go to prompt screen | ||
194 | int f_num = ctx->friendnum; | ||
195 | delwin(ctx->linewin); | ||
196 | del_window(self, f_num); | ||
197 | } | ||
188 | else | 198 | else |
189 | wprintw(ctx->history, "Invalid command.\n"); | 199 | wprintw(ctx->history, "Invalid command.\n"); |
190 | } | 200 | } |
@@ -217,17 +227,19 @@ static void chat_onInit(ToxWindow* self) { | |||
217 | scrollok(ctx->history, 1); | 227 | scrollok(ctx->history, 1); |
218 | 228 | ||
219 | ctx->linewin = subwin(self->window, 2, x, y - 3, 0); | 229 | ctx->linewin = subwin(self->window, 2, x, y - 3, 0); |
230 | print_help(ctx); | ||
220 | } | 231 | } |
221 | 232 | ||
222 | void print_help(ChatContext* self) { | 233 | void print_help(ChatContext* self) { |
223 | wattron(self->history, COLOR_PAIR(2) | A_BOLD); | 234 | wattron(self->history, COLOR_PAIR(2) | A_BOLD); |
224 | wprintw(self->history, "\nCommands:\n"); | 235 | wprintw(self->history, "Commands:\n"); |
225 | wattroff(self->history, A_BOLD); | 236 | wattroff(self->history, A_BOLD); |
226 | 237 | ||
227 | wprintw(self->history, " /status <message> : Set your status\n"); | 238 | wprintw(self->history, " /status <message> : Set your status\n"); |
228 | wprintw(self->history, " /nick <nickname> : Set your nickname\n"); | 239 | wprintw(self->history, " /nick <nickname> : Set your nickname\n"); |
229 | wprintw(self->history, " /myid : Print your ID\n"); | 240 | wprintw(self->history, " /myid : Print your ID\n"); |
230 | wprintw(self->history, " /clear : Clear the screen\n"); | 241 | wprintw(self->history, " /clear : Clear the screen\n"); |
242 | wprintw(self->history, " /close : Close the current chat window\n"); | ||
231 | wprintw(self->history, " /quit or /exit : Exit program\n"); | 243 | wprintw(self->history, " /quit or /exit : Exit program\n"); |
232 | wprintw(self->history, " /help : Print this message again\n\n"); | 244 | wprintw(self->history, " /help : Print this message again\n\n"); |
233 | 245 | ||
diff --git a/testing/toxic/friendlist.c b/testing/toxic/friendlist.c index b4b619a2..94e8fb47 100644 --- a/testing/toxic/friendlist.c +++ b/testing/toxic/friendlist.c | |||
@@ -12,11 +12,10 @@ | |||
12 | 12 | ||
13 | #include "windows.h" | 13 | #include "windows.h" |
14 | 14 | ||
15 | extern int add_window(ToxWindow w); | 15 | extern char WINDOW_STATUS[TOXWINDOWS_MAX_NUM]; |
16 | extern int focus_window(int num); | 16 | extern int add_window(ToxWindow w, int n); |
17 | extern ToxWindow new_chat(int friendnum); | 17 | extern ToxWindow new_chat(int friendnum); |
18 | 18 | extern int w_active; | |
19 | #define MAX_FRIENDS_NUM 100 | ||
20 | 19 | ||
21 | typedef struct { | 20 | typedef struct { |
22 | uint8_t name[MAX_NAME_LENGTH]; | 21 | uint8_t name[MAX_NAME_LENGTH]; |
@@ -53,7 +52,17 @@ void friendlist_onMessage(ToxWindow* self, int num, uint8_t* str, uint16_t len) | |||
53 | return; | 52 | return; |
54 | 53 | ||
55 | if(friends[num].chatwin == -1) { | 54 | if(friends[num].chatwin == -1) { |
56 | friends[num].chatwin = add_window(new_chat(num)); | 55 | friends[num].chatwin = num; |
56 | int i; | ||
57 | /* Find first open slot to hold chat window */ | ||
58 | for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; i++) { | ||
59 | if (WINDOW_STATUS[i] == -1) { | ||
60 | WINDOW_STATUS[i] = num; | ||
61 | add_window(new_chat(num), i); | ||
62 | w_active = i; | ||
63 | break; | ||
64 | } | ||
65 | } | ||
57 | } | 66 | } |
58 | } | 67 | } |
59 | 68 | ||
@@ -86,29 +95,42 @@ int friendlist_onFriendAdded(int num) { | |||
86 | getname(num, friends[num_friends].name); | 95 | getname(num, friends[num_friends].name); |
87 | strcpy((char*) friends[num_friends].name, "unknown"); | 96 | strcpy((char*) friends[num_friends].name, "unknown"); |
88 | strcpy((char*) friends[num_friends].status, "unknown"); | 97 | strcpy((char*) friends[num_friends].status, "unknown"); |
89 | friends[num_friends].chatwin = -1; | 98 | friends[num_friends++].chatwin = -1; |
90 | |||
91 | num_friends++; | ||
92 | return 0; | 99 | return 0; |
93 | } | 100 | } |
94 | 101 | ||
95 | static void friendlist_onKey(ToxWindow* self, int key) { | 102 | static void friendlist_onKey(ToxWindow* self, int key) { |
96 | |||
97 | if(key == KEY_UP) { | 103 | if(key == KEY_UP) { |
98 | if(num_selected != 0) | 104 | num_selected--; |
99 | num_selected--; | 105 | if (num_selected < 0) |
106 | num_selected = num_friends-1; | ||
100 | } | 107 | } |
101 | else if(key == KEY_DOWN) { | 108 | else if(key == KEY_DOWN) { |
102 | if(num_friends != 0) | 109 | if(num_friends != 0) |
103 | num_selected = (num_selected+1) % num_friends; | 110 | num_selected = (num_selected+1) % num_friends; |
104 | } | 111 | } |
105 | else if(key == '\n') { | 112 | else if(key == '\n') { |
106 | 113 | /* Jump to chat window if already open */ | |
107 | if(friends[num_selected].chatwin != -1) | 114 | if (friends[num_selected].chatwin != -1) { |
108 | return; | 115 | int i; |
109 | 116 | for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; i++) { | |
110 | friends[num_selected].chatwin = add_window(new_chat(num_selected)); | 117 | if (WINDOW_STATUS[i] == num_selected) { |
111 | focus_window(friends[num_selected].chatwin); | 118 | w_active = i; |
119 | break; | ||
120 | } | ||
121 | } | ||
122 | }else { | ||
123 | int i; | ||
124 | for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; i++) { | ||
125 | if (WINDOW_STATUS[i] == -1) { | ||
126 | WINDOW_STATUS[i] = num_selected; | ||
127 | friends[num_selected].chatwin = num_selected; | ||
128 | add_window(new_chat(num_selected), i); | ||
129 | w_active = i; | ||
130 | break; | ||
131 | } | ||
132 | } | ||
133 | } | ||
112 | } | 134 | } |
113 | } | 135 | } |
114 | 136 | ||
@@ -116,7 +138,7 @@ static void friendlist_onDraw(ToxWindow* self) { | |||
116 | curs_set(0); | 138 | curs_set(0); |
117 | size_t i; | 139 | size_t i; |
118 | 140 | ||
119 | wclear(self->window); | 141 | werase(self->window); |
120 | 142 | ||
121 | if(num_friends == 0) { | 143 | if(num_friends == 0) { |
122 | wprintw(self->window, "Empty. Add some friends! :-)\n"); | 144 | wprintw(self->window, "Empty. Add some friends! :-)\n"); |
@@ -145,6 +167,10 @@ static void friendlist_onDraw(ToxWindow* self) { | |||
145 | wrefresh(self->window); | 167 | wrefresh(self->window); |
146 | } | 168 | } |
147 | 169 | ||
170 | void disable_chatwin(int f_num) { | ||
171 | friends[f_num].chatwin = -1; | ||
172 | } | ||
173 | |||
148 | static void friendlist_onInit(ToxWindow* self) { | 174 | static void friendlist_onInit(ToxWindow* self) { |
149 | 175 | ||
150 | } | 176 | } |
diff --git a/testing/toxic/main.c b/testing/toxic/main.c index 45760b1c..19a0b959 100644 --- a/testing/toxic/main.c +++ b/testing/toxic/main.c | |||
@@ -17,14 +17,13 @@ extern ToxWindow new_prompt(); | |||
17 | extern ToxWindow new_friendlist(); | 17 | extern ToxWindow new_friendlist(); |
18 | 18 | ||
19 | extern int friendlist_onFriendAdded(int num); | 19 | extern int friendlist_onFriendAdded(int num); |
20 | 20 | extern void disable_chatwin(int f_num); | |
21 | extern int add_req(uint8_t* public_key); // XXX | 21 | extern int add_req(uint8_t* public_key); // XXX |
22 | 22 | ||
23 | #define TOXWINDOWS_MAX_NUM 32 | 23 | char WINDOW_STATUS[MAX_WINDOW_SLOTS]; // Holds status of chat windows |
24 | 24 | static ToxWindow windows[MAX_WINDOW_SLOTS]; | |
25 | static ToxWindow windows[TOXWINDOWS_MAX_NUM]; | 25 | int w_num; |
26 | static int w_num; | 26 | int w_active; |
27 | static int w_active; | ||
28 | static ToxWindow* prompt; | 27 | static ToxWindow* prompt; |
29 | 28 | ||
30 | // CALLBACKS START | 29 | // CALLBACKS START |
@@ -41,7 +40,7 @@ void on_request(uint8_t* public_key, uint8_t* data, uint16_t length) { | |||
41 | 40 | ||
42 | wprintw(prompt->window, "Use \"accept %d\" to accept it.\n", n); | 41 | wprintw(prompt->window, "Use \"accept %d\" to accept it.\n", n); |
43 | 42 | ||
44 | for(i=0; i<w_num; i++) { | 43 | for(i=0; i<MAX_WINDOW_SLOTS; i++) { |
45 | if(windows[i].onFriendRequest != NULL) | 44 | if(windows[i].onFriendRequest != NULL) |
46 | windows[i].onFriendRequest(&windows[i], public_key, data, length); | 45 | windows[i].onFriendRequest(&windows[i], public_key, data, length); |
47 | } | 46 | } |
@@ -52,7 +51,7 @@ void on_message(int friendnumber, uint8_t* string, uint16_t length) { | |||
52 | 51 | ||
53 | wprintw(prompt->window, "\n(message) %d: %s\n", friendnumber, string); | 52 | wprintw(prompt->window, "\n(message) %d: %s\n", friendnumber, string); |
54 | 53 | ||
55 | for(i=0; i<w_num; i++) { | 54 | for(i=0; i<MAX_WINDOW_SLOTS; i++) { |
56 | if(windows[i].onMessage != NULL) | 55 | if(windows[i].onMessage != NULL) |
57 | windows[i].onMessage(&windows[i], friendnumber, string, length); | 56 | windows[i].onMessage(&windows[i], friendnumber, string, length); |
58 | } | 57 | } |
@@ -63,18 +62,18 @@ void on_nickchange(int friendnumber, uint8_t* string, uint16_t length) { | |||
63 | 62 | ||
64 | wprintw(prompt->window, "\n(nickchange) %d: %s!\n", friendnumber, string); | 63 | wprintw(prompt->window, "\n(nickchange) %d: %s!\n", friendnumber, string); |
65 | 64 | ||
66 | for(i=0; i<w_num; i++) { | 65 | for(i=0; i<MAX_WINDOW_SLOTS; i++) { |
67 | if(windows[i].onNickChange != NULL) | 66 | if(windows[i].onNickChange != NULL) |
68 | windows[i].onNickChange(&windows[i], friendnumber, string, length); | 67 | windows[i].onNickChange(&windows[i], friendnumber, string, length); |
69 | } | 68 | } |
70 | } | 69 | } |
71 | 70 | ||
72 | void on_statuschange(int friendnumber, uint8_t* string, uint16_t length) { | 71 | void on_statuschange(int friendnumber, USERSTATUS_KIND kind, uint8_t* string, uint16_t length) { |
73 | size_t i; | 72 | size_t i; |
74 | 73 | ||
75 | wprintw(prompt->window, "\n(statuschange) %d: %s!\n", friendnumber, string); | 74 | wprintw(prompt->window, "\n(statuschange) %d: %s\n", friendnumber, string); |
76 | 75 | ||
77 | for(i=0; i<w_num; i++) { | 76 | for(i=0; i<MAX_WINDOW_SLOTS; i++) { |
78 | if(windows[i].onStatusChange != NULL) | 77 | if(windows[i].onStatusChange != NULL) |
79 | windows[i].onStatusChange(&windows[i], friendnumber, string, length); | 78 | windows[i].onStatusChange(&windows[i], friendnumber, string, length); |
80 | } | 79 | } |
@@ -115,44 +114,60 @@ static void init_tox() { | |||
115 | m_callback_userstatus(on_statuschange); | 114 | m_callback_userstatus(on_statuschange); |
116 | } | 115 | } |
117 | 116 | ||
118 | int add_window(ToxWindow w) { | 117 | void init_window_status() { |
119 | if(w_num == TOXWINDOWS_MAX_NUM) | 118 | /* Default window values decrement from -2 */ |
119 | int i; | ||
120 | for (i = 0; i < N_DEFAULT_WINS; i++) | ||
121 | WINDOW_STATUS[i] = -(i+2); | ||
122 | |||
123 | int j; | ||
124 | for (j = N_DEFAULT_WINS; j < MAX_WINDOW_SLOTS; j++) | ||
125 | WINDOW_STATUS[j] = -1; | ||
126 | } | ||
127 | |||
128 | int add_window(ToxWindow w, int n) { | ||
129 | if(w_num >= TOXWINDOWS_MAX_NUM) | ||
120 | return -1; | 130 | return -1; |
121 | 131 | ||
122 | if(LINES < 2) | 132 | if(LINES < 2) |
123 | return -1; | 133 | return -1; |
124 | 134 | ||
125 | w.window = newwin(LINES - 2, COLS, 0, 0); | 135 | w.window = newwin(LINES - 2, COLS, 0, 0); |
126 | |||
127 | if(w.window == NULL) | 136 | if(w.window == NULL) |
128 | return -1; | 137 | return -1; |
129 | 138 | ||
130 | windows[w_num++] = w; | 139 | windows[n] = w; |
131 | w.onInit(&w); | 140 | w.onInit(&w); |
132 | 141 | w_num++; | |
133 | return w_num - 1; | 142 | return n; |
134 | } | 143 | } |
135 | 144 | ||
136 | int focus_window(int num) { | 145 | /* Deletes window w and cleans up */ |
137 | if(num >= w_num || num < 0) | 146 | void del_window(ToxWindow *w, int f_num) { |
138 | return -1; | 147 | delwin(w->window); |
139 | 148 | int i; | |
140 | w_active = num; | 149 | for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; i++) { |
141 | return 0; | 150 | if (WINDOW_STATUS[i] == f_num) { |
151 | WINDOW_STATUS[i] = -1; | ||
152 | disable_chatwin(f_num); | ||
153 | break; | ||
154 | } | ||
155 | } | ||
156 | clear(); | ||
157 | refresh(); | ||
142 | } | 158 | } |
143 | 159 | ||
144 | static void init_windows() { | 160 | static void init_windows() { |
145 | w_num = 0; | 161 | w_num = 0; |
146 | w_active = 0; | 162 | int n_prompt = 0; |
147 | 163 | int n_friendslist = 1; | |
148 | if(add_window(new_prompt()) == -1 || add_window(new_friendlist()) == -1) { | 164 | if(add_window(new_prompt(), n_prompt) == -1 |
165 | || add_window(new_friendlist(), n_friendslist) == -1) { | ||
149 | fprintf(stderr, "add_window() failed.\n"); | 166 | fprintf(stderr, "add_window() failed.\n"); |
150 | |||
151 | endwin(); | 167 | endwin(); |
152 | exit(1); | 168 | exit(1); |
153 | } | 169 | } |
154 | 170 | prompt = &windows[n_prompt]; | |
155 | prompt = &windows[0]; | ||
156 | } | 171 | } |
157 | 172 | ||
158 | static void do_tox() { | 173 | static void do_tox() { |
@@ -201,7 +216,7 @@ static void load_data(char *path) { | |||
201 | 216 | ||
202 | Messenger_load(buf, len); | 217 | Messenger_load(buf, len); |
203 | } | 218 | } |
204 | else { | 219 | else { |
205 | len = Messenger_size(); | 220 | len = Messenger_size(); |
206 | buf = malloc(len); | 221 | buf = malloc(len); |
207 | 222 | ||
@@ -238,7 +253,6 @@ static void load_data(char *path) { | |||
238 | 253 | ||
239 | static void draw_bar() { | 254 | static void draw_bar() { |
240 | static int odd = 0; | 255 | static int odd = 0; |
241 | size_t i; | ||
242 | 256 | ||
243 | attron(COLOR_PAIR(4)); | 257 | attron(COLOR_PAIR(4)); |
244 | mvhline(LINES - 2, 0, '_', COLS); | 258 | mvhline(LINES - 2, 0, '_', COLS); |
@@ -250,28 +264,26 @@ static void draw_bar() { | |||
250 | printw(" TOXIC 1.0 |"); | 264 | printw(" TOXIC 1.0 |"); |
251 | attroff(COLOR_PAIR(4) | A_BOLD); | 265 | attroff(COLOR_PAIR(4) | A_BOLD); |
252 | 266 | ||
253 | for(i=0; i<w_num; i++) { | 267 | int i; |
254 | if(i == w_active) { | 268 | for (i = 0; i < (MAX_WINDOW_SLOTS-1); i++) { |
255 | attron(A_BOLD); | 269 | if (WINDOW_STATUS[i] != -1) { |
256 | } | 270 | if (i == w_active) |
257 | 271 | attron(A_BOLD); | |
258 | odd = (odd+1) % 10; | 272 | |
259 | 273 | odd = (odd+1) % 10; | |
260 | if(windows[i].blink && (odd < 5)) { | 274 | if(windows[i].blink && (odd < 5)) { |
261 | attron(COLOR_PAIR(3)); | 275 | attron(COLOR_PAIR(3)); |
262 | } | 276 | } |
263 | 277 | ||
264 | printw(" %s", windows[i].title); | 278 | printw(" %s", windows[i].title); |
265 | 279 | if(windows[i].blink && (odd < 5)) { | |
266 | if(windows[i].blink && (odd < 5)) { | 280 | attron(COLOR_PAIR(3)); |
267 | attron(COLOR_PAIR(3)); | 281 | } |
268 | } | 282 | if(i == w_active) { |
269 | 283 | attroff(A_BOLD); | |
270 | if(i == w_active) { | 284 | } |
271 | attroff(A_BOLD); | ||
272 | } | 285 | } |
273 | } | 286 | } |
274 | |||
275 | refresh(); | 287 | refresh(); |
276 | } | 288 | } |
277 | 289 | ||
@@ -280,6 +292,42 @@ void prepare_window(WINDOW* w) { | |||
280 | wresize(w, LINES-2, COLS); | 292 | wresize(w, LINES-2, COLS); |
281 | } | 293 | } |
282 | 294 | ||
295 | /* Shows next window when tab or back-tab is pressed */ | ||
296 | void set_active_window(int ch) { | ||
297 | int f_inf = 0; | ||
298 | int max = MAX_WINDOW_SLOTS-1; | ||
299 | if (ch == '\t') { | ||
300 | int i = (w_active + 1) % max; | ||
301 | while (true) { | ||
302 | if (WINDOW_STATUS[i] != -1) { | ||
303 | w_active = i; | ||
304 | return; | ||
305 | } | ||
306 | i = (i + 1) % max; | ||
307 | if (f_inf++ > max) { // infinite loop check | ||
308 | endwin(); | ||
309 | clear(); | ||
310 | exit(2); | ||
311 | } | ||
312 | } | ||
313 | }else { | ||
314 | int i = w_active - 1; | ||
315 | if (i < 0) i = max; | ||
316 | while (true) { | ||
317 | if (WINDOW_STATUS[i] != -1) { | ||
318 | w_active = i; | ||
319 | return; | ||
320 | } | ||
321 | if (--i < 0) i = max; | ||
322 | if (f_inf++ > max) { | ||
323 | endwin(); | ||
324 | clear(); | ||
325 | exit(2); | ||
326 | } | ||
327 | } | ||
328 | } | ||
329 | } | ||
330 | |||
283 | int main(int argc, char* argv[]) { | 331 | int main(int argc, char* argv[]) { |
284 | int ch; | 332 | int ch; |
285 | int i = 0; | 333 | int i = 0; |
@@ -289,7 +337,7 @@ int main(int argc, char* argv[]) { | |||
289 | 337 | ||
290 | for(i = 0; i < argc; i++) { | 338 | for(i = 0; i < argc; i++) { |
291 | if (argv[i] == NULL){ | 339 | if (argv[i] == NULL){ |
292 | break; | 340 | break; |
293 | } else if(argv[i][0] == '-') { | 341 | } else if(argv[i][0] == '-') { |
294 | if(argv[i][1] == 'f') { | 342 | if(argv[i][1] == 'f') { |
295 | if(argv[i + 1] != NULL) | 343 | if(argv[i + 1] != NULL) |
@@ -305,6 +353,7 @@ int main(int argc, char* argv[]) { | |||
305 | init_tox(); | 353 | init_tox(); |
306 | load_data(filename); | 354 | load_data(filename); |
307 | init_windows(); | 355 | init_windows(); |
356 | init_window_status(); | ||
308 | 357 | ||
309 | if(f_flag == -1) { | 358 | if(f_flag == -1) { |
310 | attron(COLOR_PAIR(3) | A_BOLD); | 359 | attron(COLOR_PAIR(3) | A_BOLD); |
@@ -312,8 +361,7 @@ int main(int argc, char* argv[]) { | |||
312 | "defaulting to 'data' for a keyfile...\n"); | 361 | "defaulting to 'data' for a keyfile...\n"); |
313 | attroff(COLOR_PAIR(3) | A_BOLD); | 362 | attroff(COLOR_PAIR(3) | A_BOLD); |
314 | } | 363 | } |
315 | 364 | ||
316 | |||
317 | while(true) { | 365 | while(true) { |
318 | // Update tox. | 366 | // Update tox. |
319 | do_tox(); | 367 | do_tox(); |
@@ -327,18 +375,14 @@ int main(int argc, char* argv[]) { | |||
327 | 375 | ||
328 | // Handle input. | 376 | // Handle input. |
329 | ch = getch(); | 377 | ch = getch(); |
330 | if(ch == '\t') { | 378 | if(ch == '\t' || ch == KEY_BTAB) |
331 | w_active = (w_active + 1) % w_num; | 379 | set_active_window(ch); |
332 | } | 380 | else if(ch != ERR) { |
333 | else if(ch == KEY_BTAB) { | 381 | a->onKey(a, ch); |
334 | w_active = (w_active + w_num - 1) % w_num; | ||
335 | } | 382 | } |
336 | else if(ch != ERR) { | 383 | else if(ch != ERR) { |
337 | a->onKey(a, ch); | 384 | a->onKey(a, ch); |
338 | } | 385 | } |
339 | |||
340 | } | 386 | } |
341 | |||
342 | return 0; | 387 | return 0; |
343 | } | 388 | } |
344 | |||
diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c index e5dc5086..20f6b480 100644 --- a/testing/toxic/prompt.c +++ b/testing/toxic/prompt.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Toxic -- Tox Curses Client | 2 | * Toxic -- Tox Curses Client |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <stdlib.h> | 5 | #include <stdlib.h> |
6 | #include <string.h> | 6 | #include <string.h> |
@@ -41,7 +41,17 @@ unsigned char * hex_string_to_bin(char hex_string[]) | |||
41 | static char prompt_buf[256] = {0}; | 41 | static char prompt_buf[256] = {0}; |
42 | static int prompt_buf_pos=0; | 42 | static int prompt_buf_pos=0; |
43 | 43 | ||
44 | static void execute(ToxWindow* self, char* cmd) { | 44 | static void execute(ToxWindow* self, char* u_cmd) { |
45 | int i; | ||
46 | int newlines = 0; | ||
47 | char cmd[256] = {0}; | ||
48 | for(i = 0; i < strlen(prompt_buf); i++) | ||
49 | { | ||
50 | if (u_cmd[i] == '\n') | ||
51 | ++newlines; | ||
52 | else | ||
53 | cmd[i - newlines] = u_cmd[i]; | ||
54 | } | ||
45 | 55 | ||
46 | if(!strcmp(cmd, "quit") || !strcmp(cmd, "exit") || !strcmp(cmd, "q")) { | 56 | if(!strcmp(cmd, "quit") || !strcmp(cmd, "exit") || !strcmp(cmd, "q")) { |
47 | endwin(); | 57 | endwin(); |
@@ -91,7 +101,7 @@ static void execute(ToxWindow* self, char* cmd) { | |||
91 | dht.ip.i = resolved_address; | 101 | dht.ip.i = resolved_address; |
92 | unsigned char *binary_string = hex_string_to_bin(key); | 102 | unsigned char *binary_string = hex_string_to_bin(key); |
93 | DHT_bootstrap(dht, binary_string); | 103 | DHT_bootstrap(dht, binary_string); |
94 | free(binary_string); | 104 | free(binary_string); |
95 | } | 105 | } |
96 | else if(!strncmp(cmd, "add ", strlen("add "))) { | 106 | else if(!strncmp(cmd, "add ", strlen("add "))) { |
97 | uint8_t id_bin[32]; | 107 | uint8_t id_bin[32]; |
@@ -137,7 +147,7 @@ static void execute(ToxWindow* self, char* cmd) { | |||
137 | 147 | ||
138 | num = m_addfriend(id_bin, (uint8_t*) msg, strlen(msg)+1); | 148 | num = m_addfriend(id_bin, (uint8_t*) msg, strlen(msg)+1); |
139 | switch (num) { | 149 | switch (num) { |
140 | case -1: | 150 | case -1: |
141 | wprintw(self->window, "Message is too long.\n"); | 151 | wprintw(self->window, "Message is too long.\n"); |
142 | break; | 152 | break; |
143 | case -2: | 153 | case -2: |
@@ -151,18 +161,19 @@ static void execute(ToxWindow* self, char* cmd) { | |||
151 | break; | 161 | break; |
152 | case -5: | 162 | case -5: |
153 | wprintw(self->window, "Undefined error when adding friend.\n"); | 163 | wprintw(self->window, "Undefined error when adding friend.\n"); |
154 | break; | 164 | break; |
155 | default: | 165 | default: |
156 | wprintw(self->window, "Friend added as %d.\n", num); | 166 | wprintw(self->window, "Friend added as %d.\n", num); |
157 | on_friendadded(num); | 167 | on_friendadded(num); |
158 | break; | 168 | break; |
159 | } | 169 | } |
160 | } | 170 | } |
161 | else if(!strcmp(cmd, "clear")) { | 171 | else if(!strcmp(cmd, "clear")) { |
162 | wclear(self->window); | 172 | wclear(self->window); |
163 | } | 173 | } |
164 | else if(!strcmp(cmd, "help")) { | 174 | else if(!strcmp(cmd, "help")) { |
165 | print_usage(self); | 175 | wclear(self->window); |
176 | print_usage(self); | ||
166 | } | 177 | } |
167 | else if(!strncmp(cmd, "status ", strlen("status "))) { | 178 | else if(!strncmp(cmd, "status ", strlen("status "))) { |
168 | char* msg; | 179 | char* msg; |
@@ -174,7 +185,7 @@ static void execute(ToxWindow* self, char* cmd) { | |||
174 | } | 185 | } |
175 | msg++; | 186 | msg++; |
176 | 187 | ||
177 | m_set_userstatus((uint8_t*) msg, strlen(msg)+1); | 188 | m_set_userstatus(USERSTATUS_KIND_RETAIN, (uint8_t*) msg, strlen(msg)+1); |
178 | wprintw(self->window, "Status set to: %s\n", msg); | 189 | wprintw(self->window, "Status set to: %s\n", msg); |
179 | } | 190 | } |
180 | else if(!strncmp(cmd, "nick ", strlen("nick "))) { | 191 | else if(!strncmp(cmd, "nick ", strlen("nick "))) { |
@@ -196,7 +207,7 @@ static void execute(ToxWindow* self, char* cmd) { | |||
196 | 207 | ||
197 | for(i=0; i<32; i++) { | 208 | for(i=0; i<32; i++) { |
198 | char xx[3]; | 209 | char xx[3]; |
199 | snprintf(xx, sizeof(xx), "%02x", self_public_key[i] & 0xff); | 210 | snprintf(xx, sizeof(xx), "%02x", self_public_key[i] & 0xff); |
200 | strcat(id, xx); | 211 | strcat(id, xx); |
201 | } | 212 | } |
202 | 213 | ||
@@ -256,7 +267,6 @@ static void execute(ToxWindow* self, char* cmd) { | |||
256 | wprintw(self->window, "Message successfully sent.\n"); | 267 | wprintw(self->window, "Message successfully sent.\n"); |
257 | } | 268 | } |
258 | } | 269 | } |
259 | |||
260 | else { | 270 | else { |
261 | wprintw(self->window, "Invalid command.\n"); | 271 | wprintw(self->window, "Invalid command.\n"); |
262 | } | 272 | } |
@@ -265,8 +275,16 @@ static void execute(ToxWindow* self, char* cmd) { | |||
265 | static void prompt_onKey(ToxWindow* self, int key) { | 275 | static void prompt_onKey(ToxWindow* self, int key) { |
266 | // PRINTABLE characters: Add to line. | 276 | // PRINTABLE characters: Add to line. |
267 | if(isprint(key)) { | 277 | if(isprint(key)) { |
268 | if(prompt_buf_pos == (sizeof(prompt_buf) - 1)) { | 278 | if (prompt_buf_pos == (sizeof(prompt_buf) - 1)){ |
269 | return; | 279 | wprintw(self->window, "\nToo Long.\n"); |
280 | prompt_buf_pos = 0; | ||
281 | prompt_buf[0] = 0; | ||
282 | } | ||
283 | else if(!(prompt_buf_pos == 0) && (prompt_buf_pos < COLS) && (prompt_buf_pos % (COLS - 3) == 0)) { | ||
284 | prompt_buf[prompt_buf_pos++] = '\n'; | ||
285 | } | ||
286 | else if(!(prompt_buf_pos == 0) && (prompt_buf_pos > COLS) && ((prompt_buf_pos - (COLS - 3)) % (COLS) == 0)) { | ||
287 | prompt_buf[prompt_buf_pos++] = '\n'; | ||
270 | } | 288 | } |
271 | prompt_buf[prompt_buf_pos++] = key; | 289 | prompt_buf[prompt_buf_pos++] = key; |
272 | prompt_buf[prompt_buf_pos] = 0; | 290 | prompt_buf[prompt_buf_pos] = 0; |
@@ -289,20 +307,22 @@ static void prompt_onKey(ToxWindow* self, int key) { | |||
289 | } | 307 | } |
290 | 308 | ||
291 | static void prompt_onDraw(ToxWindow* self) { | 309 | static void prompt_onDraw(ToxWindow* self) { |
292 | curs_set(1); | 310 | curs_set(1); |
293 | int x, y; | 311 | int x, y; |
294 | 312 | getyx(self->window, y, x); | |
295 | getyx(self->window, y, x); | 313 | (void) x; |
296 | (void) x; | 314 | int i; |
297 | 315 | for (i = 0; i < (strlen(prompt_buf)); i++) | |
298 | wattron(self->window, COLOR_PAIR(1)); | 316 | { |
299 | mvwprintw(self->window, y, 0, "# "); | 317 | if ((prompt_buf[i] == '\n') && (y != 0)) |
300 | wattroff(self->window, COLOR_PAIR(1)); | 318 | --y; |
301 | 319 | } | |
302 | mvwprintw(self->window, y, 2, "%s", prompt_buf); | 320 | wattron(self->window, COLOR_PAIR(1)); |
303 | wclrtoeol(self->window); | 321 | mvwprintw(self->window, y, 0, "# "); |
304 | 322 | wattroff(self->window, COLOR_PAIR(1)); | |
305 | wrefresh(self->window); | 323 | mvwprintw(self->window, y, 2, "%s", prompt_buf); |
324 | wclrtoeol(self->window); | ||
325 | wrefresh(self->window); | ||
306 | } | 326 | } |
307 | 327 | ||
308 | static void print_usage(ToxWindow* self) { | 328 | static void print_usage(ToxWindow* self) { |
@@ -310,15 +330,15 @@ static void print_usage(ToxWindow* self) { | |||
310 | wprintw(self->window, "Commands:\n"); | 330 | wprintw(self->window, "Commands:\n"); |
311 | wattroff(self->window, A_BOLD); | 331 | wattroff(self->window, A_BOLD); |
312 | 332 | ||
313 | wprintw(self->window, " connect <ip> <port> <key> : Connect to DHT server\n"); | 333 | wprintw(self->window, " connect <ip> <port> <key> : Connect to DHT server\n"); |
314 | wprintw(self->window, " add <id> <message> : Add friend\n"); | 334 | wprintw(self->window, " add <id> <message> : Add friend\n"); |
315 | wprintw(self->window, " status <message> : Set your status\n"); | 335 | wprintw(self->window, " status <message> : Set your status\n"); |
316 | wprintw(self->window, " nick <nickname> : Set your nickname\n"); | 336 | wprintw(self->window, " nick <nickname> : Set your nickname\n"); |
317 | wprintw(self->window, " accept <number> : Accept friend request\n"); | 337 | wprintw(self->window, " accept <number> : Accept friend request\n"); |
318 | wprintw(self->window, " myid : Print your ID\n"); | 338 | wprintw(self->window, " myid : Print your ID\n"); |
319 | wprintw(self->window, " quit/exit : Exit program\n"); | 339 | wprintw(self->window, " quit/exit : Exit program\n"); |
320 | wprintw(self->window, " help : Print this message again\n"); | 340 | wprintw(self->window, " help : Print this message again\n"); |
321 | wprintw(self->window, " clear : Clear this window\n"); | 341 | wprintw(self->window, " clear : Clear this window\n"); |
322 | 342 | ||
323 | wattron(self->window, A_BOLD); | 343 | wattron(self->window, A_BOLD); |
324 | wprintw(self->window, "TIP: Use the TAB key to navigate through the tabs.\n\n"); | 344 | wprintw(self->window, "TIP: Use the TAB key to navigate through the tabs.\n\n"); |
diff --git a/testing/toxic/windows.h b/testing/toxic/windows.h index dde1430f..cb45614d 100644 --- a/testing/toxic/windows.h +++ b/testing/toxic/windows.h | |||
@@ -3,6 +3,14 @@ | |||
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <stdbool.h> | 5 | #include <stdbool.h> |
6 | #define TOXWINDOWS_MAX_NUM 32 | ||
7 | #define MAX_FRIENDS_NUM 100 | ||
8 | |||
9 | /* number of permanent default windows */ | ||
10 | #define N_DEFAULT_WINS 2 | ||
11 | |||
12 | /* maximum window slots for WINDOW_STATUS array */ | ||
13 | #define MAX_WINDOW_SLOTS N_DEFAULT_WINS+MAX_FRIENDS_NUM | ||
6 | 14 | ||
7 | typedef struct ToxWindow_ ToxWindow; | 15 | typedef struct ToxWindow_ ToxWindow; |
8 | 16 | ||