From c4a11f8dc71c490088c51f44589161412ca6ba5c Mon Sep 17 00:00:00 2001 From: jfreegman Date: Tue, 9 Oct 2018 18:59:25 -0400 Subject: [PATCH] Refactor ToxWindows ToxWindow constructor functions now return pointers instead of structs ToxWindow windows array now holds pointers instead of structs Refactor some logic in windows.c pertaining to keeping track of active windows Use uint8_t for window array indexing --- src/audio_call.c | 85 +++++-------- src/chat.c | 78 ++++++------ src/chat.h | 2 +- src/friendlist.c | 72 +++++------ src/friendlist.h | 2 +- src/groupchat.c | 44 +++---- src/groupchat.h | 2 +- src/prompt.c | 34 ++--- src/prompt.h | 2 +- src/toxic.c | 1 - src/windows.c | 314 ++++++++++++++++++++++------------------------- src/windows.h | 10 +- 12 files changed, 303 insertions(+), 343 deletions(-) diff --git a/src/audio_call.c b/src/audio_call.c index 5c2a38e..052448d 100644 --- a/src/audio_call.c +++ b/src/audio_call.c @@ -58,6 +58,8 @@ #endif /* __APPLE__ */ extern FriendsList Friends; +extern ToxWindow *windows[MAX_WINDOWS_NUM]; + struct CallControl CallControl; #define cbend pthread_exit(NULL) @@ -371,38 +373,28 @@ void callback_recv_invite(Tox *m, uint32_t friend_number) Friends.list[friend_number].chatwin = add_window(m, new_chat(m, Friends.list[friend_number].num)); } - ToxWindow *windows = CallControl.prompt; - int i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onInvite != NULL && windows[i].num == friend_number) { - windows[i].onInvite(&windows[i], CallControl.av, friend_number, CallControl.call_state); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onInvite != NULL && windows[i]->num == friend_number) { + windows[i]->onInvite(windows[i], CallControl.av, friend_number, CallControl.call_state); } } } void callback_recv_ringing(uint32_t friend_number) { - ToxWindow *windows = CallControl.prompt; - int i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onRinging != NULL && windows[i].num == friend_number) { - windows[i].onRinging(&windows[i], CallControl.av, friend_number, CallControl.call_state); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onRinging != NULL && windows[i]->num == friend_number) { + windows[i]->onRinging(windows[i], CallControl.av, friend_number, CallControl.call_state); } } } void callback_recv_starting(uint32_t friend_number) { - ToxWindow *windows = CallControl.prompt; + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onStarting != NULL && windows[i]->num == friend_number) { + windows[i]->onStarting(windows[i], CallControl.av, friend_number, CallControl.call_state); - int i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onStarting != NULL && windows[i].num == friend_number) { - windows[i].onStarting(&windows[i], CallControl.av, friend_number, CallControl.call_state); - - if (0 != start_transmission(&windows[i], &CallControl.calls[friend_number])) { /* YEAH! */ - line_info_add(&windows[i], NULL, NULL, NULL, SYS_MSG, 0, 0, "Error starting transmission!"); + if (0 != start_transmission(windows[i], &CallControl.calls[friend_number])) { /* YEAH! */ + line_info_add(windows[i], NULL, NULL, NULL, SYS_MSG, 0, 0, "Error starting transmission!"); } return; @@ -411,61 +403,46 @@ void callback_recv_starting(uint32_t friend_number) } void callback_recv_ending(uint32_t friend_number) { - ToxWindow *windows = CallControl.prompt; - int i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onEnding != NULL && windows[i].num == friend_number) { - windows[i].onEnding(&windows[i], CallControl.av, friend_number, CallControl.call_state); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onEnding != NULL && windows[i]->num == friend_number) { + windows[i]->onEnding(windows[i], CallControl.av, friend_number, CallControl.call_state); } } } void callback_call_started(uint32_t friend_number) { - ToxWindow *windows = CallControl.prompt; + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onStart != NULL && windows[i]->num == friend_number) { + windows[i]->onStart(windows[i], CallControl.av, friend_number, CallControl.call_state); - int i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) - if (windows[i].onStart != NULL && windows[i].num == friend_number) { - windows[i].onStart(&windows[i], CallControl.av, friend_number, CallControl.call_state); - - if (0 != start_transmission(&windows[i], &CallControl.calls[friend_number])) { /* YEAH! */ - line_info_add(&windows[i], NULL, NULL, NULL, SYS_MSG, 0, 0, "Error starting transmission!"); + if (0 != start_transmission(windows[i], &CallControl.calls[friend_number])) { /* YEAH! */ + line_info_add(windows[i], NULL, NULL, NULL, SYS_MSG, 0, 0, "Error starting transmission!"); return; } } + } } void callback_call_canceled(uint32_t friend_number) { - ToxWindow *windows = CallControl.prompt; - int i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onCancel != NULL && windows[i].num == friend_number) { - windows[i].onCancel(&windows[i], CallControl.av, friend_number, CallControl.call_state); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onCancel != NULL && windows[i]->num == friend_number) { + windows[i]->onCancel(windows[i], CallControl.av, friend_number, CallControl.call_state); } } } void callback_call_rejected(uint32_t friend_number) { - ToxWindow *windows = CallControl.prompt; - int i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onReject != NULL && windows[i].num == friend_number) { - windows[i].onReject(&windows[i], CallControl.av, friend_number, CallControl.call_state); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onReject != NULL && windows[i]->num == friend_number) { + windows[i]->onReject(windows[i], CallControl.av, friend_number, CallControl.call_state); } } } void callback_call_ended(uint32_t friend_number) { - ToxWindow *windows = CallControl.prompt; - int i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onEnd != NULL && windows[i].num == friend_number) { - windows[i].onEnd(&windows[i], CallControl.av, friend_number, CallControl.call_state); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onEnd != NULL && windows[i]->num == friend_number) { + windows[i]->onEnd(windows[i], CallControl.av, friend_number, CallControl.call_state); } } } diff --git a/src/chat.c b/src/chat.c index ed36de7..343735c 100644 --- a/src/chat.c +++ b/src/chat.c @@ -1290,51 +1290,53 @@ static void chat_onInit(ToxWindow *self, Tox *m) wmove(self->window, y2 - CURS_Y_OFFSET, 0); } -ToxWindow new_chat(Tox *m, uint32_t friendnum) +ToxWindow *new_chat(Tox *m, uint32_t friendnum) { - ToxWindow ret; - memset(&ret, 0, sizeof(ret)); + ToxWindow *ret = calloc(1, sizeof(ToxWindow)); - ret.active = true; - ret.is_chat = true; + if (ret == NULL) { + exit_toxic_err("failed in new_chat", FATALERR_MEMORY); + } - ret.onKey = &chat_onKey; - ret.onDraw = &chat_onDraw; - ret.onInit = &chat_onInit; - ret.onMessage = &chat_onMessage; - ret.onConnectionChange = &chat_onConnectionChange; - ret.onTypingChange = & chat_onTypingChange; - ret.onGroupInvite = &chat_onGroupInvite; - ret.onNickChange = &chat_onNickChange; - ret.onStatusChange = &chat_onStatusChange; - ret.onStatusMessageChange = &chat_onStatusMessageChange; - ret.onFileChunkRequest = &chat_onFileChunkRequest; - ret.onFileRecvChunk = &chat_onFileRecvChunk; - ret.onFileControl = &chat_onFileControl; - ret.onFileRecv = &chat_onFileRecv; - ret.onReadReceipt = &chat_onReadReceipt; + ret->is_chat = true; + + ret->onKey = &chat_onKey; + ret->onDraw = &chat_onDraw; + ret->onInit = &chat_onInit; + ret->onMessage = &chat_onMessage; + ret->onConnectionChange = &chat_onConnectionChange; + ret->onTypingChange = & chat_onTypingChange; + ret->onGroupInvite = &chat_onGroupInvite; + ret->onNickChange = &chat_onNickChange; + ret->onStatusChange = &chat_onStatusChange; + ret->onStatusMessageChange = &chat_onStatusMessageChange; + ret->onFileChunkRequest = &chat_onFileChunkRequest; + ret->onFileRecvChunk = &chat_onFileRecvChunk; + ret->onFileControl = &chat_onFileControl; + ret->onFileRecv = &chat_onFileRecv; + ret->onReadReceipt = &chat_onReadReceipt; #ifdef AUDIO - ret.onInvite = &chat_onInvite; - ret.onRinging = &chat_onRinging; - ret.onStarting = &chat_onStarting; - ret.onEnding = &chat_onEnding; - ret.onError = &chat_onError; - ret.onStart = &chat_onStart; - ret.onCancel = &chat_onCancel; - ret.onReject = &chat_onReject; - ret.onEnd = &chat_onEnd; + ret->onInvite = &chat_onInvite; + ret->onRinging = &chat_onRinging; + ret->onStarting = &chat_onStarting; + ret->onEnding = &chat_onEnding; + ret->onError = &chat_onError; + ret->onStart = &chat_onStart; + ret->onCancel = &chat_onCancel; + ret->onReject = &chat_onReject; + ret->onEnd = &chat_onEnd; - ret.is_call = false; - ret.device_selection[0] = ret.device_selection[1] = -1; - ret.ringing_sound = -1; + ret->is_call = false; + ret->device_selection[0] = ret->device_selection[1] = -1; + ret->ringing_sound = -1; #endif /* AUDIO */ - ret.active_box = -1; + ret->active_box = -1; char nick[TOX_MAX_NAME_LENGTH]; size_t n_len = get_nick_truncate(m, nick, friendnum); - set_window_title(&ret, nick, n_len); + set_window_title(ret, nick, n_len); ChatContext *chatwin = calloc(1, sizeof(ChatContext)); StatusBar *stb = calloc(1, sizeof(StatusBar)); @@ -1344,11 +1346,11 @@ ToxWindow new_chat(Tox *m, uint32_t friendnum) exit_toxic_err("failed in new_chat", FATALERR_MEMORY); } - ret.chatwin = chatwin; - ret.stb = stb; - ret.help = help; + ret->chatwin = chatwin; + ret->stb = stb; + ret->help = help; - ret.num = friendnum; + ret->num = friendnum; return ret; } diff --git a/src/chat.h b/src/chat.h index 783f78c..db899b5 100644 --- a/src/chat.h +++ b/src/chat.h @@ -30,6 +30,6 @@ set msg to NULL if we don't want to display a message */ void chat_close_file_receiver(Tox *m, int filenum, int friendnum, int CTRL); void kill_chat_window(ToxWindow *self, Tox *m); -ToxWindow new_chat(Tox *m, int32_t friendnum); +ToxWindow *new_chat(Tox *m, int32_t friendnum); #endif /* end of include guard: CHAT_H */ diff --git a/src/friendlist.c b/src/friendlist.c index 5f8cfb3..f733cf0 100644 --- a/src/friendlist.c +++ b/src/friendlist.c @@ -115,7 +115,7 @@ static void realloc_blocklist(int n) void kill_friendlist(ToxWindow *self) { - for (int i = 0; i < Friends.max_idx; ++i) { + for (size_t i = 0; i < Friends.max_idx; ++i) { if (Friends.list[i].active && Friends.list[i].group_invite.key != NULL) { free(Friends.list[i].group_invite.key); } @@ -619,7 +619,7 @@ static void delete_friend(Tox *m, uint32_t f_num) if (toxwin != NULL) { kill_chat_window(toxwin, m); - set_active_window(1); /* keep friendlist focused */ + set_active_window_index(1); /* keep friendlist focused */ } } @@ -844,10 +844,10 @@ static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) /* Jump to chat window if already open */ if (Friends.list[f].chatwin != -1) { - set_active_window(Friends.list[f].chatwin); + set_active_window_index(Friends.list[f].chatwin); } else if (get_num_active_windows() < MAX_WINDOWS_NUM) { Friends.list[f].chatwin = add_window(m, new_chat(m, Friends.list[f].num)); - set_active_window(Friends.list[f].chatwin); + set_active_window_index(Friends.list[f].chatwin); } else { const char *msg = "* Warning: Too many windows are open."; line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, msg); @@ -1209,7 +1209,7 @@ static void friendlist_onAV(ToxWindow *self, ToxAV *av, uint32_t friend_number, if (get_num_active_windows() < MAX_WINDOWS_NUM) { if (state != TOXAV_FRIEND_CALL_STATE_FINISHED) { Friends.list[friend_number].chatwin = add_window(m, new_chat(m, Friends.list[friend_number].num)); - set_active_window(Friends.list[friend_number].chatwin); + set_active_window_index(Friends.list[friend_number].chatwin); } } else { char nick[TOX_MAX_NAME_LENGTH]; @@ -1237,42 +1237,44 @@ Tox_Connection get_friend_connection_status(uint32_t friendnumber) return Friends.list[friendnumber].connection_status; } -ToxWindow new_friendlist(void) +ToxWindow *new_friendlist(void) { - ToxWindow ret; - memset(&ret, 0, sizeof(ret)); + ToxWindow *ret = calloc(1, sizeof(ToxWindow)); - ret.active = true; - ret.is_friendlist = true; + if (ret == NULL) { + exit_toxic_err("failed in new_friendlist", FATALERR_MEMORY); + } - ret.onKey = &friendlist_onKey; - ret.onDraw = &friendlist_onDraw; - ret.onFriendAdded = &friendlist_onFriendAdded; - ret.onMessage = &friendlist_onMessage; - ret.onConnectionChange = &friendlist_onConnectionChange; - ret.onNickChange = &friendlist_onNickChange; - ret.onStatusChange = &friendlist_onStatusChange; - ret.onStatusMessageChange = &friendlist_onStatusMessageChange; - ret.onFileRecv = &friendlist_onFileRecv; - ret.onGroupInvite = &friendlist_onGroupInvite; + ret->is_friendlist = true; + + ret->onKey = &friendlist_onKey; + ret->onDraw = &friendlist_onDraw; + ret->onFriendAdded = &friendlist_onFriendAdded; + ret->onMessage = &friendlist_onMessage; + ret->onConnectionChange = &friendlist_onConnectionChange; + ret->onNickChange = &friendlist_onNickChange; + ret->onStatusChange = &friendlist_onStatusChange; + ret->onStatusMessageChange = &friendlist_onStatusMessageChange; + ret->onFileRecv = &friendlist_onFileRecv; + ret->onGroupInvite = &friendlist_onGroupInvite; #ifdef AUDIO - ret.onInvite = &friendlist_onAV; - ret.onRinging = &friendlist_onAV; - ret.onStarting = &friendlist_onAV; - ret.onEnding = &friendlist_onAV; - ret.onError = &friendlist_onAV; - ret.onStart = &friendlist_onAV; - ret.onCancel = &friendlist_onAV; - ret.onReject = &friendlist_onAV; - ret.onEnd = &friendlist_onAV; + ret->onInvite = &friendlist_onAV; + ret->onRinging = &friendlist_onAV; + ret->onStarting = &friendlist_onAV; + ret->onEnding = &friendlist_onAV; + ret->onError = &friendlist_onAV; + ret->onStart = &friendlist_onAV; + ret->onCancel = &friendlist_onAV; + ret->onReject = &friendlist_onAV; + ret->onEnd = &friendlist_onAV; - ret.is_call = false; - ret.device_selection[0] = ret.device_selection[1] = -1; + ret->is_call = false; + ret->device_selection[0] = ret->device_selection[1] = -1; #endif /* AUDIO */ - ret.num = -1; - ret.active_box = -1; + ret->num = -1; + ret->active_box = -1; Help *help = calloc(1, sizeof(Help)); @@ -1280,7 +1282,7 @@ ToxWindow new_friendlist(void) exit_toxic_err("failed in new_friendlist", FATALERR_MEMORY); } - ret.help = help; - strcpy(ret.name, "contacts"); + ret->help = help; + strcpy(ret->name, "contacts"); return ret; } diff --git a/src/friendlist.h b/src/friendlist.h index a9ae3be..ee5667d 100644 --- a/src/friendlist.h +++ b/src/friendlist.h @@ -81,7 +81,7 @@ typedef struct { ToxicFriend *list; } FriendsList; -ToxWindow new_friendlist(void); +ToxWindow *new_friendlist(void); void disable_chatwin(uint32_t f_num); int get_friendnum(uint8_t *name); int load_blocklist(char *data); diff --git a/src/groupchat.c b/src/groupchat.c index ea5e096..915aa38 100644 --- a/src/groupchat.c +++ b/src/groupchat.c @@ -134,7 +134,7 @@ int init_groupchat_win(ToxWindow *prompt, Tox *m, uint32_t groupnum, uint8_t typ return -1; } - ToxWindow self = new_group_chat(m, groupnum); + ToxWindow *self = new_group_chat(m, groupnum); for (int i = 0; i <= max_groupchat_index; ++i) { if (!groupchats[i].active) { @@ -144,7 +144,7 @@ int init_groupchat_win(ToxWindow *prompt, Tox *m, uint32_t groupnum, uint8_t typ groupchats[i].type = type; groupchats[i].start_time = get_unix_time(); - set_active_window(groupchats[i].chatwin); + set_active_window_index(groupchats[i].chatwin); if (i == max_groupchat_index) { ++max_groupchat_index; @@ -154,7 +154,7 @@ int init_groupchat_win(ToxWindow *prompt, Tox *m, uint32_t groupnum, uint8_t typ } } - kill_groupchat_window(&self); + kill_groupchat_window(self); return -1; } @@ -700,23 +700,25 @@ static void groupchat_onInit(ToxWindow *self, Tox *m) wmove(self->window, y2 - CURS_Y_OFFSET, 0); } -ToxWindow new_group_chat(Tox *m, uint32_t groupnum) +ToxWindow *new_group_chat(Tox *m, uint32_t groupnum) { - ToxWindow ret; - memset(&ret, 0, sizeof(ret)); + ToxWindow *ret = calloc(1, sizeof(ToxWindow)); - ret.active = true; - ret.is_groupchat = true; + if (ret == NULL) { + exit_toxic_err("failed in new_group_chat", FATALERR_MEMORY); + } - ret.onKey = &groupchat_onKey; - ret.onDraw = &groupchat_onDraw; - ret.onInit = &groupchat_onInit; - ret.onGroupMessage = &groupchat_onGroupMessage; - ret.onGroupNameListChange = &groupchat_onGroupNameListChange; - ret.onGroupPeerNameChange = &groupchat_onGroupPeerNameChange; - ret.onGroupTitleChange = &groupchat_onGroupTitleChange; + ret->is_groupchat = true; - snprintf(ret.name, sizeof(ret.name), "Group %d", groupnum); + ret->onKey = &groupchat_onKey; + ret->onDraw = &groupchat_onDraw; + ret->onInit = &groupchat_onInit; + ret->onGroupMessage = &groupchat_onGroupMessage; + ret->onGroupNameListChange = &groupchat_onGroupNameListChange; + ret->onGroupPeerNameChange = &groupchat_onGroupPeerNameChange; + ret->onGroupTitleChange = &groupchat_onGroupTitleChange; + + snprintf(ret->name, sizeof(ret->name), "Group %u", groupnum); ChatContext *chatwin = calloc(1, sizeof(ChatContext)); Help *help = calloc(1, sizeof(Help)); @@ -725,12 +727,12 @@ ToxWindow new_group_chat(Tox *m, uint32_t groupnum) exit_toxic_err("failed in new_group_chat", FATALERR_MEMORY); } - ret.chatwin = chatwin; - ret.help = help; + ret->chatwin = chatwin; + ret->help = help; - ret.num = groupnum; - ret.show_peerlist = true; - ret.active_box = -1; + ret->num = groupnum; + ret->show_peerlist = true; + ret->active_box = -1; return ret; } diff --git a/src/groupchat.h b/src/groupchat.h index 6d77b47..2b319e0 100644 --- a/src/groupchat.h +++ b/src/groupchat.h @@ -61,6 +61,6 @@ int init_groupchat_win(ToxWindow *prompt, Tox *m, uint32_t groupnum, uint8_t typ /* destroys and re-creates groupchat window with or without the peerlist */ void redraw_groupchat_win(ToxWindow *self); -ToxWindow new_group_chat(Tox *m, uint32_t groupnum); +ToxWindow *new_group_chat(Tox *m, uint32_t groupnum); #endif /* GROUPCHAT_H */ diff --git a/src/prompt.c b/src/prompt.c index 06f7e6f..6cb4cec 100644 --- a/src/prompt.c +++ b/src/prompt.c @@ -594,22 +594,24 @@ static void prompt_onInit(ToxWindow *self, Tox *m) } } -ToxWindow new_prompt(void) +ToxWindow *new_prompt(void) { - ToxWindow ret; - memset(&ret, 0, sizeof(ret)); + ToxWindow *ret = calloc(1, sizeof(ToxWindow)); - ret.num = -1; - ret.active = true; - ret.is_prompt = true; + if (ret == NULL) { + exit_toxic_err("failed in new_prompt", FATALERR_MEMORY); + } - ret.onKey = &prompt_onKey; - ret.onDraw = &prompt_onDraw; - ret.onInit = &prompt_onInit; - ret.onConnectionChange = &prompt_onConnectionChange; - ret.onFriendRequest = &prompt_onFriendRequest; + ret->num = -1; + ret->is_prompt = true; - strcpy(ret.name, "home"); + ret->onKey = &prompt_onKey; + ret->onDraw = &prompt_onDraw; + ret->onInit = &prompt_onInit; + ret->onConnectionChange = &prompt_onConnectionChange; + ret->onFriendRequest = &prompt_onFriendRequest; + + strcpy(ret->name, "home"); ChatContext *chatwin = calloc(1, sizeof(ChatContext)); StatusBar *stb = calloc(1, sizeof(StatusBar)); @@ -619,11 +621,11 @@ ToxWindow new_prompt(void) exit_toxic_err("failed in new_prompt", FATALERR_MEMORY); } - ret.chatwin = chatwin; - ret.stb = stb; - ret.help = help; + ret->chatwin = chatwin; + ret->stb = stb; + ret->help = help; - ret.active_box = -1; + ret->active_box = -1; return ret; } diff --git a/src/prompt.h b/src/prompt.h index 62b7527..59b4a8e 100644 --- a/src/prompt.h +++ b/src/prompt.h @@ -42,7 +42,7 @@ typedef struct { extern FriendRequests FrndRequests; -ToxWindow new_prompt(void); +ToxWindow *new_prompt(void); void prep_prompt_win(void); void prompt_init_statusbar(ToxWindow *self, Tox *m, bool first_time_run); diff --git a/src/toxic.c b/src/toxic.c index 523f924..7fa68b1 100644 --- a/src/toxic.c +++ b/src/toxic.c @@ -1281,7 +1281,6 @@ int main(int argc, char **argv) arg_opts.encrypt_data = 0; } - init_term(); prompt = init_windows(m); diff --git a/src/windows.c b/src/windows.c index 9a3791a..f3bd50e 100644 --- a/src/windows.c +++ b/src/windows.c @@ -39,36 +39,32 @@ extern char *DATA_FILE; extern struct Winthread Winthread; -static ToxWindow windows[MAX_WINDOWS_NUM]; -static ToxWindow *active_window; + +ToxWindow *windows[MAX_WINDOWS_NUM]; +static uint8_t active_window_index; +static int num_active_windows; extern ToxWindow *prompt; extern struct user_settings *user_settings; -static int num_active_windows; - /* CALLBACKS START */ void on_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) { char msg[MAX_STR_SIZE + 1]; length = copy_tox_str(msg, sizeof(msg), (const char *) data, length); - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onFriendRequest != NULL) { - windows[i].onFriendRequest(&windows[i], m, (const char *) public_key, msg, length); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i]->onFriendRequest != NULL) { + windows[i]->onFriendRequest(windows[i], m, (const char *) public_key, msg, length); } } } void on_friend_connection_status(Tox *m, uint32_t friendnumber, Tox_Connection connection_status, void *userdata) { - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onConnectionChange != NULL) { - windows[i].onConnectionChange(&windows[i], m, friendnumber, connection_status); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onConnectionChange != NULL) { + windows[i]->onConnectionChange(windows[i], m, friendnumber, connection_status); } } } @@ -79,11 +75,9 @@ void on_friend_typing(Tox *m, uint32_t friendnumber, bool is_typing, void *userd return; } - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onTypingChange != NULL) { - windows[i].onTypingChange(&windows[i], m, friendnumber, is_typing); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onTypingChange != NULL) { + windows[i]->onTypingChange(windows[i], m, friendnumber, is_typing); } } } @@ -94,11 +88,9 @@ void on_friend_message(Tox *m, uint32_t friendnumber, Tox_Message_Type type, con char msg[MAX_STR_SIZE + 1]; length = copy_tox_str(msg, sizeof(msg), (const char *) string, length); - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onMessage != NULL) { - windows[i].onMessage(&windows[i], m, friendnumber, type, msg, length); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onMessage != NULL) { + windows[i]->onMessage(windows[i], m, friendnumber, type, msg, length); } } } @@ -109,11 +101,9 @@ void on_friend_name(Tox *m, uint32_t friendnumber, const uint8_t *string, size_t length = copy_tox_str(nick, sizeof(nick), (const char *) string, length); filter_str(nick, length); - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onNickChange != NULL) { - windows[i].onNickChange(&windows[i], m, friendnumber, nick, length); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onNickChange != NULL) { + windows[i]->onNickChange(windows[i], m, friendnumber, nick, length); } } @@ -126,33 +116,27 @@ void on_friend_status_message(Tox *m, uint32_t friendnumber, const uint8_t *stri length = copy_tox_str(msg, sizeof(msg), (const char *) string, length); filter_str(msg, length); - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onStatusMessageChange != NULL) { - windows[i].onStatusMessageChange(&windows[i], friendnumber, msg, length); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onStatusMessageChange != NULL) { + windows[i]->onStatusMessageChange(windows[i], friendnumber, msg, length); } } } void on_friend_status(Tox *m, uint32_t friendnumber, Tox_User_Status status, void *userdata) { - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onStatusChange != NULL) { - windows[i].onStatusChange(&windows[i], m, friendnumber, status); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onStatusChange != NULL) { + windows[i]->onStatusChange(windows[i], m, friendnumber, status); } } } void on_friend_added(Tox *m, uint32_t friendnumber, bool sort) { - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onFriendAdded != NULL) { - windows[i].onFriendAdded(&windows[i], m, friendnumber, sort); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onFriendAdded != NULL) { + windows[i]->onFriendAdded(windows[i], m, friendnumber, sort); } } @@ -165,11 +149,9 @@ void on_conference_message(Tox *m, uint32_t groupnumber, uint32_t peernumber, To char msg[MAX_STR_SIZE + 1]; length = copy_tox_str(msg, sizeof(msg), (const char *) message, length); - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onGroupMessage != NULL) { - windows[i].onGroupMessage(&windows[i], m, groupnumber, peernumber, type, msg, length); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onGroupMessage != NULL) { + windows[i]->onGroupMessage(windows[i], m, groupnumber, peernumber, type, msg, length); } } } @@ -177,22 +159,18 @@ void on_conference_message(Tox *m, uint32_t groupnumber, uint32_t peernumber, To void on_conference_invite(Tox *m, uint32_t friendnumber, Tox_Conference_Type type, const uint8_t *group_pub_key, size_t length, void *userdata) { - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onGroupInvite != NULL) { - windows[i].onGroupInvite(&windows[i], m, friendnumber, type, (char *) group_pub_key, length); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onGroupInvite != NULL) { + windows[i]->onGroupInvite(windows[i], m, friendnumber, type, (char *) group_pub_key, length); } } } void on_conference_peer_list_changed(Tox *m, uint32_t groupnumber, void *userdata) { - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onGroupNameListChange != NULL) { - windows[i].onGroupNameListChange(&windows[i], m, groupnumber); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onGroupNameListChange != NULL) { + windows[i]->onGroupNameListChange(windows[i], m, groupnumber); } } } @@ -204,11 +182,9 @@ void on_conference_peer_name(Tox *m, uint32_t groupnumber, uint32_t peernumber, length = copy_tox_str(nick, sizeof(nick), (const char *) name, length); filter_str(nick, length); - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onGroupPeerNameChange != NULL) { - windows[i].onGroupPeerNameChange(&windows[i], m, groupnumber, peernumber, nick, length); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onGroupPeerNameChange != NULL) { + windows[i]->onGroupPeerNameChange(windows[i], m, groupnumber, peernumber, nick, length); } } } @@ -219,11 +195,9 @@ void on_conference_title(Tox *m, uint32_t groupnumber, uint32_t peernumber, cons char data[MAX_STR_SIZE + 1]; length = copy_tox_str(data, sizeof(data), (const char *) title, length); - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onGroupTitleChange != NULL) { - windows[i].onGroupTitleChange(&windows[i], m, groupnumber, peernumber, data, length); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onGroupTitleChange != NULL) { + windows[i]->onGroupTitleChange(windows[i], m, groupnumber, peernumber, data, length); } } } @@ -242,11 +216,9 @@ void on_file_chunk_request(Tox *m, uint32_t friendnumber, uint32_t filenumber, u return; } - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onFileChunkRequest != NULL) { - windows[i].onFileChunkRequest(&windows[i], m, friendnumber, filenumber, position, length); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onFileChunkRequest != NULL) { + windows[i]->onFileChunkRequest(windows[i], m, friendnumber, filenumber, position, length); } } } @@ -260,11 +232,9 @@ void on_file_recv_chunk(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint return; } - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onFileRecvChunk != NULL) { - windows[i].onFileRecvChunk(&windows[i], m, friendnumber, filenumber, position, (char *) data, length); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onFileRecvChunk != NULL) { + windows[i]->onFileRecvChunk(windows[i], m, friendnumber, filenumber, position, (char *) data, length); } } } @@ -283,11 +253,9 @@ void on_file_recv_control(Tox *m, uint32_t friendnumber, uint32_t filenumber, To return; } - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onFileControl != NULL) { - windows[i].onFileControl(&windows[i], m, friendnumber, filenumber, control); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onFileControl != NULL) { + windows[i]->onFileControl(windows[i], m, friendnumber, filenumber, control); } } } @@ -301,55 +269,50 @@ void on_file_recv(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint32_t k return; } - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onFileRecv != NULL) { - windows[i].onFileRecv(&windows[i], m, friendnumber, filenumber, file_size, (char *) filename, - filename_length); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onFileRecv != NULL) { + windows[i]->onFileRecv(windows[i], m, friendnumber, filenumber, file_size, (char *) filename, + filename_length); } } } void on_friend_read_receipt(Tox *m, uint32_t friendnumber, uint32_t receipt, void *userdata) { - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onReadReceipt != NULL) { - windows[i].onReadReceipt(&windows[i], m, friendnumber, receipt); + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL && windows[i]->onReadReceipt != NULL) { + windows[i]->onReadReceipt(windows[i], m, friendnumber, receipt); } } } /* CALLBACKS END */ -int add_window(Tox *m, ToxWindow w) +int add_window(Tox *m, ToxWindow *w) { if (LINES < 2) { return -1; } - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; i++) { - if (windows[i].active) { + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; i++) { + if (windows[i] != NULL) { continue; } - w.window = newwin(LINES - 2, COLS, 0, 0); + w->index = i; + w->window = newwin(LINES - 2, COLS, 0, 0); - if (w.window == NULL) { + if (w->window == NULL) { return -1; } #ifdef URXVT_FIX /* Fixes text color problem on some terminals. */ - wbkgd(w.window, COLOR_PAIR(6)); + wbkgd(w->window, COLOR_PAIR(6)); #endif windows[i] = w; - if (w.onInit) { - w.onInit(&w, m); + if (w->onInit) { + w->onInit(w, m); } ++num_active_windows; @@ -360,47 +323,46 @@ int add_window(Tox *m, ToxWindow w) return -1; } -void set_active_window(int index) +void set_active_window_index(uint8_t index) { - if (index < 0 || index >= MAX_WINDOWS_NUM) { - return; + if (index < MAX_WINDOWS_NUM) { + active_window_index = index; } - - active_window = windows + index; } /* Shows next window when tab or back-tab is pressed */ void set_next_window(int ch) { - ToxWindow *end = windows + MAX_WINDOWS_NUM - 1; - ToxWindow *inf = active_window; - - while (true) { - if (ch == user_settings->key_next_tab) { - if (++active_window > end) { - active_window = windows; + if (ch == user_settings->key_next_tab) { + for (uint8_t i = active_window_index + 1; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] != NULL) { + set_active_window_index(i); + return; } - } else if (--active_window < windows) { - active_window = end; } + } else { + uint8_t start = active_window_index == 0 ? MAX_WINDOWS_NUM - 1 : active_window_index - 1; - if (active_window->window) { - return; - } - - if (active_window == inf) { /* infinite loop check */ - exit_toxic_err("failed in set_next_window", FATALERR_INFLOOP); + for (uint8_t i = start; i > 0; --i) { + if (windows[i] != NULL) { + set_active_window_index(i); + return; + } } } + + set_active_window_index(0); } /* Deletes window w and cleans up */ void del_window(ToxWindow *w) { - set_active_window(0); /* Go to prompt screen */ + set_active_window_index(0); + uint8_t idx = w->index; delwin(w->window); - memset(w, 0, sizeof(ToxWindow)); + free(windows[idx]); + windows[idx] = NULL; clear(); refresh(); @@ -409,14 +371,18 @@ void del_window(ToxWindow *w) ToxWindow *init_windows(Tox *m) { - int n_prompt = add_window(m, new_prompt()); + prompt = new_prompt(); + int n_prompt = add_window(m, prompt); - if (n_prompt == -1 || add_window(m, new_friendlist()) == -1) { - exit_toxic_err("failed in init_windows", FATALERR_WININIT); + if (n_prompt < 0) { + exit_toxic_err("add_window() for prompt failed in init_windows", FATALERR_WININIT); } - prompt = &windows[n_prompt]; - active_window = prompt; + if (add_window(m, new_friendlist()) == -1) { + exit_toxic_err("add_window() for friendlist failed in init_windows", FATALERR_WININIT); + } + + set_active_window_index(n_prompt); return prompt; } @@ -436,16 +402,14 @@ void on_window_resize(void) return; } - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (!windows[i].active) { + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] == NULL) { continue; } - ToxWindow *w = &windows[i]; + ToxWindow *w = windows[i]; - if (windows[i].is_friendlist) { + if (windows[i]->is_friendlist) { delwin(w->window); w->window = newwin(y2, x2, 0, 0); continue; @@ -519,8 +483,14 @@ static void draw_bar(void) { int y, x; + ToxWindow *w = windows[active_window_index]; + + if (w == NULL) { + return; + } + // save current cursor position - getyx(active_window->window, y, x); + getyx(w->window, y, x); attron(COLOR_PAIR(BLUE)); mvhline(LINES - 2, 0, '_', COLS); @@ -528,14 +498,12 @@ static void draw_bar(void) move(LINES - 1, 0); - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (!windows[i].active) { + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] == NULL) { continue; } - if (windows + i == active_window) { + if (i == active_window_index) { #ifdef URXVT_FIX attron(A_BOLD | COLOR_PAIR(GREEN)); @@ -545,9 +513,9 @@ static void draw_bar(void) attron(A_BOLD); } - draw_window_tab(&windows[i]); + draw_window_tab(windows[i]); - if (windows + i == active_window) { + if (i == active_window_index) { #ifdef URXVT_FIX attroff(A_BOLD | COLOR_PAIR(GREEN)); @@ -566,7 +534,11 @@ static void draw_bar(void) void draw_active_window(Tox *m) { - ToxWindow *a = active_window; + ToxWindow *a = windows[active_window_index]; + + if (a == NULL) { + return; + } pthread_mutex_lock(&Winthread.lock); a->alert = WINDOW_ALERT_NONE; @@ -619,35 +591,37 @@ void draw_active_window(Tox *m) call at least once per second */ void refresh_inactive_windows(void) { - size_t i; + for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) { + ToxWindow *toxwin = windows[i]; - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - ToxWindow *a = &windows[i]; + if (toxwin == NULL) { + continue; + } - if (a->active && a != active_window && !a->is_friendlist) { + if (i != active_window_index && !toxwin->is_friendlist) { pthread_mutex_lock(&Winthread.lock); - line_info_print(a); + line_info_print(toxwin); pthread_mutex_unlock(&Winthread.lock); } } } -/* returns a pointer to the ToxWindow in the ith index. Returns NULL if no ToxWindow exists */ -ToxWindow *get_window_ptr(int i) +/* Returns a pointer to the ToxWindow in the ith index. + * Returns NULL if no ToxWindow exists. + */ +ToxWindow *get_window_ptr(size_t index) { - ToxWindow *toxwin = NULL; - - if (i >= 0 && i < MAX_WINDOWS_NUM && windows[i].active) { - toxwin = &windows[i]; + if (index >= MAX_WINDOWS_NUM) { + return NULL; } - return toxwin; + return windows[index]; } -/* returns a pointer to the currently open ToxWindow. */ +/* Returns a pointer to the currently active ToxWindow. */ ToxWindow *get_active_window(void) { - return active_window; + return windows[active_window_index]; } void force_refresh(WINDOW *w) @@ -665,17 +639,19 @@ int get_num_active_windows(void) /* destroys all chat and groupchat windows (should only be called on shutdown) */ void kill_all_windows(Tox *m) { - size_t i; + for (uint8_t i = 2; i < MAX_WINDOWS_NUM; ++i) { + if (windows[i] == NULL) { + continue; + } - for (i = 2; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].is_chat) { - kill_chat_window(&windows[i], m); - } else if (windows[i].is_groupchat) { - free_groupchat(&windows[i], m, windows[i].num); + if (windows[i]->is_chat) { + kill_chat_window(windows[i], m); + } else if (windows[i]->is_groupchat) { + free_groupchat(windows[i], m, windows[i]->num); } } /* TODO: use enum instead of magic indices */ - kill_friendlist(&windows[1]); - kill_prompt_window(&windows[0]); + kill_friendlist(windows[1]); + kill_prompt_window(windows[0]); } diff --git a/src/windows.h b/src/windows.h index 914a73d..1c3074a 100644 --- a/src/windows.h +++ b/src/windows.h @@ -36,7 +36,7 @@ #include "toxic.h" -#define MAX_WINDOWS_NUM 32 +#define MAX_WINDOWS_NUM 16 #define MAX_WINDOW_NAME_LENGTH 22 #define CURS_Y_OFFSET 1 /* y-axis cursor offset for chat contexts */ #define CHATBOX_HEIGHT 2 @@ -162,7 +162,7 @@ struct ToxWindow { char name[TOXIC_MAX_NAME_LENGTH + 1]; uint32_t num; /* corresponds to friendnumber in chat windows */ - bool active; + uint8_t index; /* This window's index in the windows array */ int x; bool is_chat; @@ -252,14 +252,14 @@ struct Help { ToxWindow *init_windows(Tox *m); void draw_active_window(Tox *m); -int add_window(Tox *m, ToxWindow w); +int add_window(Tox *m, ToxWindow *w); void del_window(ToxWindow *w); -void set_active_window(int ch); +void set_active_window_index(uint8_t index); int get_num_active_windows(void); void kill_all_windows(Tox *m); /* should only be called on shutdown */ void on_window_resize(void); void force_refresh(WINDOW *w); -ToxWindow *get_window_ptr(int i); +ToxWindow *get_window_ptr(size_t i); ToxWindow *get_active_window(void); /* refresh inactive windows to prevent scrolling bugs.