1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-07-03 16:57:46 +02:00

Messenger refactor - redid work from pull request 79

Moves static state out of Messenger.c and into a Messenger struct
Purely stylistic, no functional changes were made.

This commit also changed all the callers of Messenger as they now have
to pass an instance of the Messenger struct to messenger functions.

Also removed some uses of the 'static' keyword at the beginning of
function definitions when the function was already declared static, as
these caused gcc to whine.
This commit is contained in:
Chris Hall 2013-08-11 15:24:11 +12:00
parent 652f7aec26
commit 8687a54a87
5 changed files with 95 additions and 92 deletions

36
chat.c
View File

@ -29,9 +29,9 @@ extern int active_window;
extern void del_window(ToxWindow *w, int f_num);
extern void fix_name(uint8_t *name);
void print_help(ChatContext *self);
void execute(ToxWindow *self, ChatContext *ctx, char *cmd, struct tm *timeinfo);
void execute(ToxWindow *self, ChatContext *ctx, Messenger *m, char *cmd, struct tm *timeinfo);
static void chat_onMessage(ToxWindow *self, int num, uint8_t *msg, uint16_t len)
static void chat_onMessage(ToxWindow *self, Messenger *m, int num, uint8_t *msg, uint16_t len)
{
ChatContext *ctx = (ChatContext*) self->x;
uint8_t nick[MAX_NAME_LENGTH] = {0};
@ -43,7 +43,7 @@ static void chat_onMessage(ToxWindow *self, int num, uint8_t *msg, uint16_t len)
if (ctx->friendnum != num)
return;
getname(num, (uint8_t*) &nick);
getname(m, num, (uint8_t*) &nick);
msg[len-1] = '\0';
nick[MAX_NAME_LENGTH-1] = '\0';
fix_name(msg);
@ -61,7 +61,7 @@ static void chat_onMessage(ToxWindow *self, int num, uint8_t *msg, uint16_t len)
beep();
}
static void chat_onAction(ToxWindow *self, int num, uint8_t *action, uint16_t len)
static void chat_onAction(ToxWindow *self, Messenger *m, int num, uint8_t *action, uint16_t len)
{
ChatContext *ctx = (ChatContext*) self->x;
time_t now;
@ -117,7 +117,7 @@ int string_is_empty(char *string)
return rc;
}
static void chat_onKey(ToxWindow *self, int key)
static void chat_onKey(ToxWindow *self, Messenger *m, int key)
{
ChatContext *ctx = (ChatContext*) self->x;
time_t now;
@ -155,7 +155,7 @@ static void chat_onKey(ToxWindow *self, int key)
wmove(self->window, y2-CURS_Y_OFFSET, 0);
wclrtobot(self->window);
if (ctx->line[0] == '/')
execute(self, ctx, ctx->line, timeinfo);
execute(self, ctx, m, ctx->line, timeinfo);
else {
if (!string_is_empty(ctx->line)) {
/* make sure the string has at least non-space character */
@ -167,7 +167,7 @@ static void chat_onKey(ToxWindow *self, int key)
wattroff(ctx->history, COLOR_PAIR(1));
wprintw(ctx->history, "%s\n", ctx->line);
}
if (m_sendmessage(ctx->friendnum, (uint8_t*) ctx->line, strlen(ctx->line)+1) == 0) {
if (m_sendmessage(m, ctx->friendnum, (uint8_t*) ctx->line, strlen(ctx->line)+1) == 0) {
wattron(ctx->history, COLOR_PAIR(3));
wprintw(ctx->history, " * Failed to send message.\n");
wattroff(ctx->history, COLOR_PAIR(3));
@ -178,7 +178,7 @@ static void chat_onKey(ToxWindow *self, int key)
}
}
void execute(ToxWindow *self, ChatContext *ctx, char *cmd, struct tm *timeinfo)
void execute(ToxWindow *self, ChatContext *ctx, Messenger *m, char *cmd, struct tm *timeinfo)
{
if (!strcmp(cmd, "/clear") || !strcmp(cmd, "/c")) {
wclear(self->window);
@ -210,14 +210,14 @@ void execute(ToxWindow *self, ChatContext *ctx, char *cmd, struct tm *timeinfo)
wattroff(ctx->history, COLOR_PAIR(2));
uint8_t selfname[MAX_NAME_LENGTH];
int len = getself_name(selfname);
int len = getself_name(m, selfname);
char msg[MAX_STR_SIZE-len-4];
snprintf(msg, sizeof(msg), "* %s %s\n", (uint8_t*) selfname, action);
wattron(ctx->history, COLOR_PAIR(1));
wprintw(ctx->history, msg);
wattroff(ctx->history, COLOR_PAIR(1));
if (m_sendaction(ctx->friendnum, (uint8_t*) msg, strlen(msg)+1) < 0) {
if (m_sendaction(m, ctx->friendnum, (uint8_t*) msg, strlen(msg)+1) < 0) {
wattron(ctx->history, COLOR_PAIR(3));
wprintw(ctx->history, " * Failed to send action\n");
wattroff(ctx->history, COLOR_PAIR(3));
@ -256,13 +256,13 @@ void execute(ToxWindow *self, ChatContext *ctx, char *cmd, struct tm *timeinfo)
msg = strchr(status, ' ');
if (msg == NULL) {
m_set_userstatus(status_kind);
m_set_userstatus(m, status_kind);
wprintw(ctx->history, "Status set to: %s\n", status_text);
}
else {
msg++;
m_set_userstatus(status_kind);
m_set_statusmessage((uint8_t*) msg, strlen(msg)+1);
m_set_userstatus(m, status_kind);
m_set_statusmessage(m, ( uint8_t*) msg, strlen(msg)+1);
wprintw(ctx->history, "Status set to: %s, %s\n", status_text, msg);
}
}
@ -275,7 +275,7 @@ void execute(ToxWindow *self, ChatContext *ctx, char *cmd, struct tm *timeinfo)
return;
}
nick++;
setname((uint8_t*) nick, strlen(nick)+1);
setname(m, (uint8_t*) nick, strlen(nick)+1);
wprintw(ctx->history, "Nickname set to: %s\n", nick);
}
@ -312,7 +312,7 @@ static void chat_onDraw(ToxWindow *self)
wrefresh(self->window);
}
static void chat_onInit(ToxWindow *self)
static void chat_onInit(ToxWindow *self, Messenger *m)
{
int x, y;
ChatContext *ctx = (ChatContext*) self->x;
@ -329,7 +329,7 @@ void print_help(ChatContext *self)
wattron(self->history, COLOR_PAIR(2) | A_BOLD);
wprintw(self->history, "Commands:\n");
wattroff(self->history, A_BOLD);
wprintw(self->history, " /status <type> <message> : Set your status\n");
wprintw(self->history, " /nick <nickname> : Set your nickname\n");
wprintw(self->history, " /me <action> : Do an action\n");
@ -342,7 +342,7 @@ void print_help(ChatContext *self)
wattroff(self->history, COLOR_PAIR(2));
}
ToxWindow new_chat(int friendnum)
ToxWindow new_chat(Messenger *m, int friendnum)
{
ToxWindow ret;
memset(&ret, 0, sizeof(ret));
@ -356,7 +356,7 @@ ToxWindow new_chat(int friendnum)
ret.onAction = &chat_onAction;
uint8_t nick[MAX_NAME_LENGTH] = {0};
getname(friendnum, (uint8_t*) &nick);
getname(m, friendnum, (uint8_t*) &nick);
fix_name(nick);
snprintf(ret.title, sizeof(ret.title), "[%s (%d)]", nick, friendnum);

View File

@ -14,7 +14,7 @@
extern char WINDOW_STATUS[TOXWINDOWS_MAX_NUM];
extern int add_window(ToxWindow w, int n);
extern ToxWindow new_chat(int friendnum);
extern ToxWindow new_chat(Messenger *m, int friendnum);
extern int active_window;
@ -42,7 +42,7 @@ void fix_name(uint8_t *name)
*q = 0;
}
void friendlist_onMessage(ToxWindow *self, int num, uint8_t *str, uint16_t len)
void friendlist_onMessage(ToxWindow *self, Messenger *m, int num, uint8_t *str, uint16_t len)
{
if (num >= num_friends)
return;
@ -54,7 +54,7 @@ void friendlist_onMessage(ToxWindow *self, int num, uint8_t *str, uint16_t len)
for (i = N_DEFAULT_WINS; i < MAX_WINDOW_SLOTS; ++i) {
if (WINDOW_STATUS[i] == -1) {
WINDOW_STATUS[i] = num;
add_window(new_chat(num), i);
add_window(new_chat(m, num), i);
active_window = i;
break;
}
@ -82,20 +82,20 @@ void friendlist_onStatusChange(ToxWindow *self, int num, uint8_t *str, uint16_t
fix_name(friends[num].status);
}
int friendlist_onFriendAdded(int num)
int friendlist_onFriendAdded(Messenger *m, int num)
{
if (num_friends == MAX_FRIENDS_NUM)
return -1;
friends[num_friends].num = num;
getname(num, friends[num_friends].name);
getname(m, num, friends[num_friends].name);
strcpy((char*) friends[num_friends].name, "unknown");
strcpy((char*) friends[num_friends].status, "unknown");
friends[num_friends++].chatwin = -1;
return 0;
}
static void friendlist_onKey(ToxWindow *self, int key)
static void friendlist_onKey(ToxWindow *self, Messenger *m, int key)
{
if (key == KEY_UP) {
if (--num_selected < 0)
@ -121,7 +121,7 @@ static void friendlist_onKey(ToxWindow *self, int key)
if (WINDOW_STATUS[i] == -1) {
WINDOW_STATUS[i] = num_selected;
friends[num_selected].chatwin = num_selected;
add_window(new_chat(num_selected), i);
add_window(new_chat(m, num_selected), i);
active_window = i;
break;
}
@ -164,7 +164,7 @@ void disable_chatwin(int f_num)
friends[f_num].chatwin = -1;
}
static void friendlist_onInit(ToxWindow *self)
static void friendlist_onInit(ToxWindow *self, Messenger *m)
{
}

47
main.c
View File

@ -25,7 +25,7 @@
extern ToxWindow new_prompt();
extern ToxWindow new_friendlist();
extern int friendlist_onFriendAdded(int num);
extern int friendlist_onFriendAdded(Messenger *m, int num);
extern void disable_chatwin(int f_num);
extern int add_req(uint8_t *public_key); // XXX
extern unsigned char *hex_string_to_bin(char hex_string[]);
@ -40,6 +40,8 @@ char WINDOW_STATUS[MAX_WINDOW_SLOTS];
static ToxWindow windows[MAX_WINDOW_SLOTS];
static ToxWindow* prompt;
static Messenger *m;
int w_num;
int active_window;
@ -63,25 +65,25 @@ void on_request(uint8_t *public_key, uint8_t *data, uint16_t length)
}
}
void on_message(int friendnumber, uint8_t *string, uint16_t length)
void on_message(Messenger *m, int friendnumber, uint8_t *string, uint16_t length)
{
int i;
for (i = 0; i < MAX_WINDOW_SLOTS; ++i) {
if (windows[i].onMessage != NULL)
windows[i].onMessage(&windows[i], friendnumber, string, length);
windows[i].onMessage(&windows[i], m, friendnumber, string, length);
}
}
void on_action(int friendnumber, uint8_t *string, uint16_t length)
void on_action(Messenger *m, int friendnumber, uint8_t *string, uint16_t length)
{
int i;
for (i = 0; i < MAX_WINDOW_SLOTS; ++i) {
if (windows[i].onAction != NULL)
windows[i].onAction(&windows[i], friendnumber, string, length);
windows[i].onAction(&windows[i], m, friendnumber, string, length);
}
}
void on_nickchange(int friendnumber, uint8_t *string, uint16_t length)
void on_nickchange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length)
{
wprintw(prompt->window, "\n(nickchange) %d: %s\n", friendnumber, string);
int i;
@ -91,7 +93,7 @@ void on_nickchange(int friendnumber, uint8_t *string, uint16_t length)
}
}
void on_statuschange(int friendnumber, uint8_t *string, uint16_t length)
void on_statuschange(Messenger *m, int friendnumber, uint8_t *string, uint16_t length)
{
wprintw(prompt->window, "\n(statuschange) %d: %s\n", friendnumber, string);
int i;
@ -103,7 +105,7 @@ void on_statuschange(int friendnumber, uint8_t *string, uint16_t length)
void on_friendadded(int friendnumber)
{
friendlist_onFriendAdded(friendnumber);
friendlist_onFriendAdded(m, friendnumber);
}
/* CALLBACKS END */
@ -129,14 +131,14 @@ static void init_term()
static void init_tox()
{
/* Init core */
initMessenger();
m = initMessenger();
/* Callbacks */
m_callback_friendrequest(on_request);
m_callback_friendmessage(on_message);
m_callback_namechange(on_nickchange);
m_callback_statusmessage(on_statuschange);
m_callback_action(on_action);
m_callback_friendrequest(m, on_request);
m_callback_friendmessage(m, on_message);
m_callback_namechange(m, on_nickchange);
m_callback_statusmessage(m, on_statuschange);
m_callback_action(m, on_action);
}
#define MAXLINE 90 /* Approx max number of chars in a sever line (IP + port + key) */
@ -211,7 +213,7 @@ int add_window(ToxWindow w, int n)
return -1;
windows[n] = w;
w.onInit(&w);
w.onInit(&w, m);
w_num++;
return n;
}
@ -237,7 +239,7 @@ static void init_windows()
w_num = 0;
int n_prompt = 0;
int n_friendslist = 1;
if (add_window(new_prompt(), n_prompt) == -1
if (add_window(new_prompt(), n_prompt) == -1
|| add_window(new_friendlist(), n_friendslist) == -1) {
fprintf(stderr, "add_window() failed.\n");
endwin();
@ -257,7 +259,7 @@ static void do_tox()
dht_on = false;
wprintw(prompt->window, "\nDHT disconnected.\n");
}
doMessenger();
doMessenger(m);
}
static void load_data(char *path)
@ -285,17 +287,17 @@ static void load_data(char *path)
endwin();
exit(1);
}
Messenger_load(buf, len);
Messenger_load(m, buf, len);
}
else {
len = Messenger_size();
len = Messenger_size(m);
buf = malloc(len);
if (buf == NULL) {
fprintf(stderr, "malloc() failed.\n");
endwin();
exit(1);
}
Messenger_save(buf);
Messenger_save(m, buf);
fd = fopen(path, "w");
if (fd == NULL) {
@ -329,7 +331,7 @@ static void draw_bar()
move(LINES - 1, 0);
attron(COLOR_PAIR(4) | A_BOLD);
printw(" TOXIC " TOXICVER "|");
printw(" TOXIC " TOXICVER "|");
attroff(COLOR_PAIR(4) | A_BOLD);
int i;
@ -473,7 +475,8 @@ int main(int argc, char *argv[])
if (ch == '\t' || ch == KEY_BTAB)
set_active_window(ch);
else if (ch != ERR)
a->onKey(a, ch);
a->onKey(a, m, ch);
}
cleanupMessenger(m);
return 0;
}

View File

@ -20,24 +20,24 @@ static char prompt_buf[MAX_STR_SIZE] = {0};
static int prompt_buf_pos = 0;
/* commands */
void cmd_accept(ToxWindow *, char **);
void cmd_add(ToxWindow *, char **);
void cmd_clear(ToxWindow *, char **);
void cmd_connect(ToxWindow *, char **);
void cmd_help(ToxWindow *, char **);
void cmd_msg(ToxWindow *, char **);
void cmd_myid(ToxWindow *, char **);
void cmd_nick(ToxWindow *, char **);
void cmd_quit(ToxWindow *, char **);
void cmd_status(ToxWindow *, char **);
void cmd_statusmsg(ToxWindow *, char **);
void cmd_accept(ToxWindow *, Messenger *m, char **);
void cmd_add(ToxWindow *, Messenger *m, char **);
void cmd_clear(ToxWindow *, Messenger *m, char **);
void cmd_connect(ToxWindow *, Messenger *m, char **);
void cmd_help(ToxWindow *, Messenger *m, char **);
void cmd_msg(ToxWindow *, Messenger *m, char **);
void cmd_myid(ToxWindow *, Messenger *m, char **);
void cmd_nick(ToxWindow *, Messenger *m, char **);
void cmd_quit(ToxWindow *, Messenger *m, char **);
void cmd_status(ToxWindow *, Messenger *m, char **);
void cmd_statusmsg(ToxWindow *, Messenger *m, char **);
#define NUM_COMMANDS 13
static struct {
char *name;
int numargs;
void (*func)(ToxWindow *, char **);
void (*func)(ToxWindow *, Messenger *m, char **);
} commands[] = {
{ "accept", 1, cmd_accept },
{ "add", 1, cmd_add },
@ -74,7 +74,7 @@ unsigned char *hex_string_to_bin(char hex_string[])
return val;
}
void cmd_accept(ToxWindow *self, char **args)
void cmd_accept(ToxWindow *self, Messenger *m, char **args)
{
int num = atoi(args[1]);
if (num >= num_requests) {
@ -82,7 +82,7 @@ void cmd_accept(ToxWindow *self, char **args)
return;
}
num = m_addfriend_norequest(pending_requests[num]);
num = m_addfriend_norequest(m, pending_requests[num]);
if (num == -1)
wprintw(self->window, "Failed to add friend.\n");
else {
@ -91,7 +91,7 @@ void cmd_accept(ToxWindow *self, char **args)
}
}
void cmd_add(ToxWindow *self, char **args)
void cmd_add(ToxWindow *self, Messenger *m, char **args)
{
uint8_t id_bin[KEY_SIZE_BYTES];
char xx[3];
@ -121,7 +121,7 @@ void cmd_add(ToxWindow *self, char **args)
}
id_bin[i] = x;
}
int num = m_addfriend(id_bin, (uint8_t*) msg, strlen(msg)+1);
int num = m_addfriend(m, id_bin, (uint8_t*) msg, strlen(msg)+1);
switch (num) {
case FAERR_TOOLONG:
wprintw(self->window, "Message is too long.\n");
@ -145,12 +145,12 @@ void cmd_add(ToxWindow *self, char **args)
}
}
void cmd_clear(ToxWindow *self, char **args)
void cmd_clear(ToxWindow *self, Messenger *m, char **args)
{
wclear(self->window);
}
void cmd_connect(ToxWindow *self, char **args)
void cmd_connect(ToxWindow *self, Messenger *m, char **args)
{
IP_Port dht;
char *ip = args[1];
@ -174,13 +174,13 @@ void cmd_connect(ToxWindow *self, char **args)
free(binary_string);
}
void cmd_quit(ToxWindow *self, char **args)
void cmd_quit(ToxWindow *self, Messenger *m, char **args)
{
endwin();
exit(0);
}
void cmd_help(ToxWindow *self, char **args)
void cmd_help(ToxWindow *self, Messenger *m, char **args)
{
wclear(self->window);
wattron(self->window, COLOR_PAIR(2) | A_BOLD);
@ -197,7 +197,7 @@ void cmd_help(ToxWindow *self, char **args)
wprintw(self->window, " quit/exit : Exit program\n");
wprintw(self->window, " help : Print this message again\n");
wprintw(self->window, " clear : Clear this window\n");
wattron(self->window, A_BOLD);
wprintw(self->window, "TIP: Use the TAB key to navigate through the tabs.\n\n");
wattroff(self->window, A_BOLD);
@ -205,17 +205,17 @@ void cmd_help(ToxWindow *self, char **args)
wattroff(self->window, COLOR_PAIR(2));
}
void cmd_msg(ToxWindow *self, char **args)
void cmd_msg(ToxWindow *self, Messenger *m, char **args)
{
char *id = args[1];
char *msg = args[2];
if (m_sendmessage(atoi(id), (uint8_t*) msg, strlen(msg)+1) == 0)
if (m_sendmessage(m, atoi(id), (uint8_t*) msg, strlen(msg)+1) == 0)
wprintw(self->window, "Error occurred while sending message.\n");
else
wprintw(self->window, "Message successfully sent.\n");
}
void cmd_myid(ToxWindow *self, char **args)
void cmd_myid(ToxWindow *self, Messenger *m, char **args)
{
char id[KEY_SIZE_BYTES*2 + 1] = {0};
size_t i;
@ -227,14 +227,14 @@ void cmd_myid(ToxWindow *self, char **args)
wprintw(self->window, "Your ID: %s\n", id);
}
void cmd_nick(ToxWindow *self, char **args)
void cmd_nick(ToxWindow *self, Messenger *m, char **args)
{
char *nick = args[1];
setname((uint8_t*) nick, strlen(nick)+1);
setname(m, (uint8_t*) nick, strlen(nick)+1);
wprintw(self->window, "Nickname set to: %s\n", nick);
}
void cmd_status(ToxWindow *self, char **args)
void cmd_status(ToxWindow *self, Messenger *m, char **args)
{
char *status = args[1];
char *status_text;
@ -260,24 +260,24 @@ void cmd_status(ToxWindow *self, char **args)
char *msg = args[2];
if (msg == NULL) {
m_set_userstatus(status_kind);
m_set_userstatus(m, status_kind);
wprintw(self->window, "Status set to: %s\n", status_text);
}
else {
m_set_userstatus(status_kind);
m_set_statusmessage((uint8_t*) msg, strlen(msg)+1);
m_set_userstatus(m, status_kind);
m_set_statusmessage(m, (uint8_t*) msg, strlen(msg)+1);
wprintw(self->window, "Status set to: %s, %s\n", status_text, msg);
}
}
void cmd_statusmsg(ToxWindow *self, char **args)
void cmd_statusmsg(ToxWindow *self, Messenger *m, char **args)
{
char *msg = args[1];
m_set_statusmessage((uint8_t*) msg, strlen(msg)+1);
m_set_statusmessage(m, (uint8_t*) msg, strlen(msg)+1);
wprintw(self->window, "Status set to: %s\n", msg);
}
static void execute(ToxWindow *self, char *u_cmd)
static void execute(ToxWindow *self, Messenger *m, char *u_cmd)
{
int newlines = 0;
char cmd[MAX_STR_SIZE] = {0};
@ -341,13 +341,13 @@ static void execute(ToxWindow *self, char *u_cmd)
return;
}
}
/* check for excess arguments */
/* check for excess arguments */
if (strcmp(cmdargs[0], "add") && strlen(cmdargs[j]) != 0) {
wprintw(self->window, "Invalid command: too many arguments to %s.\n", commands[i].name);
return;
}
/* pass arguments to command function */
(commands[i].func)(self, cmdargs);
(commands[i].func)(self, m, cmdargs);
return;
}
}
@ -356,7 +356,7 @@ static void execute(ToxWindow *self, char *u_cmd)
wprintw(self->window, "Invalid command.\n");
}
static void prompt_onKey(ToxWindow *self, int key)
static void prompt_onKey(ToxWindow *self, Messenger *m, int key)
{
/* Add printable characters to line */
if (isprint(key)) {
@ -380,7 +380,7 @@ static void prompt_onKey(ToxWindow *self, int key)
/* RETURN key: execute command */
else if (key == '\n') {
wprintw(self->window, "\n");
execute(self, prompt_buf);
execute(self, m, prompt_buf);
prompt_buf_pos = 0;
prompt_buf[0] = 0;
}
@ -413,10 +413,10 @@ static void prompt_onDraw(ToxWindow *self)
wrefresh(self->window);
}
static void prompt_onInit(ToxWindow *self)
static void prompt_onInit(ToxWindow *self, Messenger *m)
{
scrollok(self->window, 1);
cmd_help(self, NULL);
cmd_help(self, m, NULL);
wclrtoeol(self->window);
}

View File

@ -9,7 +9,7 @@
#define KEY_SIZE_BYTES 32
/* number of permanent default windows */
#define N_DEFAULT_WINS 2
#define N_DEFAULT_WINS 2
/* maximum window slots for WINDOW_STATUS array */
#define MAX_WINDOW_SLOTS N_DEFAULT_WINS+MAX_FRIENDS_NUM
@ -17,14 +17,14 @@
typedef struct ToxWindow_ ToxWindow;
struct ToxWindow_ {
void(*onKey)(ToxWindow*, int);
void(*onKey)(ToxWindow*, Messenger*, int);
void(*onDraw)(ToxWindow*);
void(*onInit)(ToxWindow*);
void(*onInit)(ToxWindow*, Messenger*);
void(*onFriendRequest)(ToxWindow*, uint8_t*, uint8_t*, uint16_t);
void(*onMessage)(ToxWindow*, int, uint8_t*, uint16_t);
void(*onMessage)(ToxWindow*, Messenger*, int, uint8_t*, uint16_t);
void(*onNickChange)(ToxWindow*, int, uint8_t*, uint16_t);
void(*onStatusChange)(ToxWindow*, int, uint8_t*, uint16_t);
void(*onAction)(ToxWindow*, int, uint8_t*, uint16_t);
void(*onAction)(ToxWindow*, Messenger*, int, uint8_t*, uint16_t);
char title[256];
void* x;