summaryrefslogtreecommitdiff
path: root/testing
diff options
context:
space:
mode:
Diffstat (limited to 'testing')
-rw-r--r--testing/toxic/chat.c16
-rw-r--r--testing/toxic/friendlist.c60
-rw-r--r--testing/toxic/main.c162
-rw-r--r--testing/toxic/prompt.c1
-rw-r--r--testing/toxic/windows.h8
5 files changed, 167 insertions, 80 deletions
diff --git a/testing/toxic/chat.c b/testing/toxic/chat.c
index da1f9f4a..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
28extern int w_active;
29extern void del_window(ToxWindow *w, int f_num);
28extern void fix_name(uint8_t* name); 30extern void fix_name(uint8_t* name);
29void print_help(ChatContext* self); 31void print_help(ChatContext* self);
30void execute(ToxWindow* self, ChatContext* ctx, char* cmd); 32void execute(ToxWindow* self, ChatContext* ctx, char* cmd);
@@ -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);
@@ -118,7 +120,7 @@ static void chat_onKey(ToxWindow* self, int key) {
118 if(!string_is_empty(ctx->line)) { 120 if(!string_is_empty(ctx->line)) {
119 /* make sure the string has at least non-space character */ 121 /* make sure the string has at least non-space character */
120 wattron(ctx->history, COLOR_PAIR(2)); 122 wattron(ctx->history, COLOR_PAIR(2));
121 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);
122 wattroff(ctx->history, COLOR_PAIR(2)); 124 wattroff(ctx->history, COLOR_PAIR(2));
123 wattron(ctx->history, COLOR_PAIR(1)); 125 wattron(ctx->history, COLOR_PAIR(1));
124 wprintw(ctx->history, "you: ", ctx->line); 126 wprintw(ctx->history, "you: ", ctx->line);
@@ -187,6 +189,12 @@ void execute(ToxWindow* self, ChatContext* ctx, char* cmd)
187 } 189 }
188 wprintw(ctx->history, "Your ID: %s\n", id); 190 wprintw(ctx->history, "Your ID: %s\n", id);
189 } 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 }
190 else 198 else
191 wprintw(ctx->history, "Invalid command.\n"); 199 wprintw(ctx->history, "Invalid command.\n");
192} 200}
@@ -219,17 +227,19 @@ static void chat_onInit(ToxWindow* self) {
219 scrollok(ctx->history, 1); 227 scrollok(ctx->history, 1);
220 228
221 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);
222} 231}
223 232
224void print_help(ChatContext* self) { 233void print_help(ChatContext* self) {
225 wattron(self->history, COLOR_PAIR(2) | A_BOLD); 234 wattron(self->history, COLOR_PAIR(2) | A_BOLD);
226 wprintw(self->history, "\nCommands:\n"); 235 wprintw(self->history, "Commands:\n");
227 wattroff(self->history, A_BOLD); 236 wattroff(self->history, A_BOLD);
228 237
229 wprintw(self->history, " /status <message> : Set your status\n"); 238 wprintw(self->history, " /status <message> : Set your status\n");
230 wprintw(self->history, " /nick <nickname> : Set your nickname\n"); 239 wprintw(self->history, " /nick <nickname> : Set your nickname\n");
231 wprintw(self->history, " /myid : Print your ID\n"); 240 wprintw(self->history, " /myid : Print your ID\n");
232 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");
233 wprintw(self->history, " /quit or /exit : Exit program\n"); 243 wprintw(self->history, " /quit or /exit : Exit program\n");
234 wprintw(self->history, " /help : Print this message again\n\n"); 244 wprintw(self->history, " /help : Print this message again\n\n");
235 245
diff --git a/testing/toxic/friendlist.c b/testing/toxic/friendlist.c
index 05651b0e..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
15extern int add_window(ToxWindow w); 15extern char WINDOW_STATUS[TOXWINDOWS_MAX_NUM];
16extern int focus_window(int num); 16extern int add_window(ToxWindow w, int n);
17extern ToxWindow new_chat(int friendnum); 17extern ToxWindow new_chat(int friendnum);
18 18extern int w_active;
19#define MAX_FRIENDS_NUM 100
20 19
21typedef struct { 20typedef 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
95static void friendlist_onKey(ToxWindow* self, int key) { 102static 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
@@ -145,6 +167,10 @@ static void friendlist_onDraw(ToxWindow* self) {
145 wrefresh(self->window); 167 wrefresh(self->window);
146} 168}
147 169
170void disable_chatwin(int f_num) {
171 friends[f_num].chatwin = -1;
172}
173
148static void friendlist_onInit(ToxWindow* self) { 174static void friendlist_onInit(ToxWindow* self) {
149 175
150} 176}
diff --git a/testing/toxic/main.c b/testing/toxic/main.c
index ee5e9f2a..19a0b959 100644
--- a/testing/toxic/main.c
+++ b/testing/toxic/main.c
@@ -17,14 +17,13 @@ extern ToxWindow new_prompt();
17extern ToxWindow new_friendlist(); 17extern ToxWindow new_friendlist();
18 18
19extern int friendlist_onFriendAdded(int num); 19extern int friendlist_onFriendAdded(int num);
20 20extern void disable_chatwin(int f_num);
21extern int add_req(uint8_t* public_key); // XXX 21extern int add_req(uint8_t* public_key); // XXX
22 22
23#define TOXWINDOWS_MAX_NUM 32 23char WINDOW_STATUS[MAX_WINDOW_SLOTS]; // Holds status of chat windows
24 24static ToxWindow windows[MAX_WINDOW_SLOTS];
25static ToxWindow windows[TOXWINDOWS_MAX_NUM]; 25int w_num;
26static int w_num; 26int w_active;
27static int w_active;
28static ToxWindow* prompt; 27static 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,7 +62,7 @@ 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 }
@@ -74,7 +73,7 @@ void on_statuschange(int friendnumber, USERSTATUS_KIND kind, uint8_t* string, ui
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
118int add_window(ToxWindow w) { 117void 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
128int 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
136int focus_window(int num) { 145/* Deletes window w and cleans up */
137 if(num >= w_num || num < 0) 146void 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
144static void init_windows() { 160static 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
158static void do_tox() { 173static void do_tox() {
@@ -238,7 +253,6 @@ static void load_data(char *path) {
238 253
239static void draw_bar() { 254static 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 */
296void 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
283int main(int argc, char* argv[]) { 331int main(int argc, char* argv[]) {
284 int ch; 332 int ch;
285 int i = 0; 333 int i = 0;
@@ -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 a53c163f..20f6b480 100644
--- a/testing/toxic/prompt.c
+++ b/testing/toxic/prompt.c
@@ -267,7 +267,6 @@ static void execute(ToxWindow* self, char* u_cmd) {
267 wprintw(self->window, "Message successfully sent.\n"); 267 wprintw(self->window, "Message successfully sent.\n");
268 } 268 }
269 } 269 }
270
271 else { 270 else {
272 wprintw(self->window, "Invalid command.\n"); 271 wprintw(self->window, "Invalid command.\n");
273 } 272 }
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
7typedef struct ToxWindow_ ToxWindow; 15typedef struct ToxWindow_ ToxWindow;
8 16