summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--toxcore/Messenger.c60
-rw-r--r--toxcore/Messenger.h26
-rw-r--r--toxcore/tox.c34
-rw-r--r--toxcore/tox.h20
4 files changed, 140 insertions, 0 deletions
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index 692d3d0e..ee5213a7 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -268,6 +268,7 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
268 m->friendlist[i].statusmessage = calloc(1, 1); 268 m->friendlist[i].statusmessage = calloc(1, 1);
269 m->friendlist[i].statusmessage_length = 1; 269 m->friendlist[i].statusmessage_length = 1;
270 m->friendlist[i].userstatus = USERSTATUS_NONE; 270 m->friendlist[i].userstatus = USERSTATUS_NONE;
271 m->friendlist[i].is_typing = 0;
271 memcpy(m->friendlist[i].info, data, length); 272 memcpy(m->friendlist[i].info, data, length);
272 m->friendlist[i].info_size = length; 273 m->friendlist[i].info_size = length;
273 m->friendlist[i].message_id = 0; 274 m->friendlist[i].message_id = 0;
@@ -315,6 +316,7 @@ int m_addfriend_norequest(Messenger *m, uint8_t *client_id)
315 m->friendlist[i].statusmessage = calloc(1, 1); 316 m->friendlist[i].statusmessage = calloc(1, 1);
316 m->friendlist[i].statusmessage_length = 1; 317 m->friendlist[i].statusmessage_length = 1;
317 m->friendlist[i].userstatus = USERSTATUS_NONE; 318 m->friendlist[i].userstatus = USERSTATUS_NONE;
319 m->friendlist[i].is_typing = 0;
318 m->friendlist[i].message_id = 0; 320 m->friendlist[i].message_id = 0;
319 m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */ 321 m->friendlist[i].receives_read_receipts = 1; /* Default: YES. */
320 322
@@ -615,6 +617,29 @@ USERSTATUS m_get_self_userstatus(Messenger *m)
615 return m->userstatus; 617 return m->userstatus;
616} 618}
617 619
620int m_set_usertyping(Messenger *m, int friendnumber, uint8_t is_typing)
621{
622 if (is_typing != 0 || is_typing != 1) {
623 return -1;
624 }
625
626 if (friend_not_valid(m, friendnumber))
627 return -1;
628
629 m->friendlist[friendnumber].user_istyping = is_typing;
630 m->friendlist[friendnumber].user_istyping_sent = 0;
631
632 return 0;
633}
634
635uint8_t m_get_istyping(Messenger *m, int friendnumber)
636{
637 if (friend_not_valid(m, friendnumber))
638 return -1;
639
640 return m->friendlist[friendnumber].is_typing;
641}
642
618static int send_statusmessage(Messenger *m, int friendnumber, uint8_t *status, uint16_t length) 643static int send_statusmessage(Messenger *m, int friendnumber, uint8_t *status, uint16_t length)
619{ 644{
620 return write_cryptpacket_id(m, friendnumber, PACKET_ID_STATUSMESSAGE, status, length); 645 return write_cryptpacket_id(m, friendnumber, PACKET_ID_STATUSMESSAGE, status, length);
@@ -626,6 +651,12 @@ static int send_userstatus(Messenger *m, int friendnumber, USERSTATUS status)
626 return write_cryptpacket_id(m, friendnumber, PACKET_ID_USERSTATUS, &stat, sizeof(stat)); 651 return write_cryptpacket_id(m, friendnumber, PACKET_ID_USERSTATUS, &stat, sizeof(stat));
627} 652}
628 653
654static int send_user_istyping(Messenger *m, int friendnumber, uint8_t is_typing)
655{
656 uint8_t typing = is_typing;
657 return write_cryptpacket_id(m, friendnumber, PACKET_ID_TYPING, &typing, sizeof(typing));
658}
659
629static int send_ping(Messenger *m, int friendnumber) 660static int send_ping(Messenger *m, int friendnumber)
630{ 661{
631 int ret = write_cryptpacket_id(m, friendnumber, PACKET_ID_PING, 0, 0); 662 int ret = write_cryptpacket_id(m, friendnumber, PACKET_ID_PING, 0, 0);
@@ -654,6 +685,11 @@ static void set_friend_userstatus(Messenger *m, int friendnumber, USERSTATUS sta
654 m->friendlist[friendnumber].userstatus = status; 685 m->friendlist[friendnumber].userstatus = status;
655} 686}
656 687
688static void set_friend_typing(Messenger *m, int friendnumber, uint8_t is_typing)
689{
690 m->friendlist[friendnumber].is_typing = is_typing;
691}
692
657/* Sets whether we send read receipts for friendnumber. */ 693/* Sets whether we send read receipts for friendnumber. */
658void m_set_sends_receipts(Messenger *m, int friendnumber, int yesno) 694void m_set_sends_receipts(Messenger *m, int friendnumber, int yesno)
659{ 695{
@@ -707,6 +743,12 @@ void m_callback_userstatus(Messenger *m, void (*function)(Messenger *m, int, USE
707 m->friend_userstatuschange_userdata = userdata; 743 m->friend_userstatuschange_userdata = userdata;
708} 744}
709 745
746void m_callback_typingchange(Messenger *m, void(*function)(Messenger *m, int, uint8_t, void *), void *userdata)
747{
748 m->friend_typingchange = function;
749 m->friend_typingchange_userdata = userdata;
750}
751
710void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, int, uint32_t, void *), void *userdata) 752void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, int, uint32_t, void *), void *userdata)
711{ 753{
712 m->read_receipt = function; 754 m->read_receipt = function;
@@ -1821,6 +1863,11 @@ void do_friends(Messenger *m)
1821 if (send_userstatus(m, i, m->userstatus)) 1863 if (send_userstatus(m, i, m->userstatus))
1822 m->friendlist[i].userstatus_sent = 1; 1864 m->friendlist[i].userstatus_sent = 1;
1823 } 1865 }
1866
1867 if (m->friendlist[i].user_istyping_sent == 0) {
1868 if (send_user_istyping(m, i, m->friendlist[i].user_istyping))
1869 m->friendlist[i].user_istyping_sent = 1;
1870 }
1824 1871
1825 if (m->friendlist[i].ping_lastsent + FRIEND_PING_INTERVAL < temp_time) { 1872 if (m->friendlist[i].ping_lastsent + FRIEND_PING_INTERVAL < temp_time) {
1826 send_ping(m, i); 1873 send_ping(m, i);
@@ -1882,6 +1929,19 @@ void do_friends(Messenger *m)
1882 set_friend_userstatus(m, i, status); 1929 set_friend_userstatus(m, i, status);
1883 break; 1930 break;
1884 } 1931 }
1932
1933 case PACKET_ID_TYPING: {
1934 if (data_length != 1)
1935 break;
1936
1937 uint8_t typing = data[0];
1938
1939 if (m->friend_typingchange)
1940 m->friend_typingchange(m, i, typing, m->friend_typingchange_userdata);
1941
1942 set_friend_typing(m, i, typing);
1943 break;
1944 }
1885 1945
1886 case PACKET_ID_MESSAGE: { 1946 case PACKET_ID_MESSAGE: {
1887 uint8_t *message_id = data; 1947 uint8_t *message_id = data;
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h
index ccca8fba..952aa436 100644
--- a/toxcore/Messenger.h
+++ b/toxcore/Messenger.h
@@ -42,6 +42,7 @@
42#define PACKET_ID_NICKNAME 48 42#define PACKET_ID_NICKNAME 48
43#define PACKET_ID_STATUSMESSAGE 49 43#define PACKET_ID_STATUSMESSAGE 49
44#define PACKET_ID_USERSTATUS 50 44#define PACKET_ID_USERSTATUS 50
45#define PACKET_ID_TYPING 51
45#define PACKET_ID_RECEIPT 65 46#define PACKET_ID_RECEIPT 65
46#define PACKET_ID_MESSAGE 64 47#define PACKET_ID_MESSAGE 64
47#define PACKET_ID_ACTION 63 48#define PACKET_ID_ACTION 63
@@ -145,6 +146,9 @@ typedef struct {
145 uint8_t statusmessage_sent; 146 uint8_t statusmessage_sent;
146 USERSTATUS userstatus; 147 USERSTATUS userstatus;
147 uint8_t userstatus_sent; 148 uint8_t userstatus_sent;
149 uint8_t user_istyping;
150 uint8_t user_istyping_sent;
151 uint8_t is_typing;
148 uint16_t info_size; // Length of the info. 152 uint16_t info_size; // Length of the info.
149 uint32_t message_id; // a semi-unique id used in read receipts. 153 uint32_t message_id; // a semi-unique id used in read receipts.
150 uint8_t receives_read_receipts; // shall we send read receipts to this person? 154 uint8_t receives_read_receipts; // shall we send read receipts to this person?
@@ -204,6 +208,8 @@ typedef struct Messenger {
204 void *friend_statusmessagechange_userdata; 208 void *friend_statusmessagechange_userdata;
205 void (*friend_userstatuschange)(struct Messenger *m, int, USERSTATUS, void *); 209 void (*friend_userstatuschange)(struct Messenger *m, int, USERSTATUS, void *);
206 void *friend_userstatuschange_userdata; 210 void *friend_userstatuschange_userdata;
211 void (*friend_typingchange)(struct Messenger *m, int, uint8_t, void *);
212 void *friend_typingchange_userdata;
207 void (*read_receipt)(struct Messenger *m, int, uint32_t, void *); 213 void (*read_receipt)(struct Messenger *m, int, uint32_t, void *);
208 void *read_receipt_userdata; 214 void *read_receipt_userdata;
209 void (*friend_statuschange)(struct Messenger *m, int, uint8_t, void *); 215 void (*friend_statuschange)(struct Messenger *m, int, uint8_t, void *);
@@ -398,6 +404,21 @@ int m_copy_self_statusmessage(Messenger *m, uint8_t *buf, uint32_t maxlen);
398USERSTATUS m_get_userstatus(Messenger *m, int friendnumber); 404USERSTATUS m_get_userstatus(Messenger *m, int friendnumber);
399USERSTATUS m_get_self_userstatus(Messenger *m); 405USERSTATUS m_get_self_userstatus(Messenger *m);
400 406
407/* Set our typing status for a friend.
408 * You are responsible for turning it on or off.
409 *
410 * returns 0 on success.
411 * returns -1 on failure.
412 */
413int m_set_usertyping(Messenger *m, int friendnumber, uint8_t is_typing);
414
415/* Get the typing status of a friend.
416 *
417 * returns 0 if friend is not typing.
418 * returns -1 if friend is typing.
419 */
420uint8_t m_get_istyping(Messenger *m, int friendnumber);
421
401/* Sets whether we send read receipts for friendnumber. 422/* Sets whether we send read receipts for friendnumber.
402 * This function is not lazy, and it will fail if yesno is not (0 or 1). 423 * This function is not lazy, and it will fail if yesno is not (0 or 1).
403 */ 424 */
@@ -439,6 +460,11 @@ void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, int,
439 */ 460 */
440void m_callback_userstatus(Messenger *m, void (*function)(Messenger *m, int, USERSTATUS, void *), void *userdata); 461void m_callback_userstatus(Messenger *m, void (*function)(Messenger *m, int, USERSTATUS, void *), void *userdata);
441 462
463/* Set the callback for typing changes.
464 * Function(int friendnumber, uint8_t is_typing)
465 */
466void m_callback_typingchange(Messenger *m, void(*function)(Messenger *m, int, uint8_t, void *), void *userdata);
467
442/* Set the callback for read receipts. 468/* Set the callback for read receipts.
443 * Function(int friendnumber, uint32_t receipt) 469 * Function(int friendnumber, uint32_t receipt)
444 * 470 *
diff --git a/toxcore/tox.c b/toxcore/tox.c
index f4690080..3f2c1e92 100644
--- a/toxcore/tox.c
+++ b/toxcore/tox.c
@@ -270,6 +270,29 @@ TOX_USERSTATUS tox_get_self_user_status(Tox *tox)
270 return (TOX_USERSTATUS)m_get_self_userstatus(m); 270 return (TOX_USERSTATUS)m_get_self_userstatus(m);
271} 271}
272 272
273/* Set our typing status for a friend.
274 * You are responsible for turning it on or off.
275 *
276 * returns 0 on success.
277 * returns -1 on failure.
278 */
279int tox_set_user_is_typing(Tox *tox, int friendnumber, uint8_t is_typing)
280{
281 Messenger *m = tox;
282 return (int)m_set_usertyping(m, friendnumber, is_typing);
283}
284
285/* Get the typing status of a friend.
286 *
287 * returns 0 if friend is not typing.
288 * returns -1 if friend is typing.
289 */
290int tox_get_is_typing(Tox *tox, int friendnumber)
291{
292 Messenger *m = tox;
293 return (int)m_get_istyping(m, friendnumber);
294}
295
273 296
274/* Sets whether we send read receipts for friendnumber. 297/* Sets whether we send read receipts for friendnumber.
275 * This function is not lazy, and it will fail if yesno is not (0 or 1). 298 * This function is not lazy, and it will fail if yesno is not (0 or 1).
@@ -370,6 +393,17 @@ void tox_callback_user_status(Tox *tox, void (*_function)(Tox *tox, int, TOX_USE
370 m_callback_userstatus(m, function, userdata); 393 m_callback_userstatus(m, function, userdata);
371} 394}
372 395
396/* Set the callback for typing changes.
397 * function (int friendnumber, uint8_t is_typing)
398 */
399void tox_callback_typing_change(Tox *tox, void (*function)(Tox *tox, int, uint8_t, void *), void *userdata)
400{
401 Messenger *m = tox;
402 typedef void (*function_type)(Messenger *, int, uint8_t, void *);
403 function_type function_new = (function_type)function;
404 m_callback_typingchange(m, function_new, userdata);
405}
406
373/* Set the callback for read receipts. 407/* Set the callback for read receipts.
374 * function(int friendnumber, uint32_t receipt) 408 * function(int friendnumber, uint32_t receipt)
375 * 409 *
diff --git a/toxcore/tox.h b/toxcore/tox.h
index 447a1146..0a4e80f7 100644
--- a/toxcore/tox.h
+++ b/toxcore/tox.h
@@ -280,6 +280,21 @@ int tox_get_self_status_message(Tox *tox, uint8_t *buf, uint32_t maxlen);
280 */ 280 */
281TOX_USERSTATUS tox_get_user_status(Tox *tox, int friendnumber); 281TOX_USERSTATUS tox_get_user_status(Tox *tox, int friendnumber);
282TOX_USERSTATUS tox_get_self_user_status(Tox *tox); 282TOX_USERSTATUS tox_get_self_user_status(Tox *tox);
283
284/* Set our typing status for a friend.
285 * You are responsible for turning it on or off.
286 *
287 * returns 0 on success.
288 * returns -1 on failure.
289 */
290int tox_set_user_is_typing(Tox *tox, int friendnumber, uint8_t is_typing);
291
292/* Get the typing status of a friend.
293 *
294 * returns 0 if friend is not typing.
295 * returns -1 if friend is typing.
296 */
297int tox_get_is_typing(Tox *tox, int friendnumber);
283 298
284/* Sets whether we send read receipts for friendnumber. 299/* Sets whether we send read receipts for friendnumber.
285 * This function is not lazy, and it will fail if yesno is not (0 or 1). 300 * This function is not lazy, and it will fail if yesno is not (0 or 1).
@@ -335,6 +350,11 @@ void tox_callback_status_message(Tox *tox, void (*function)(Tox *tox, int, uint8
335 * function(int friendnumber, USERSTATUS kind) 350 * function(int friendnumber, USERSTATUS kind)
336 */ 351 */
337void tox_callback_user_status(Tox *tox, void (*function)(Tox *tox, int, TOX_USERSTATUS, void *), void *userdata); 352void tox_callback_user_status(Tox *tox, void (*function)(Tox *tox, int, TOX_USERSTATUS, void *), void *userdata);
353
354/* Set the callback for typing changes.
355 * function (int friendnumber, uint8_t is_typing)
356 */
357void tox_callback_typing_change(Tox *tox, void (*function)(Tox *tox, int, uint8_t, void *), void *userdata);
338 358
339/* Set the callback for read receipts. 359/* Set the callback for read receipts.
340 * function(int friendnumber, uint32_t receipt) 360 * function(int friendnumber, uint32_t receipt)