summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/Messenger.c28
-rw-r--r--core/Messenger.h10
-rw-r--r--testing/toxic/chat.c66
-rw-r--r--testing/toxic/friendlist.c1
-rw-r--r--testing/toxic/main.c26
-rw-r--r--testing/toxic/windows.h1
6 files changed, 117 insertions, 15 deletions
diff --git a/core/Messenger.c b/core/Messenger.c
index 90dfe48d..af4fd797 100644
--- a/core/Messenger.c
+++ b/core/Messenger.c
@@ -247,6 +247,21 @@ uint32_t m_sendmessage_withid(int friendnumber, uint32_t theid, uint8_t *message
247 return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, temp, length + 1 + sizeof(theid)); 247 return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, temp, length + 1 + sizeof(theid));
248} 248}
249 249
250/* send an action to an online friend
251 return 1 if packet was successfully put into the send queue
252 return 0 if it was not */
253int m_sendaction(int friendnumber, uint8_t *action, uint32_t length)
254{
255 if (friendnumber < 0 || friendnumber >= numfriends)
256 return 0;
257 if (length >= MAX_DATA_SIZE || friendlist[friendnumber].status != FRIEND_ONLINE)
258 return 0;
259 uint8_t temp[MAX_DATA_SIZE];
260 temp[0] = PACKET_ID_ACTION;
261 memcpy(temp + 1, action, length);
262 return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, temp, length + 1);
263}
264
250/* send a name packet to friendnumber 265/* send a name packet to friendnumber
251 length is the length with the NULL terminator*/ 266 length is the length with the NULL terminator*/
252static int m_sendname(int friendnumber, uint8_t * name, uint16_t length) 267static int m_sendname(int friendnumber, uint8_t * name, uint16_t length)
@@ -447,6 +462,14 @@ void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t))
447 friend_message_isset = 1; 462 friend_message_isset = 1;
448} 463}
449 464
465static void (*friend_action)(int, uint8_t *, uint16_t);
466static uint8_t friend_action_isset = 0;
467void m_callback_action(void (*function)(int, uint8_t *, uint16_t))
468{
469 friend_action = function;
470 friend_action_isset = 1;
471}
472
450static void (*friend_namechange)(int, uint8_t *, uint16_t); 473static void (*friend_namechange)(int, uint8_t *, uint16_t);
451static uint8_t friend_namechange_isset = 0; 474static uint8_t friend_namechange_isset = 0;
452void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t)) 475void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t))
@@ -606,6 +629,11 @@ static void doFriends(void)
606 (*friend_message)(i, temp + 5, len - 5); 629 (*friend_message)(i, temp + 5, len - 5);
607 break; 630 break;
608 } 631 }
632 case PACKET_ID_ACTION: {
633 if (friend_action_isset)
634 (*friend_action)(i, temp + 1, len - 1);
635 break;
636 }
609 case PACKET_ID_RECEIPT: { 637 case PACKET_ID_RECEIPT: {
610 uint32_t msgid; 638 uint32_t msgid;
611 if (len < 1 + sizeof(msgid)) 639 if (len < 1 + sizeof(msgid))
diff --git a/core/Messenger.h b/core/Messenger.h
index 3044122b..55c86682 100644
--- a/core/Messenger.h
+++ b/core/Messenger.h
@@ -43,6 +43,7 @@ extern "C" {
43#define PACKET_ID_USERSTATUS 50 43#define PACKET_ID_USERSTATUS 50
44#define PACKET_ID_RECEIPT 65 44#define PACKET_ID_RECEIPT 65
45#define PACKET_ID_MESSAGE 64 45#define PACKET_ID_MESSAGE 64
46#define PACKET_ID_ACTION 63
46 47
47/* status definitions */ 48/* status definitions */
48#define FRIEND_ONLINE 4 49#define FRIEND_ONLINE 4
@@ -122,6 +123,11 @@ int m_friendstatus(int friendnumber);
122uint32_t m_sendmessage(int friendnumber, uint8_t *message, uint32_t length); 123uint32_t m_sendmessage(int friendnumber, uint8_t *message, uint32_t length);
123uint32_t m_sendmessage_withid(int friendnumber, uint32_t theid, uint8_t *message, uint32_t length); 124uint32_t m_sendmessage_withid(int friendnumber, uint32_t theid, uint8_t *message, uint32_t length);
124 125
126/* send an action to an online friend
127 returns 1 if packet was successfully put into the send queue
128 return 0 if it was not */
129int m_sendaction(int friendnumber, uint8_t *action, uint32_t length);
130
125/* Set our nickname 131/* Set our nickname
126 name must be a string of maximum MAX_NAME_LENGTH length. 132 name must be a string of maximum MAX_NAME_LENGTH length.
127 length must be at least 1 byte 133 length must be at least 1 byte
@@ -178,6 +184,10 @@ void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t));
178 function format is: function(int friendnumber, uint8_t * message, uint32_t length) */ 184 function format is: function(int friendnumber, uint8_t * message, uint32_t length) */
179void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t)); 185void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t));
180 186
187/* set the function that will be executed when an action from a friend is received.
188 function format is: function(int friendnumber, uint8_t * action, uint32_t length) */
189void m_callback_action(void (*function)(int, uint8_t *, uint16_t));
190
181/* set the callback for name changes 191/* set the callback for name changes
182 function(int friendnumber, uint8_t *newname, uint16_t length) 192 function(int friendnumber, uint8_t *newname, uint16_t length)
183 you are not responsible for freeing newname */ 193 you are not responsible for freeing newname */
diff --git a/testing/toxic/chat.c b/testing/toxic/chat.c
index 83765777..73cb1458 100644
--- a/testing/toxic/chat.c
+++ b/testing/toxic/chat.c
@@ -27,7 +27,7 @@ extern int active_window;
27extern void del_window(ToxWindow *w, int f_num); 27extern void del_window(ToxWindow *w, int f_num);
28extern void fix_name(uint8_t *name); 28extern void fix_name(uint8_t *name);
29void print_help(ChatContext *self); 29void print_help(ChatContext *self);
30void execute(ToxWindow *self, ChatContext *ctx, char *cmd); 30void execute(ToxWindow *self, ChatContext *ctx, char *cmd, struct tm *timeinfo);
31 31
32static void chat_onMessage(ToxWindow *self, int num, uint8_t *msg, uint16_t len) 32static void chat_onMessage(ToxWindow *self, int num, uint8_t *msg, uint16_t len)
33{ 33{
@@ -35,7 +35,7 @@ static void chat_onMessage(ToxWindow *self, int num, uint8_t *msg, uint16_t len)
35 uint8_t nick[MAX_NAME_LENGTH] = {0}; 35 uint8_t nick[MAX_NAME_LENGTH] = {0};
36 time_t now; 36 time_t now;
37 time(&now); 37 time(&now);
38 struct tm * timeinfo; 38 struct tm *timeinfo;
39 timeinfo = localtime(&now); 39 timeinfo = localtime(&now);
40 40
41 if (ctx->friendnum != num) 41 if (ctx->friendnum != num)
@@ -59,6 +59,32 @@ static void chat_onMessage(ToxWindow *self, int num, uint8_t *msg, uint16_t len)
59 beep(); 59 beep();
60} 60}
61 61
62static void chat_onAction(ToxWindow *self, int num, uint8_t *action, uint16_t len)
63{
64 ChatContext *ctx = (ChatContext*) self->x;
65 time_t now;
66 time(&now);
67 struct tm *timeinfo;
68 timeinfo = localtime(&now);
69
70 if (ctx->friendnum != num)
71 return;
72
73 action[len-1] = '\0';
74 fix_name(action);
75
76 wattron(ctx->history, COLOR_PAIR(2));
77 wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
78 wattroff(ctx->history, COLOR_PAIR(2));
79
80 wattron(ctx->history, COLOR_PAIR(4));
81 wprintw(ctx->history, "%s\n", action);
82 wattroff(ctx->history, COLOR_PAIR(4));
83
84 self->blink = true;
85 beep();
86}
87
62static void chat_onNickChange(ToxWindow *self, int num, uint8_t *nick, uint16_t len) 88static void chat_onNickChange(ToxWindow *self, int num, uint8_t *nick, uint16_t len)
63{ 89{
64 ChatContext *ctx = (ChatContext*) self->x; 90 ChatContext *ctx = (ChatContext*) self->x;
@@ -108,7 +134,7 @@ static void chat_onKey(ToxWindow *self, int key)
108 /* RETURN key: Execute command or print line */ 134 /* RETURN key: Execute command or print line */
109 else if (key == '\n') { 135 else if (key == '\n') {
110 if (ctx->line[0] == '/') 136 if (ctx->line[0] == '/')
111 execute(self, ctx, ctx->line); 137 execute(self, ctx, ctx->line, timeinfo);
112 else { 138 else {
113 if (!string_is_empty(ctx->line)) { 139 if (!string_is_empty(ctx->line)) {
114 /* make sure the string has at least non-space character */ 140 /* make sure the string has at least non-space character */
@@ -138,7 +164,7 @@ static void chat_onKey(ToxWindow *self, int key)
138 } 164 }
139} 165}
140 166
141void execute(ToxWindow *self, ChatContext *ctx, char *cmd) 167void execute(ToxWindow *self, ChatContext *ctx, char *cmd, struct tm *timeinfo)
142{ 168{
143 if (!strcmp(cmd, "/clear") || !strcmp(cmd, "/c")) { 169 if (!strcmp(cmd, "/clear") || !strcmp(cmd, "/c")) {
144 wclear(self->window); 170 wclear(self->window);
@@ -153,6 +179,33 @@ void execute(ToxWindow *self, ChatContext *ctx, char *cmd)
153 exit(0); 179 exit(0);
154 } 180 }
155 181
182 else if (!strncmp(cmd, "/me ", strlen("/me "))) {
183 char *action = strchr(cmd, ' ');
184 if (action == NULL) {
185 wprintw(self->window, "Invalid syntax.\n");
186 return;
187 }
188 action++;
189
190 wattron(ctx->history, COLOR_PAIR(2));
191 wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
192 wattroff(ctx->history, COLOR_PAIR(2));
193
194 uint8_t selfname[MAX_NAME_LENGTH];
195 int len = getself_name(selfname);
196 char msg[MAX_STR_SIZE-len-4];
197 snprintf(msg, sizeof(msg), "* %s %s\n", (uint8_t*) selfname, action);
198
199 wattron(ctx->history, COLOR_PAIR(1));
200 wprintw(ctx->history, msg);
201 wattroff(ctx->history, COLOR_PAIR(1));
202 if (m_sendaction(ctx->friendnum, (uint8_t*) msg, strlen(msg)+1) < 0) {
203 wattron(ctx->history, COLOR_PAIR(3));
204 wprintw(ctx->history, " * Failed to send action\n");
205 wattroff(ctx->history, COLOR_PAIR(3));
206 }
207 }
208
156 else if (!strncmp(cmd, "/status ", strlen("/status "))) { 209 else if (!strncmp(cmd, "/status ", strlen("/status "))) {
157 char *status = strchr(cmd, ' '); 210 char *status = strchr(cmd, ' ');
158 char *msg; 211 char *msg;
@@ -178,8 +231,7 @@ void execute(ToxWindow *self, ChatContext *ctx, char *cmd)
178 status_text = "BUSY"; 231 status_text = "BUSY";
179 } 232 }
180 233
181 else 234 else {
182 {
183 wprintw(ctx->history, "Invalid status.\n"); 235 wprintw(ctx->history, "Invalid status.\n");
184 return; 236 return;
185 } 237 }
@@ -265,6 +317,7 @@ void print_help(ChatContext *self)
265 317
266 wprintw(self->history, " /status <type> <message> : Set your status\n"); 318 wprintw(self->history, " /status <type> <message> : Set your status\n");
267 wprintw(self->history, " /nick <nickname> : Set your nickname\n"); 319 wprintw(self->history, " /nick <nickname> : Set your nickname\n");
320 wprintw(self->history, " /me <action> : Do an action\n");
268 wprintw(self->history, " /myid : Print your ID\n"); 321 wprintw(self->history, " /myid : Print your ID\n");
269 wprintw(self->history, " /clear : Clear the screen\n"); 322 wprintw(self->history, " /clear : Clear the screen\n");
270 wprintw(self->history, " /close : Close the current chat window\n"); 323 wprintw(self->history, " /close : Close the current chat window\n");
@@ -285,6 +338,7 @@ ToxWindow new_chat(int friendnum)
285 ret.onMessage = &chat_onMessage; 338 ret.onMessage = &chat_onMessage;
286 ret.onNickChange = &chat_onNickChange; 339 ret.onNickChange = &chat_onNickChange;
287 ret.onStatusChange = &chat_onStatusChange; 340 ret.onStatusChange = &chat_onStatusChange;
341 ret.onAction = &chat_onAction;
288 342
289 uint8_t nick[MAX_NAME_LENGTH] = {0}; 343 uint8_t nick[MAX_NAME_LENGTH] = {0};
290 getname(friendnum, (uint8_t*) &nick); 344 getname(friendnum, (uint8_t*) &nick);
diff --git a/testing/toxic/friendlist.c b/testing/toxic/friendlist.c
index 159217b1..f2aa1cf4 100644
--- a/testing/toxic/friendlist.c
+++ b/testing/toxic/friendlist.c
@@ -177,6 +177,7 @@ ToxWindow new_friendlist() {
177 ret.onDraw = &friendlist_onDraw; 177 ret.onDraw = &friendlist_onDraw;
178 ret.onInit = &friendlist_onInit; 178 ret.onInit = &friendlist_onInit;
179 ret.onMessage = &friendlist_onMessage; 179 ret.onMessage = &friendlist_onMessage;
180 ret.onAction = &friendlist_onMessage; // Action has identical behaviour to message
180 ret.onNickChange = &friendlist_onNickChange; 181 ret.onNickChange = &friendlist_onNickChange;
181 ret.onStatusChange = &friendlist_onStatusChange; 182 ret.onStatusChange = &friendlist_onStatusChange;
182 183
diff --git a/testing/toxic/main.c b/testing/toxic/main.c
index 162cce68..2922456e 100644
--- a/testing/toxic/main.c
+++ b/testing/toxic/main.c
@@ -53,8 +53,9 @@ void on_request(uint8_t *public_key, uint8_t *data, uint16_t length)
53 wprintw(prompt->window, "%02x", public_key[i] & 0xff); 53 wprintw(prompt->window, "%02x", public_key[i] & 0xff);
54 } 54 }
55 55
56 wprintw(prompt->window, "\n"); 56 wprintw(prompt->window, "\nWith the message: %s\n", data);
57 wprintw(prompt->window, "Use \"accept %d\" to accept it.\n", n); 57 wprintw(prompt->window, "\nUse \"accept %d\" to accept it.\n", n);
58
58 for (i = 0; i < MAX_WINDOW_SLOTS; ++i) { 59 for (i = 0; i < MAX_WINDOW_SLOTS; ++i) {
59 if (windows[i].onFriendRequest != NULL) 60 if (windows[i].onFriendRequest != NULL)
60 windows[i].onFriendRequest(&windows[i], public_key, data, length); 61 windows[i].onFriendRequest(&windows[i], public_key, data, length);
@@ -63,7 +64,6 @@ void on_request(uint8_t *public_key, uint8_t *data, uint16_t length)
63 64
64void on_message(int friendnumber, uint8_t *string, uint16_t length) 65void on_message(int friendnumber, uint8_t *string, uint16_t length)
65{ 66{
66 wprintw(prompt->window, "\n(message) %d: %s\n", friendnumber, string);
67 int i; 67 int i;
68 for (i = 0; i < MAX_WINDOW_SLOTS; ++i) { 68 for (i = 0; i < MAX_WINDOW_SLOTS; ++i) {
69 if (windows[i].onMessage != NULL) 69 if (windows[i].onMessage != NULL)
@@ -71,6 +71,15 @@ void on_message(int friendnumber, uint8_t *string, uint16_t length)
71 } 71 }
72} 72}
73 73
74void on_action(int friendnumber, uint8_t *string, uint16_t length)
75{
76 int i;
77 for (i = 0; i < MAX_WINDOW_SLOTS; ++i) {
78 if (windows[i].onAction != NULL)
79 windows[i].onAction(&windows[i], friendnumber, string, length);
80 }
81}
82
74void on_nickchange(int friendnumber, uint8_t *string, uint16_t length) 83void on_nickchange(int friendnumber, uint8_t *string, uint16_t length)
75{ 84{
76 wprintw(prompt->window, "\n(nickchange) %d: %s!\n", friendnumber, string); 85 wprintw(prompt->window, "\n(nickchange) %d: %s!\n", friendnumber, string);
@@ -126,6 +135,7 @@ static void init_tox()
126 m_callback_friendmessage(on_message); 135 m_callback_friendmessage(on_message);
127 m_callback_namechange(on_nickchange); 136 m_callback_namechange(on_nickchange);
128 m_callback_statusmessage(on_statuschange); 137 m_callback_statusmessage(on_statuschange);
138 m_callback_action(on_action);
129} 139}
130 140
131void init_window_status() 141void init_window_status()
@@ -281,13 +291,13 @@ static void draw_bar()
281 attron(A_BOLD); 291 attron(A_BOLD);
282 292
283 odd = (odd+1) % blinkrate; 293 odd = (odd+1) % blinkrate;
284 if (windows[i].blink && (odd < (blinkrate/2))) { 294 if (windows[i].blink && (odd < (blinkrate/2)))
285 attron(COLOR_PAIR(3)); 295 attron(COLOR_PAIR(3));
286 } 296
287 printw(" %s", windows[i].title); 297 printw(" %s", windows[i].title);
288 if (windows[i].blink && (odd < (blinkrate/2))) { 298 if (windows[i].blink && (odd < (blinkrate/2)))
289 attroff(COLOR_PAIR(3)); 299 attroff(COLOR_PAIR(3));
290 } 300
291 if (i == active_window) { 301 if (i == active_window) {
292 attroff(A_BOLD); 302 attroff(A_BOLD);
293 } 303 }
@@ -317,7 +327,6 @@ void set_active_window(int ch)
317 i = (i + 1) % max; 327 i = (i + 1) % max;
318 if (f_inf++ > max) { // infinite loop check 328 if (f_inf++ > max) { // infinite loop check
319 endwin(); 329 endwin();
320 clear();
321 exit(2); 330 exit(2);
322 } 331 }
323 } 332 }
@@ -332,7 +341,6 @@ void set_active_window(int ch)
332 if (--i < 0) i = max; 341 if (--i < 0) i = max;
333 if (f_inf++ > max) { 342 if (f_inf++ > max) {
334 endwin(); 343 endwin();
335 clear();
336 exit(2); 344 exit(2);
337 } 345 }
338 } 346 }
diff --git a/testing/toxic/windows.h b/testing/toxic/windows.h
index 287e534a..c6925ce1 100644
--- a/testing/toxic/windows.h
+++ b/testing/toxic/windows.h
@@ -24,6 +24,7 @@ struct ToxWindow_ {
24 void(*onMessage)(ToxWindow*, int, uint8_t*, uint16_t); 24 void(*onMessage)(ToxWindow*, int, uint8_t*, uint16_t);
25 void(*onNickChange)(ToxWindow*, int, uint8_t*, uint16_t); 25 void(*onNickChange)(ToxWindow*, int, uint8_t*, uint16_t);
26 void(*onStatusChange)(ToxWindow*, int, uint8_t*, uint16_t); 26 void(*onStatusChange)(ToxWindow*, int, uint8_t*, uint16_t);
27 void(*onAction)(ToxWindow*, int, uint8_t*, uint16_t);
27 char title[256]; 28 char title[256];
28 29
29 void* x; 30 void* x;