From 601a88037a1cbdff8f5409163bcdf87850eba5ca Mon Sep 17 00:00:00 2001 From: James Booth Date: Tue, 20 Aug 2013 23:08:21 +0100 Subject: Initial code refactor for growable window list --- Makefile.am | 2 + src/ui/console.c | 155 ++++-------- src/ui/core.c | 712 +++++++++++++++++++++---------------------------------- src/ui/ui.h | 5 - src/ui/window.h | 8 + src/ui/windows.c | 456 +++++++++++++++++++++++++++++++++++ src/ui/windows.h | 51 ++++ 7 files changed, 841 insertions(+), 548 deletions(-) create mode 100644 src/ui/windows.c create mode 100644 src/ui/windows.h diff --git a/Makefile.am b/Makefile.am index f7c3f825..0d384dda 100644 --- a/Makefile.am +++ b/Makefile.am @@ -13,6 +13,7 @@ profanity_SOURCES = \ src/ui/ui.h src/ui/window.c src/ui/window.h src/ui/core.c \ src/ui/titlebar.c src/ui/statusbar.c src/ui/inputwin.c \ src/ui/console.c src/ui/notifier.c src/ui/notifier.h \ + src/ui/windows.c src/ui/windows.h \ src/command/command.h src/command/command.c src/command/history.c \ src/command/history.h src/tools/parser.c \ src/tools/parser.h \ @@ -39,6 +40,7 @@ tests_testsuite_SOURCES = \ src/ui/ui.h src/ui/window.c src/ui/window.h src/ui/core.c \ src/ui/titlebar.c src/ui/statusbar.c src/ui/inputwin.c \ src/ui/console.c src/ui/notifier.c src/ui/notifier.h \ + src/ui/windows.c src/ui/windows.h \ src/command/command.h src/command/command.c src/command/history.c \ src/command/history.h src/tools/parser.c \ src/tools/parser.h \ diff --git a/src/ui/console.c b/src/ui/console.c index ee5ad221..0e5e26af 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -35,6 +35,7 @@ #include "config/theme.h" #include "ui/notifier.h" #include "ui/window.h" +#include "ui/windows.h" #include "ui/ui.h" #include "xmpp/xmpp.h" @@ -57,14 +58,14 @@ void cons_show_time(void) { win_print_time(console, '-'); - ui_console_dirty(); + wins_refresh_console(); } void cons_show_word(const char * const word) { wprintw(console->win, "%s", word); - ui_console_dirty(); + wins_refresh_console(); } void @@ -80,7 +81,7 @@ cons_debug(const char * const msg, ...) g_string_free(fmt_msg, TRUE); va_end(arg); - ui_console_dirty(); + wins_refresh_console(); cons_alert(); ui_current_page_off(); @@ -99,7 +100,7 @@ cons_show(const char * const msg, ...) wprintw(console->win, "%s\n", fmt_msg->str); g_string_free(fmt_msg, TRUE); va_end(arg); - ui_console_dirty(); + wins_refresh_console(); } void @@ -116,7 +117,7 @@ cons_show_error(const char * const msg, ...) g_string_free(fmt_msg, TRUE); va_end(arg); - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -136,7 +137,7 @@ cons_show_typing(const char * const barejid) wprintw(console->win, "!! %s is typing a message...\n", display_usr); wattroff(console->win, COLOUR_TYPING); - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -152,7 +153,7 @@ cons_show_incoming_message(const char * const short_from, const int win_index) wprintw(console->win, "<< incoming from %s (%d)\n", short_from, ui_index); wattroff(console->win, COLOUR_INCOMING); - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -197,7 +198,7 @@ cons_about(void) prefresh(console->win, 0, 0, 1, 0, rows-3, cols-1); - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -225,7 +226,7 @@ cons_check_version(gboolean not_available_msg) } } - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } } @@ -246,91 +247,27 @@ cons_show_login_success(ProfAccount *account) wprintw(console->win, " (priority %d)", accounts_get_priority_for_presence_type(account->name, presence)); wprintw(console->win, ".\n"); - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } void cons_show_wins(void) { - int i = 0; - int count = 0; - int ui_index = 0; - cons_show(""); cons_show("Active windows:"); - win_print_time(console, '-'); - wprintw(console->win, "1: Console\n"); - - for (i = 1; i < NUM_WINS; i++) { - if (windows[i] != NULL) { - count++; - } - } - - if (count != 0) { - for (i = 1; i < NUM_WINS; i++) { - if (windows[i] != NULL) { - ProfWin *window = windows[i]; - win_print_time(console, '-'); - ui_index = i + 1; - if (ui_index == 10) { - ui_index = 0; - } - - switch (window->type) - { - case WIN_CHAT: - wprintw(console->win, "%d: Chat %s", ui_index, window->from); - PContact contact = roster_get_contact(window->from); - - if (contact != NULL) { - if (p_contact_name(contact) != NULL) { - wprintw(console->win, " (%s)", p_contact_name(contact)); - } - wprintw(console->win, " - %s", p_contact_presence(contact)); - } - - if (window->unread > 0) { - wprintw(console->win, ", %d unread", window->unread); - } - - break; - - case WIN_PRIVATE: - wprintw(console->win, "%d: Private %s", ui_index, window->from); - - if (window->unread > 0) { - wprintw(console->win, ", %d unread", window->unread); - } + GSList *window_strings = wins_create_summary(); - break; - - case WIN_MUC: - wprintw(console->win, "%d: Room %s", ui_index, window->from); - - if (window->unread > 0) { - wprintw(console->win, ", %d unread", window->unread); - } - - break; - - case WIN_DUCK: - wprintw(console->win, "%d: DuckDuckGo search", ui_index); - - break; - - default: - break; - } - - wprintw(console->win, "\n"); - } - } + GSList *curr = window_strings; + while (curr != NULL) { + win_print_time(console, '-'); + wprintw(console->win, curr->data); + wprintw(console->win, "\n"); + curr = g_slist_next(curr); } cons_show(""); - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -348,7 +285,7 @@ cons_show_room_invites(GSList *invites) } } - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -480,7 +417,7 @@ cons_show_info(PContact pcontact) ordered_resources = g_list_next(ordered_resources); } - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -554,7 +491,7 @@ cons_show_caps(const char * const contact, Resource *resource) } } - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -580,7 +517,7 @@ cons_show_software_version(const char * const jid, const char * const presence, cons_show("OS : %s", os); } - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -599,6 +536,9 @@ cons_show_received_subs(void) } g_slist_free_full(received, g_free); } + + wins_refresh_console(); + cons_alert(); } void @@ -618,6 +558,9 @@ cons_show_sent_subs(void) } else { cons_show("No pending requests sent."); } + + wins_refresh_console(); + cons_alert(); } void @@ -639,7 +582,7 @@ cons_show_room_list(GSList *rooms, const char * const conference_node) cons_show("No chat rooms at %s", conference_node); } - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -681,7 +624,7 @@ cons_show_disco_info(const char *jid, GSList *identities, GSList *features) features = g_slist_next(features); } - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } } @@ -706,7 +649,7 @@ cons_show_disco_items(GSList *items, const char * const jid) cons_show(""); cons_show("No service discovery items for %s", jid); } - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -720,7 +663,7 @@ cons_show_status(const char * const barejid) } else { cons_show("No such contact \"%s\" in roster.", barejid); } - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -757,7 +700,7 @@ cons_show_room_invite(const char * const invitor, const char * const room, FREE_SET_NULL(display_from); - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -786,7 +729,7 @@ cons_show_account_list(gchar **accounts) cons_show(""); } - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -899,7 +842,7 @@ cons_show_account(ProfAccount *account) } } - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -992,7 +935,7 @@ cons_show_ui_prefs(void) cons_statuses_setting(); cons_titlebar_setting(); - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -1036,7 +979,7 @@ cons_show_desktop_prefs(void) cons_show(""); cons_notify_setting(); - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -1100,7 +1043,7 @@ cons_show_chat_prefs(void) cons_gone_setting(); cons_history_setting(); - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -1137,7 +1080,7 @@ cons_show_log_prefs(void) cons_chlog_setting(); cons_grlog_setting(); - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -1173,7 +1116,7 @@ cons_show_presence_prefs(void) cons_show(""); cons_autoaway_setting(); - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -1218,7 +1161,7 @@ cons_show_connection_prefs(void) cons_reconnect_setting(); cons_autoping_setting(); - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -1237,7 +1180,7 @@ cons_show_themes(GSList *themes) } } - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -1258,7 +1201,7 @@ cons_prefs(void) cons_show_connection_prefs(); cons_show(""); - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -1281,7 +1224,7 @@ cons_help(void) cons_show("/help [command] - Detailed help on a specific command."); cons_show(""); - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -1303,7 +1246,7 @@ cons_navigation_help(void) cons_show("PAGE UP, PAGE DOWN : Page the main window."); cons_show(""); - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -1394,7 +1337,7 @@ cons_show_roster_group(const char * const group, GSList *list) } _show_roster_contacts(list, FALSE); - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -1405,7 +1348,7 @@ cons_show_roster(GSList *list) cons_show("Roster:"); _show_roster_contacts(list, TRUE); - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } @@ -1423,7 +1366,7 @@ cons_show_contacts(GSList *list) curr = g_slist_next(curr); } - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } diff --git a/src/ui/core.c b/src/ui/core.c index 83839952..37d0d35d 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -46,19 +46,9 @@ #include "ui/notifier.h" #include "ui/ui.h" #include "ui/window.h" +#include "ui/windows.h" #include "xmpp/xmpp.h" -// the window currently being displayed -static int current_index = 0; -static ProfWin *current; -static ProfWin *console; - -// current window state -static gboolean current_win_dirty; - -// max columns for main windows, never resize below -static int max_cols = 0; - static char *win_title; #ifdef HAVE_LIBXSS @@ -67,10 +57,6 @@ static Display *display; static GTimer *ui_idle_time; -static void _set_current(int index); -static int _find_prof_win_index(const char * const contact); -static int _new_prof_win(const char * const contact, win_type_t type); -static void _current_window_refresh(void); static void _win_show_user(WINDOW *win, const char * const user, const int colour); static void _win_show_message(WINDOW *win, const char * const message); static void _win_show_error_msg(WINDOW *win, const char * const message); @@ -80,11 +66,9 @@ static void _show_status_string(ProfWin *window, const char * const from, const char * const default_show); static void _win_handle_switch(const wint_t * const ch); static void _win_handle_page(const wint_t * const ch); -static void _win_resize_all(void); static void _win_show_history(WINDOW *win, int win_index, const char * const contact); static void _ui_draw_win_title(void); -gboolean _tidy(void); void ui_init(void) @@ -103,43 +87,25 @@ ui_init(void) create_status_bar(); status_bar_active(0); create_input_window(); - max_cols = getmaxx(stdscr); - windows[0] = cons_create(); - console = windows[0]; - current = console; + wins_init(); cons_about(); notifier_init(); #ifdef HAVE_LIBXSS display = XOpenDisplay(0); #endif ui_idle_time = g_timer_new(); - current_win_dirty = TRUE; + wins_refresh_current(); } void ui_refresh(void) { _ui_draw_win_title(); - title_bar_refresh(); status_bar_refresh(); - - if (current_win_dirty) { - _current_window_refresh(); - current_win_dirty = FALSE; - } - inp_put_back(); } -void -ui_console_dirty(void) -{ - if (ui_current_win_type() == WIN_CONSOLE) { - current_win_dirty = TRUE; - } -} - unsigned long ui_get_idle_time(void) { @@ -178,9 +144,9 @@ ui_resize(const int ch, const char * const input, const int size) log_info("Resizing UI"); title_bar_resize(); status_bar_resize(); - _win_resize_all(); + wins_resize_all(); inp_win_resize(input, size); - current_win_dirty = TRUE; + wins_refresh_current(); } void @@ -196,57 +162,44 @@ ui_load_colours(void) gboolean ui_windows_full(void) { - int i; - for (i = 1; i < NUM_WINS; i++) { - if (windows[i] == NULL) { - return FALSE; - } - } - - return TRUE; + return wins_full(); } gboolean ui_win_exists(int index) { - return (windows[index] != NULL); + ProfWin *window = wins_get_by_num(index); + return (window != NULL); } gboolean ui_duck_exists(void) { - int i; - for (i = 1; i < NUM_WINS; i++) { - if (windows[i] != NULL) { - if (windows[i]->type == WIN_DUCK) - return TRUE; - } - } - - return FALSE; + return wins_duck_exists(); } void ui_contact_typing(const char * const barejid) { - int win_index = _find_prof_win_index(barejid); + ProfWin *window = wins_get_by_recipient(barejid); if (prefs_get_boolean(PREF_INTYPE)) { // no chat window for user - if (win_index == NUM_WINS) { + if (window == NULL) { cons_show_typing(barejid); // have chat window but not currently in it - } else if (win_index != current_index) { + } else if (!wins_is_current(window)) { cons_show_typing(barejid); - current_win_dirty = TRUE; + wins_refresh_current(); // in chat window with user } else { title_bar_set_typing(TRUE); title_bar_draw(); - status_bar_active(win_index); - current_win_dirty = TRUE; + int num = wins_get_num(window); + status_bar_active(num); + wins_refresh_current(); } } @@ -265,26 +218,29 @@ ui_contact_typing(const char * const barejid) void ui_idle(void) { - int i; + GSList *recipients = wins_get_chat_recipients(); + GSList *curr = recipients; + while (curr != NULL) { + char *recipient = curr->data; + chat_session_no_activity(recipient); + + if (chat_session_is_gone(recipient) && + !chat_session_get_sent(recipient)) { + message_send_gone(recipient); + } else if (chat_session_is_inactive(recipient) && + !chat_session_get_sent(recipient)) { + message_send_inactive(recipient); + } else if (prefs_get_boolean(PREF_OUTTYPE) && + chat_session_is_paused(recipient) && + !chat_session_get_sent(recipient)) { + message_send_paused(recipient); + } - // loop through regular chat windows and update states - for (i = 1; i < NUM_WINS; i++) { - if ((windows[i] != NULL) && (windows[i]->type == WIN_CHAT)) { - char *recipient = windows[i]->from; - chat_session_no_activity(recipient); + curr = g_slist_next(curr); + } - if (chat_session_is_gone(recipient) && - !chat_session_get_sent(recipient)) { - message_send_gone(recipient); - } else if (chat_session_is_inactive(recipient) && - !chat_session_get_sent(recipient)) { - message_send_inactive(recipient); - } else if (prefs_get_boolean(PREF_OUTTYPE) && - chat_session_is_paused(recipient) && - !chat_session_get_sent(recipient)) { - message_send_paused(recipient); - } - } + if (recipients != NULL) { + g_slist_free(recipients); } } @@ -312,14 +268,16 @@ ui_incoming_msg(const char * const from, const char * const message, } } - int win_index = _find_prof_win_index(from); - if (win_index == NUM_WINS) { - win_index = _new_prof_win(from, win_type); + ProfWin *window = wins_get_by_recipient(from); + if (window == NULL) { + window = wins_new(from, win_type); win_created = TRUE; } + int num = wins_get_num(window); // no spare windows left - if (win_index == 0) { + if (wins_full()) { + ProfWin *console = wins_get_console(); if (tv_stamp == NULL) { win_print_time(console, '-'); } else { @@ -345,18 +303,16 @@ ui_incoming_msg(const char * const from, const char * const message, cons_show("Windows all used, close a window to respond."); - if (current_index == 0) { - current_win_dirty = TRUE; + if (wins_get_current_num() == 0) { + wins_refresh_current(); } else { status_bar_new(0); } // window found or created } else { - ProfWin *window = windows[win_index]; - // currently viewing chat window with sender - if (win_index == current_index) { + if (wins_is_current(window)) { if (tv_stamp == NULL) { win_print_time(window, '-'); } else { @@ -381,19 +337,19 @@ ui_incoming_msg(const char * const from, const char * const message, } title_bar_set_typing(FALSE); title_bar_draw(); - status_bar_active(win_index); - current_win_dirty = TRUE; + status_bar_active(num); + wins_refresh_current(); // not currently viewing chat window with sender } else { - status_bar_new(win_index); - cons_show_incoming_message(display_from, win_index); + status_bar_new(num); + cons_show_incoming_message(display_from, num); if (prefs_get_boolean(PREF_FLASH)) flash(); - windows[win_index]->unread++; + window->unread++; if (prefs_get_boolean(PREF_CHLOG) && prefs_get_boolean(PREF_HISTORY)) { - _win_show_history(window->win, win_index, from); + _win_show_history(window->win, num, from); } if (tv_stamp == NULL) { @@ -428,7 +384,7 @@ ui_incoming_msg(const char * const from, const char * const message, } } - int ui_index = win_index + 1; + int ui_index = num + 1; if (ui_index == 10) { ui_index = 0; } @@ -503,12 +459,12 @@ ui_contact_online(const char * const barejid, const char * const resource, g_string_append(display_str, ")"); } + ProfWin *console = wins_get_console(); _show_status_string(console, display_str->str, show, status, last_activity, "++", "online"); - int win_index = _find_prof_win_index(barejid); - if (win_index != NUM_WINS) { - ProfWin *window = windows[win_index]; + ProfWin *window = wins_get_by_recipient(barejid); + if (window != NULL) { _show_status_string(window, display_str->str, show, status, last_activity, "++", "online"); } @@ -516,8 +472,8 @@ ui_contact_online(const char * const barejid, const char * const resource, jid_destroy(jid); g_string_free(display_str, TRUE); - if (win_index == current_index) - current_win_dirty = TRUE; + if (wins_is_current(window)) + wins_refresh_current(); } void @@ -542,12 +498,12 @@ ui_contact_offline(const char * const from, const char * const show, g_string_append(display_str, ")"); } + ProfWin *console = wins_get_console(); _show_status_string(console, display_str->str, show, status, NULL, "--", "offline"); - int win_index = _find_prof_win_index(jidp->barejid); - if (win_index != NUM_WINS) { - ProfWin *window = windows[win_index]; + ProfWin *window = wins_get_by_recipient(jidp->barejid); + if (window != NULL) { _show_status_string(window, display_str->str, show, status, NULL, "--", "offline"); } @@ -555,30 +511,14 @@ ui_contact_offline(const char * const from, const char * const show, jid_destroy(jidp); g_string_free(display_str, TRUE); - if (win_index == current_index) - current_win_dirty = TRUE; + if (wins_is_current(window)) + wins_refresh_current(); } void ui_disconnected(void) { - int i; - // show message in all active chats - for (i = 1; i < NUM_WINS; i++) { - if (windows[i] != NULL) { - ProfWin *window = windows[i]; - win_print_time(window, '-'); - wattron(window->win, COLOUR_ERROR); - wprintw(window->win, "%s\n", "Lost connection."); - wattroff(window->win, COLOUR_ERROR); - - // if current win, set current_win_dirty - if (i == current_index) { - current_win_dirty = TRUE; - } - } - } - + wins_lost_connection(); title_bar_set_status(CONTACT_OFFLINE); status_bar_clear_message(); status_bar_refresh(); @@ -622,80 +562,66 @@ void ui_switch_win(const int i) { ui_current_page_off(); - if (windows[i] != NULL) { - current_index = i; - current = windows[current_index]; + ProfWin *new_current = wins_get_by_num(i); + if (new_current != NULL) { + wins_set_current_by_num(i); ui_current_page_off(); - current->unread = 0; + new_current->unread = 0; if (i == 0) { title_bar_title(); status_bar_active(0); } else { - PContact contact = roster_get_contact(current->from); + PContact contact = roster_get_contact(new_current->from); if (contact != NULL) { if (p_contact_name(contact) != NULL) { title_bar_set_recipient(p_contact_name(contact)); } else { - title_bar_set_recipient(current->from); + title_bar_set_recipient(new_current->from); } } else { - title_bar_set_recipient(current->from); + title_bar_set_recipient(new_current->from); } title_bar_draw();; status_bar_active(i); } + wins_refresh_current(); } - current_win_dirty = TRUE; } void ui_clear_current(void) { - werase(current->win); - current_win_dirty = TRUE; + wins_clear_current(); } void ui_close_current(void) { - win_free(current); - windows[current_index] = NULL; - - // set it as inactive in the status bar + int current_index = wins_get_current_num(); + wins_close_current(); status_bar_inactive(current_index); - - // go back to console window - _set_current(0); status_bar_active(0); title_bar_title(); - - current_win_dirty = TRUE; } void ui_close_win(int index) { - win_free(windows[index]); - windows[index] = NULL; + wins_close_by_num(index); status_bar_inactive(index); - - if (index == current_index) { - _set_current(0); - } - status_bar_active(0); title_bar_title(); - current_win_dirty = TRUE; + wins_refresh_current(); } void ui_tidy_wins(void) { - gboolean tidied = _tidy(); + gboolean tidied = wins_tidy(); if (tidied) { cons_show("Windows tidied."); @@ -708,23 +634,40 @@ void ui_prune_wins(void) { jabber_conn_status_t conn_status = jabber_get_connection_status(); - int curr = 0; gboolean pruned = FALSE; - for (curr = 1; curr <= 9; curr++) { - if (ui_win_exists(curr)) { - win_type_t win_type = windows[curr]->type; - if ((ui_win_unread(curr) == 0) && (win_type != WIN_MUC)) { - if (conn_status == JABBER_CONNECTED) { - ui_close_connected_win(curr); + GSList *recipients = wins_get_prune_recipients(); + if (recipients != NULL) { + pruned = TRUE; + } + GSList *curr = recipients; + while (curr != NULL) { + char *recipient = curr->data; + + if (conn_status == JABBER_CONNECTED) { + if (prefs_get_boolean(PREF_STATES)) { + + // send chat state before closing + if (chat_session_get_recipient_supports(recipient)) { + chat_session_set_gone(recipient); + message_send_gone(recipient); + chat_session_end(recipient); } - ui_close_win(curr); - pruned = TRUE; } } + + ProfWin *window = wins_get_by_recipient(recipient); + int num = wins_get_num(window); + ui_close_win(num); + + curr = g_slist_next(curr); + } + + if (recipients != NULL) { + g_slist_free(recipients); } - _tidy(); + wins_tidy(); if (pruned) { cons_show("Windows pruned."); } else { @@ -735,36 +678,41 @@ ui_prune_wins(void) win_type_t ui_current_win_type(void) { + ProfWin *current = wins_get_current(); return current->type; } int ui_current_win_index(void) { - return current_index; + return wins_get_current_num(); } win_type_t ui_win_type(int index) { - return windows[index]->type; + ProfWin *window = wins_get_by_num(index); + return window->type; } char * ui_recipient(int index) { - return strdup(windows[index]->from); + ProfWin *window = wins_get_by_num(index); + return window->from; } char * ui_current_recipient(void) { - return strdup(current->from); + ProfWin *current = wins_get_current(); + return current->from; } void ui_current_print_line(const char * const msg, ...) { + ProfWin *current = wins_get_current(); va_list arg; va_start(arg, msg); GString *fmt_msg = g_string_new(NULL); @@ -774,56 +722,51 @@ ui_current_print_line(const char * const msg, ...) g_string_free(fmt_msg, TRUE); va_end(arg); - current_win_dirty = TRUE; + wins_refresh_current(); } void ui_current_error_line(const char * const msg) { + ProfWin *current = wins_get_current(); win_print_time(current, '-'); wattron(current->win, COLOUR_ERROR); wprintw(current->win, "%s\n", msg); wattroff(current->win, COLOUR_ERROR); - current_win_dirty = TRUE; + wins_refresh_current(); } void ui_current_page_off(void) { - int rows = getmaxy(stdscr); - ProfWin *window = windows[current_index]; - - window->paged = 0; - - int y = getcury(window->win); + ProfWin *current = wins_get_current(); + current->paged = 0; + int rows = getmaxy(stdscr); + int y = getcury(current->win); int size = rows - 3; - window->y_pos = y - (size - 1); - if (window->y_pos < 0) - window->y_pos = 0; + current->y_pos = y - (size - 1); + if (current->y_pos < 0) { + current->y_pos = 0; + } - current_win_dirty = TRUE; + wins_refresh_current(); } void ui_print_error_from_recipient(const char * const from, const char *err_msg) { - int win_index; - ProfWin *window; - if (from == NULL || err_msg == NULL) return; - win_index = _find_prof_win_index(from); - // chat window exists - if (win_index < NUM_WINS) { - window = windows[win_index]; + ProfWin *window = wins_get_by_recipient(from); + if (window != NULL) { win_print_time(window, '-'); _win_show_error_msg(window->win, err_msg); - if (win_index == current_index) { - current_win_dirty = TRUE; + if (wins_is_current(window)) { + wins_refresh_current(); } } } @@ -831,8 +774,7 @@ ui_print_error_from_recipient(const char * const from, const char *err_msg) void ui_print_system_msg_from_recipient(const char * const from, const char *message) { - int win_index; - ProfWin *window; + int num = 0; char from_cpy[strlen(from) + 1]; char *bare_jid; @@ -842,29 +784,31 @@ ui_print_system_msg_from_recipient(const char * const from, const char *message) strcpy(from_cpy, from); bare_jid = strtok(from_cpy, "/"); - win_index = _find_prof_win_index(bare_jid); - if (win_index == NUM_WINS) { - win_index = _new_prof_win(bare_jid, WIN_CHAT); - status_bar_active(win_index); - current_win_dirty = TRUE; + ProfWin *window = wins_get_by_recipient(bare_jid); + if (window == NULL) { + window = wins_new(bare_jid, WIN_CHAT); + if (window != NULL) { + num = wins_get_num(window); + status_bar_active(num); + } else { + num = 0; + window = wins_get_console(); + status_bar_active(0); + } } - window = windows[win_index]; win_print_time(window, '-'); wprintw(window->win, "*%s %s\n", bare_jid, message); // this is the current window - if (win_index == current_index) { - current_win_dirty = TRUE; + if (wins_is_current(window)) { + wins_refresh_current(); } } void ui_recipient_gone(const char * const barejid) { - int win_index; - ProfWin *window; - if (barejid == NULL) return; @@ -876,18 +820,16 @@ ui_recipient_gone(const char * const barejid) display_usr = barejid; } - win_index = _find_prof_win_index(barejid); - // chat window exists - if (win_index < NUM_WINS) { - window = windows[win_index]; + ProfWin *window = wins_get_by_recipient(barejid); + if (window != NULL) { win_print_time(window, '!'); wattron(window->win, COLOUR_GONE); wprintw(window->win, "<- %s ", display_usr); wprintw(window->win, "has left the conversation."); wprintw(window->win, "\n"); wattroff(window->win, COLOUR_GONE); - if (win_index == current_index) { - current_win_dirty = TRUE; + if (wins_is_current(window)) { + wins_refresh_current(); } } } @@ -897,25 +839,24 @@ ui_new_chat_win(const char * const to) { // if the contact is offline, show a message PContact contact = roster_get_contact(to); - int win_index = _find_prof_win_index(to); - ProfWin *window = NULL; + ProfWin *window = wins_get_by_recipient(to); + int num = 0; // create new window - if (win_index == NUM_WINS) { + if (window == NULL) { Jid *jid = jid_create(to); if (muc_room_is_active(jid)) { - win_index = _new_prof_win(to, WIN_PRIVATE); + window = wins_new(to, WIN_PRIVATE); } else { - win_index = _new_prof_win(to, WIN_CHAT); + window = wins_new(to, WIN_CHAT); } jid_destroy(jid); - - window = windows[win_index]; + num = wins_get_num(window); if (prefs_get_boolean(PREF_CHLOG) && prefs_get_boolean(PREF_HISTORY)) { - _win_show_history(window->win, win_index, to); + _win_show_history(window->win, num, to); } if (contact != NULL) { @@ -925,71 +866,71 @@ ui_new_chat_win(const char * const to) _show_status_string(window, to, show, status, NULL, "--", "offline"); } } - - // use existing window } else { - window = windows[win_index]; + num = wins_get_num(window); } - ui_switch_win(win_index); + ui_switch_win(num); } void ui_create_duck_win(void) { - int win_index = _new_prof_win("DuckDuckGo search", WIN_DUCK); - ui_switch_win(win_index); - win_print_time(windows[win_index], '-'); - wprintw(windows[win_index]->win, "Type ':help' to find out more.\n"); + ProfWin *window = wins_new("DuckDuckGo search", WIN_DUCK); + int num = wins_get_num(window); + ui_switch_win(num); + win_print_time(window, '-'); + wprintw(window->win, "Type ':help' to find out more.\n"); } void ui_open_duck_win(void) { - int win_index = _find_prof_win_index("DuckDuckGo search"); - if (win_index != NUM_WINS) { - ui_switch_win(win_index); + ProfWin *window = wins_get_by_recipient("DuckDuckGo search"); + if (window != NULL) { + int num = wins_get_num(window); + ui_switch_win(num); } } void ui_duck(const char * const query) { - int win_index = _find_prof_win_index("DuckDuckGo search"); - if (win_index != NUM_WINS) { - win_print_time(windows[win_index], '-'); - wprintw(windows[win_index]->win, "\n"); - win_print_time(windows[win_index], '-'); - wattron(windows[win_index]->win, COLOUR_ME); - wprintw(windows[win_index]->win, "Query : "); - wattroff(windows[win_index]->win, COLOUR_ME); - wprintw(windows[win_index]->win, query); - wprintw(windows[win_index]->win, "\n"); + ProfWin *window = wins_get_by_recipient("DuckDuckGo search"); + if (window != NULL) { + win_print_time(window, '-'); + wprintw(window->win, "\n"); + win_print_time(window, '-'); + wattron(window->win, COLOUR_ME); + wprintw(window->win, "Query : "); + wattroff(window->win, COLOUR_ME); + wprintw(window->win, query); + wprintw(window->win, "\n"); } } void ui_duck_result(const char * const result) { - int win_index = _find_prof_win_index("DuckDuckGo search"); + ProfWin *window = wins_get_by_recipient("DuckDuckGo search"); - if (win_index != NUM_WINS) { - win_print_time(windows[win_index], '-'); - wattron(windows[win_index]->win, COLOUR_THEM); - wprintw(windows[win_index]->win, "Result : "); - wattroff(windows[win_index]->win, COLOUR_THEM); + if (window != NULL) { + win_print_time(window, '-'); + wattron(window->win, COLOUR_THEM); + wprintw(window->win, "Result : "); + wattroff(window->win, COLOUR_THEM); glong offset = 0; while (offset < g_utf8_strlen(result, -1)) { gchar *ptr = g_utf8_offset_to_pointer(result, offset); gunichar unichar = g_utf8_get_char(ptr); if (unichar == '\n') { - wprintw(windows[win_index]->win, "\n"); - win_print_time(windows[win_index], '-'); + wprintw(window->win, "\n"); + win_print_time(window, '-'); } else { gchar *string = g_ucs4_to_utf8(&unichar, 1, NULL, NULL, NULL); if (string != NULL) { - wprintw(windows[win_index]->win, string); + wprintw(window->win, string); g_free(string); } } @@ -997,7 +938,7 @@ ui_duck_result(const char * const result) offset++; } - wprintw(windows[win_index]->win, "\n"); + wprintw(window->win, "\n"); } } @@ -1005,27 +946,25 @@ void ui_outgoing_msg(const char * const from, const char * const to, const char * const message) { - // if the contact is offline, show a message PContact contact = roster_get_contact(to); - int win_index = _find_prof_win_index(to); - ProfWin *window = NULL; + ProfWin *window = wins_get_by_recipient(to); + int num = 0; // create new window - if (win_index == NUM_WINS) { + if (window == NULL) { Jid *jid = jid_create(to); if (muc_room_is_active(jid)) { - win_index = _new_prof_win(to, WIN_PRIVATE); + window = wins_new(to, WIN_PRIVATE); } else { - win_index = _new_prof_win(to, WIN_CHAT); + window = wins_new(to, WIN_CHAT); } jid_destroy(jid); - - window = windows[win_index]; + num = wins_get_num(window); if (prefs_get_boolean(PREF_CHLOG) && prefs_get_boolean(PREF_HISTORY)) { - _win_show_history(window->win, win_index, to); + _win_show_history(window->win, num, to); } if (contact != NULL) { @@ -1038,7 +977,7 @@ ui_outgoing_msg(const char * const from, const char * const to, // use existing window } else { - window = windows[win_index]; + num = wins_get_num(window); } win_print_time(window, '-'); @@ -1052,27 +991,28 @@ ui_outgoing_msg(const char * const from, const char * const to, _win_show_user(window->win, from, 0); _win_show_message(window->win, message); } - ui_switch_win(win_index); + ui_switch_win(num); } void ui_room_join(Jid *jid) { - int win_index = _find_prof_win_index(jid->barejid); + ProfWin *window = wins_get_by_recipient(jid->barejid); + int num = 0; // create new window - if (win_index == NUM_WINS) { - win_index = _new_prof_win(jid->barejid, WIN_MUC); + if (window == NULL) { + window = wins_new(jid->barejid, WIN_MUC); } - ui_switch_win(win_index); + num = wins_get_num(window); + ui_switch_win(num); } void ui_room_roster(const char * const room, GList *roster, const char * const presence) { - int win_index = _find_prof_win_index(room); - ProfWin *window = windows[win_index]; + ProfWin *window = wins_get_by_recipient(room); win_print_time(window, '!'); if ((roster == NULL) || (g_list_length(roster) == 0)) { @@ -1119,118 +1059,120 @@ ui_room_roster(const char * const room, GList *roster, const char * const presen wattroff(window->win, COLOUR_ONLINE); } - if (win_index == current_index) - current_win_dirty = TRUE; + if (wins_is_current(window)) { + wins_refresh_current(); + } } void ui_room_member_offline(const char * const room, const char * const nick) { - int win_index = _find_prof_win_index(room); - ProfWin *window = windows[win_index]; + ProfWin *window = wins_get_by_recipient(room); win_print_time(window, '!'); wattron(window->win, COLOUR_OFFLINE); wprintw(window->win, "<- %s has left the room.\n", nick); wattroff(window->win, COLOUR_OFFLINE); - if (win_index == current_index) - current_win_dirty = TRUE; + if (wins_is_current(window)) { + wins_refresh_current(); + } } void ui_room_member_online(const char * const room, const char * const nick, const char * const show, const char * const status) { - int win_index = _find_prof_win_index(room); - ProfWin *window = windows[win_index]; + ProfWin *window = wins_get_by_recipient(room); win_print_time(window, '!'); wattron(window->win, COLOUR_ONLINE); wprintw(window->win, "-> %s has joined the room.\n", nick); wattroff(window->win, COLOUR_ONLINE); - if (win_index == current_index) - current_win_dirty = TRUE; + if (wins_is_current(window)) { + wins_refresh_current(); + } } void ui_room_member_presence(const char * const room, const char * const nick, const char * const show, const char * const status) { - int win_index = _find_prof_win_index(room); - if (win_index != NUM_WINS) { - ProfWin *window = windows[win_index]; + ProfWin *window = wins_get_by_recipient(room); + + if (window != NULL) { _show_status_string(window, nick, show, status, NULL, "++", "online"); } - if (win_index == current_index) - current_win_dirty = TRUE; + if (wins_is_current(window)) { + wins_refresh_current(); + } } void ui_room_member_nick_change(const char * const room, const char * const old_nick, const char * const nick) { - int win_index = _find_prof_win_index(room); - ProfWin *window = windows[win_index]; + ProfWin *window = wins_get_by_recipient(room); win_print_time(window, '!'); wattron(window->win, COLOUR_THEM); wprintw(window->win, "** %s is now known as %s\n", old_nick, nick); wattroff(window->win, COLOUR_THEM); - if (win_index == current_index) - current_win_dirty = TRUE; + if (wins_is_current(window)) { + wins_refresh_current(); + } } void ui_room_nick_change(const char * const room, const char * const nick) { - int win_index = _find_prof_win_index(room); - ProfWin *window = windows[win_index]; + ProfWin *window = wins_get_by_recipient(room); win_print_time(window, '!'); wattron(window->win, COLOUR_ME); wprintw(window->win, "** You are now known as %s\n", nick); wattroff(window->win, COLOUR_ME); - if (win_index == current_index) - current_win_dirty = TRUE; + if (wins_is_current(window)) { + wins_refresh_current(); + } } void ui_room_history(const char * const room_jid, const char * const nick, GTimeVal tv_stamp, const char * const message) { - int win_index = _find_prof_win_index(room_jid); - WINDOW *win = windows[win_index]->win; + ProfWin *window = wins_get_by_recipient(room_jid); GDateTime *time = g_date_time_new_from_timeval_utc(&tv_stamp); gchar *date_fmt = g_date_time_format(time, "%H:%M:%S"); - wprintw(win, "%s - ", date_fmt); + wprintw(window->win, "%s - ", date_fmt); g_date_time_unref(time); g_free(date_fmt); if (strncmp(message, "/me ", 4) == 0) { - wprintw(win, "*%s ", nick); - waddstr(win, message + 4); - wprintw(win, "\n"); + wprintw(window->win, "*%s ", nick); + waddstr(window->win, message + 4); + wprintw(window->win, "\n"); } else { - wprintw(win, "%s: ", nick); - _win_show_message(win, message); + wprintw(window->win, "%s: ", nick); + _win_show_message(window->win, message); } - if (win_index == current_index) - current_win_dirty = TRUE; + if (wins_is_current(window)) { + wins_refresh_current(); + } } void ui_room_message(const char * const room_jid, const char * const nick, const char * const message) { - int win_index = _find_prof_win_index(room_jid); - ProfWin *window = windows[win_index]; + ProfWin *window = wins_get_by_recipient(room_jid); + int num = wins_get_num(window); win_print_time(window, '-'); if (strcmp(nick, muc_get_room_nick(room_jid)) != 0) { @@ -1259,16 +1201,16 @@ ui_room_message(const char * const room_jid, const char * const nick, } // currently in groupchat window - if (win_index == current_index) { - status_bar_active(win_index); - current_win_dirty = TRUE; + if (wins_is_current(window)) { + status_bar_active(num); + wins_refresh_current(); // not currenlty on groupchat window } else { - status_bar_new(win_index); - cons_show_incoming_message(nick, win_index); - if (current_index == 0) { - current_win_dirty = TRUE; + status_bar_new(num); + cons_show_incoming_message(nick, num); + if (wins_get_current_num() == 0) { + wins_refresh_current(); } if (strcmp(nick, muc_get_room_nick(room_jid)) != 0) { @@ -1277,10 +1219,10 @@ ui_room_message(const char * const room_jid, const char * const nick, } } - windows[win_index]->unread++; + window->unread++; } - int ui_index = win_index + 1; + int ui_index = num + 1; if (ui_index == 10) { ui_index = 0; } @@ -1300,8 +1242,8 @@ ui_room_message(const char * const room_jid, const char * const nick, void ui_room_subject(const char * const room_jid, const char * const subject) { - int win_index = _find_prof_win_index(room_jid); - ProfWin *window = windows[win_index]; + ProfWin *window = wins_get_by_recipient(room_jid); + int num = wins_get_num(window); win_print_time(window, '!'); wattron(window->win, COLOUR_ROOMINFO); @@ -1310,21 +1252,21 @@ ui_room_subject(const char * const room_jid, const char * const subject) wprintw(window->win, "%s\n", subject); // currently in groupchat window - if (win_index == current_index) { - status_bar_active(win_index); - current_win_dirty = TRUE; + if (wins_is_current(window)) { + status_bar_active(num); + wins_refresh_current(); // not currenlty on groupchat window } else { - status_bar_new(win_index); + status_bar_new(num); } } void ui_room_broadcast(const char * const room_jid, const char * const message) { - int win_index = _find_prof_win_index(room_jid); - ProfWin *window = windows[win_index]; + ProfWin *window = wins_get_by_recipient(room_jid); + int num = wins_get_num(window); win_print_time(window, '!'); wattron(window->win, COLOUR_ROOMINFO); @@ -1333,13 +1275,13 @@ ui_room_broadcast(const char * const room_jid, const char * const message) wprintw(window->win, "%s\n", message); // currently in groupchat window - if (win_index == current_index) { - status_bar_active(win_index); - current_win_dirty = TRUE; + if (wins_is_current(window)) { + status_bar_active(num); + wins_refresh_current(); // not currenlty on groupchat window } else { - status_bar_new(win_index); + status_bar_new(num); } } @@ -1348,6 +1290,7 @@ ui_status(void) { char *recipient = ui_current_recipient(); PContact pcontact = roster_get_contact(recipient); + ProfWin *current = wins_get_current(); if (pcontact != NULL) { win_show_contact(current, pcontact); @@ -1360,8 +1303,8 @@ void ui_status_private(void) { Jid *jid = jid_create(ui_current_recipient()); - PContact pcontact = muc_get_participant(jid->barejid, jid->resourcepart); + ProfWin *current = wins_get_current(); if (pcontact != NULL) { win_show_contact(current, pcontact); @@ -1376,6 +1319,7 @@ void ui_status_room(const char * const contact) { PContact pcontact = muc_get_participant(ui_current_recipient(), contact); + ProfWin *current = wins_get_current(); if (pcontact != NULL) { win_show_contact(current, pcontact); @@ -1387,21 +1331,15 @@ ui_status_room(const char * const contact) gint ui_unread(void) { - int i; - gint result = 0; - for (i = 0; i < NUM_WINS; i++) { - if (windows[i] != NULL) { - result += windows[i]->unread; - } - } - return result; + return wins_get_total_unread(); } int ui_win_unread(int index) { - if (windows[index] != NULL) { - return windows[index]->unread; + ProfWin *window = wins_get_by_num(index); + if (window != NULL) { + return window->unread; } else { return 0; } @@ -1449,38 +1387,6 @@ _ui_draw_win_title(void) } } -static int -_find_prof_win_index(const char * const contact) -{ - int i; - for (i = 1; i < NUM_WINS; i++) { - if ((windows[i] != NULL) && (strcmp(windows[i]->from, contact) == 0)) { - break; - } - } - - return i; -} - -static int -_new_prof_win(const char * const contact, win_type_t type) -{ - int i; - for (i = 1; i < NUM_WINS; i++) { - if (windows[i] == NULL) { - break; - } - } - - if (i != NUM_WINS) { - int cols = getmaxx(stdscr); - windows[i] = win_create(contact, cols, type); - return i; - } else { - return 0; - } -} - static void _win_show_user(WINDOW *win, const char * const user, const int colour) { @@ -1510,36 +1416,6 @@ _win_show_error_msg(WINDOW *win, const char * const message) wattroff(win, COLOUR_ERROR); } -static void -_current_window_refresh(void) -{ - int rows, cols; - getmaxyx(stdscr, rows, cols); - - prefresh(current->win, current->y_pos, 0, 1, 0, rows-3, cols-1); -} - -void -_win_resize_all(void) -{ - int rows, cols; - getmaxyx(stdscr, rows, cols); - - // only make the pads bigger, to avoid data loss on cropping - if (cols > max_cols) { - max_cols = cols; - - int i; - for (i = 0; i < NUM_WINS; i++) { - if (windows[i] != NULL) { - wresize(windows[i]->win, PAD_SIZE, cols); - } - } - } - - prefresh(current->win, current->y_pos, 0, 1, 0, rows-3, cols-1); -} - static void _show_status_string(ProfWin *window, const char * const from, const char * const show, const char * const status, @@ -1655,6 +1531,7 @@ _win_handle_switch(const wint_t * const ch) static void _win_handle_page(const wint_t * const ch) { + ProfWin *current = wins_get_current(); int rows = getmaxy(stdscr); int y = getcury(current->win); @@ -1683,7 +1560,7 @@ _win_handle_page(const wint_t * const ch) *page_start = y - page_space; current->paged = 1; - current_win_dirty = TRUE; + wins_refresh_current(); } else if (mouse_event.bstate & BUTTON4_PRESSED) { // mouse wheel up *page_start -= 4; @@ -1692,7 +1569,7 @@ _win_handle_page(const wint_t * const ch) *page_start = 0; current->paged = 1; - current_win_dirty = TRUE; + wins_refresh_current(); } } } @@ -1707,7 +1584,7 @@ _win_handle_page(const wint_t * const ch) *page_start = 0; current->paged = 1; - current_win_dirty = TRUE; + wins_refresh_current(); // page down } else if (*ch == KEY_NPAGE) { @@ -1722,14 +1599,15 @@ _win_handle_page(const wint_t * const ch) *page_start = y - page_space; current->paged = 1; - current_win_dirty = TRUE; + wins_refresh_current(); } } static void _win_show_history(WINDOW *win, int win_index, const char * const contact) { - if (!windows[win_index]->history_shown) { + ProfWin *window = wins_get_by_num(win_index); + if (!window->history_shown) { GSList *history = NULL; Jid *jid = jid_create(jabber_get_fulljid()); history = chat_log_get_previous(jid->barejid, contact, history); @@ -1738,48 +1616,8 @@ _win_show_history(WINDOW *win, int win_index, const char * const contact) wprintw(win, "%s\n", history->data); history = g_slist_next(history); } - windows[win_index]->history_shown = 1; + window->history_shown = 1; g_slist_free_full(history, free); } } - -void -_set_current(int index) -{ - current_index = index; - current = windows[current_index]; -} - -gboolean -_tidy(void) -{ - int gap = 1; - int filler = 1; - gboolean tidied = FALSE; - - for (gap = 1; gap < NUM_WINS; gap++) { - // if a gap - if (!ui_win_exists(gap)) { - - // find next used window and move into gap - for (filler = gap + 1; filler < NUM_WINS; filler++) { - if (ui_win_exists(filler)) { - windows[gap] = windows[filler]; - if (windows[gap]->unread > 0) { - status_bar_new(gap); - } else { - status_bar_active(gap); - } - windows[filler] = NULL; - status_bar_inactive(filler); - tidied = TRUE; - break; - } - } - } - } - - return tidied; -} - diff --git a/src/ui/ui.h b/src/ui/ui.h index d8ac22fa..54a49408 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -40,10 +40,6 @@ #include "xmpp/xmpp.h" #define INP_WIN_MAX 1000 -#define NUM_WINS 10 - -// holds console at index 0 and chat wins 1 through to 9 -ProfWin* windows[NUM_WINS]; // ui startup and control void ui_init(void); @@ -63,7 +59,6 @@ void ui_new_chat_win(const char * const to); void ui_print_error_from_recipient(const char * const from, const char *err_msg); void ui_print_system_msg_from_recipient(const char * const from, const char *message); gint ui_unread(void); -void ui_console_dirty(void); void ui_close_connected_win(int index); // current window actions diff --git a/src/ui/window.h b/src/ui/window.h index 96c8f4af..a4421d1b 100644 --- a/src/ui/window.h +++ b/src/ui/window.h @@ -23,6 +23,14 @@ #ifndef WINDOW_H #define WINDOW_H +#include "config.h" + +#ifdef HAVE_NCURSESW_NCURSES_H +#include +#elif HAVE_NCURSES_H +#include +#endif + #include "contact.h" #define PAD_SIZE 1000 diff --git a/src/ui/windows.c b/src/ui/windows.c new file mode 100644 index 00000000..fe94b482 --- /dev/null +++ b/src/ui/windows.c @@ -0,0 +1,456 @@ +/* + * windows.c + * + * Copyright (C) 2012, 2013 James Booth + * + * This file is part of Profanity. + * + * Profanity is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Profanity is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Profanity. If not, see . + * + */ + +#include "config.h" + +#include + +#include + +#ifdef HAVE_NCURSESW_NCURSES_H +#include +#elif HAVE_NCURSES_H +#include +#endif + +#include "config/theme.h" +#include "ui/ui.h" +#include "ui/window.h" +#include "ui/windows.h" + +#define NUM_WINS 10 + +static ProfWin* windows[NUM_WINS]; +static int current; +static int max_cols; + +//static GHashTable *windows; + +void +wins_init(void) +{ + /* + windows = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, + window_free); + + int cols = getmaxx(stdscr); + ProfWin *console = win_create(CONS_WIN_TITLE, cols, WIN_CONSOLE); + g_hash_table_insert(GINT_TO_POINTER(1), console); + + current = console; +*/ + int i; + for (i = 0; i < NUM_WINS; i++) { + windows[i] = NULL; + } + + max_cols = getmaxx(stdscr); + int cols = getmaxx(stdscr); + windows[0] = win_create("_cons", cols, WIN_CONSOLE); + current = 0; +} + +ProfWin * +wins_get_console(void) +{ + return windows[0]; +// return g_hash_table_lookup(windows, GINT_TO_POINTER(1)); +} + +ProfWin * +wins_get_current(void) +{ + return windows[current]; +} + +void +wins_set_current_by_num(int i) +{ + if (i < NUM_WINS) { + current = i; + } +} + +ProfWin * +wins_get_by_num(int i) +{ + if (i >= NUM_WINS) { + return NULL; + } else { + return windows[i]; + } +} + +ProfWin * +wins_get_by_recipient(const char * const recipient) +{ + int i = 0; + for (i = 1; i < NUM_WINS; i++) { + if ((windows[i] != NULL) && g_strcmp0(windows[i]->from, recipient) == 0) { + return windows[i]; + } + } + + return NULL; +} + +int +wins_get_num(ProfWin *window) +{ + int i = 0; + for (i = 0; i < NUM_WINS; i++) { + if ((windows[i] != NULL) && g_strcmp0(windows[i]->from, window->from) == 0) { + return i; + } + } + + return 0; +} + +int +wins_get_current_num(void) +{ + return current; +} + +void +wins_close_current(void) +{ + wins_close_by_num(current); +} + +void +wins_close_by_num(int i) +{ + if (i > 0 && i < NUM_WINS) { + win_free(windows[i]); + windows[i] = NULL; + if (i == current) { + current = 0; + wins_refresh_current(); + } + } +} + +void +wins_refresh_current(void) +{ + int rows, cols; + getmaxyx(stdscr, rows, cols); + prefresh(windows[current]->win, windows[current]->y_pos, 0, 1, 0, rows-3, cols-1); +} + +void +wins_clear_current(void) +{ + werase(windows[current]->win); + wins_refresh_current(); +} + +gboolean +wins_is_current(ProfWin *window) +{ + if (g_strcmp0(windows[current]->from, window->from) == 0) { + return TRUE; + } else { + return FALSE; + } +} + +ProfWin * +wins_new(const char * const from, win_type_t type) +{ + int i; + for (i = 1; i < NUM_WINS; i++) { + if (windows[i] == NULL) { + break; + } + } + + if (i != NUM_WINS) { + int cols = getmaxx(stdscr); + windows[i] = win_create(from, cols, type); + return windows[i]; + } else { + return NULL; + } +} + +int +wins_get_total_unread(void) +{ + int i; + int result = 0; + for (i = 0; i < NUM_WINS; i++) { + if (windows[i] != NULL) { + result += windows[i]->unread; + } + } + return result; +} + +void +wins_resize_all(void) +{ + int rows, cols; + getmaxyx(stdscr, rows, cols); + + // only make the pads bigger, to avoid data loss on cropping + if (cols > max_cols) { + max_cols = cols; + + int i; + for (i = 0; i < NUM_WINS; i++) { + if (windows[i] != NULL) { + wresize(windows[i]->win, PAD_SIZE, cols); + } + } + } + + prefresh(windows[current]->win, windows[current]->y_pos, 0, 1, 0, rows-3, cols-1); +} + +void +wins_refresh_console(void) +{ + if (current == 0) { + wins_refresh_current(); + } +} + +gboolean +wins_full(void) +{ + int i; + for (i = 1; i < NUM_WINS; i++) { + if (windows[i] == NULL) { + return FALSE; + } + } + + return TRUE; +} + +gboolean +wins_duck_exists(void) +{ + int i; + for (i = 1; i < NUM_WINS; i++) { + if (windows[i] != NULL) { + if (windows[i]->type == WIN_DUCK) + return TRUE; + } + } + + return FALSE; +} + +GSList * +wins_get_chat_recipients(void) +{ + GSList *result = NULL; + int i; + for (i = 1; i < NUM_WINS; i++) { + if (windows[i] != NULL && windows[i]->type == WIN_CHAT) { + result = g_slist_append(result, windows[i]->from); + } + } + return result; +} + +GSList * +wins_get_prune_recipients(void) +{ + GSList *result = NULL; + int i; + for (i = 1; i < NUM_WINS; i++) { + if (windows[i] != NULL && windows[i]->unread == 0 && windows[i]->type != WIN_MUC) { + result = g_slist_append(result, windows[i]->from); + } + } + return result; + +} + +void +wins_lost_connection(void) +{ + int i; + // show message in all active chats + for (i = 1; i < NUM_WINS; i++) { + if (windows[i] != NULL) { + ProfWin *window = windows[i]; + win_print_time(window, '-'); + wattron(window->win, COLOUR_ERROR); + wprintw(window->win, "%s\n", "Lost connection."); + wattroff(window->win, COLOUR_ERROR); + + // if current win, set current_win_dirty + if (wins_is_current(window)) { + wins_refresh_current(); + } + } + } +} + +gboolean +wins_tidy(void) +{ + int gap = 1; + int filler = 1; + gboolean tidied = FALSE; + + for (gap = 1; gap < NUM_WINS; gap++) { + // if a gap + if (windows[gap] == NULL) { + + // find next used window and move into gap + for (filler = gap + 1; filler < NUM_WINS; filler++) { + if (windows[filler] != NULL) { + windows[gap] = windows[filler]; + if (windows[gap]->unread > 0) { + status_bar_new(gap); + } else { + status_bar_active(gap); + } + windows[filler] = NULL; + status_bar_inactive(filler); + tidied = TRUE; + break; + } + } + } + } + + return tidied; +} + +GSList * +wins_create_summary(void) +{ + GSList *result = NULL; + result = g_slist_append(result, strdup("1: Console")); + int count = 0; + int ui_index = 0; + + int i; + for (i = 1; i < NUM_WINS; i++) { + if (windows[i] != NULL) { + count++; + } + } + + if (count != 0) { + for (i = 1; i < NUM_WINS; i++) { + if (windows[i] != NULL) { + ProfWin *window = windows[i]; + ui_index = i + 1; + if (ui_index == 10) { + ui_index = 0; + } + + GString *chat_string; + GString *priv_string; + GString *muc_string; + GString *duck_string; + + switch (window->type) + { + case WIN_CHAT: + chat_string = g_string_new(""); + g_string_printf(chat_string, "%d: Chat %s", ui_index, window->from); + PContact contact = roster_get_contact(window->from); + + if (contact != NULL) { + if (p_contact_name(contact) != NULL) { + GString *chat_name = g_string_new(""); + g_string_printf(chat_name, " (%s)", p_contact_name(contact)); + g_string_append(chat_string, chat_name->str); + g_string_free(chat_name, TRUE); + } + GString *chat_presence = g_string_new(""); + g_string_printf(chat_presence, " - %s", p_contact_presence(contact)); + g_string_append(chat_string, chat_presence->str); + g_string_free(chat_presence, TRUE); + } + + if (window->unread > 0) { + GString *chat_unread = g_string_new(""); + g_string_printf(chat_unread, ", %d unread", window->unread); + g_string_append(chat_string, chat_unread->str); + g_string_free(chat_unread, TRUE); + } + + result = g_slist_append(result, strdup(chat_string->str)); + g_string_free(chat_string, TRUE); + + break; + + case WIN_PRIVATE: + priv_string = g_string_new(""); + g_string_printf(priv_string, "%d: Private %s", ui_index, window->from); + + if (window->unread > 0) { + GString *priv_unread = g_string_new(""); + g_string_printf(priv_unread, ", %d unread", window->unread); + g_string_append(priv_string, priv_unread->str); + g_string_free(priv_unread, TRUE); + } + + result = g_slist_append(result, strdup(priv_string->str)); + g_string_free(priv_string, TRUE); + + break; + + case WIN_MUC: + muc_string = g_string_new(""); + g_string_printf(muc_string, "%d: Room %s", ui_index, window->from); + + if (window->unread > 0) { + GString *muc_unread = g_string_new(""); + g_string_printf(muc_unread, ", %d unread", window->unread); + g_string_append(muc_string, muc_unread->str); + g_string_free(muc_unread, TRUE); + } + + result = g_slist_append(result, strdup(muc_string->str)); + g_string_free(muc_string, TRUE); + + break; + + case WIN_DUCK: + duck_string = g_string_new(""); + g_string_printf(duck_string, "%d: DuckDuckGo search", ui_index); + result = g_slist_append(result, strdup(duck_string->str)); + g_string_free(duck_string, TRUE); + + break; + + default: + break; + } + } + } + } + + return result; +} diff --git a/src/ui/windows.h b/src/ui/windows.h new file mode 100644 index 00000000..775cb79d --- /dev/null +++ b/src/ui/windows.h @@ -0,0 +1,51 @@ +/* + * windows.h + * + * Copyright (C) 2012, 2013 James Booth + * + * This file is part of Profanity. + * + * Profanity is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Profanity is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Profanity. If not, see . + * + */ + +#ifndef WINDOWS_H +#define WINDOWS_H + +void wins_init(void); +ProfWin * wins_get_console(void); +ProfWin * wins_get_current(void); +void wins_set_current_by_num(int i); +ProfWin * wins_get_by_num(int i); +ProfWin * wins_get_by_recipient(const char * const recipient); +int wins_get_num(ProfWin *window); +int wins_get_current_num(void); +void wins_close_current(void); +void wins_close_by_num(int i); +void wins_refresh_current(void); +void wins_refresh_console(void); +void wins_clear_current(void); +gboolean wins_is_current(ProfWin *window); +ProfWin * wins_new(const char * const from, win_type_t type); +int wins_get_total_unread(void); +void wins_resize_all(void); +gboolean wins_full(void); +gboolean wins_duck_exists(void); +GSList * wins_get_chat_recipients(void); +GSList * wins_get_prune_recipients(void); +void wins_lost_connection(void); +gboolean wins_tidy(void); +GSList * wins_create_summary(void); + +#endif -- cgit 1.4.1-2-gfad0 From 770b572d583dad3b6176c1becf25afa5b0d2200a Mon Sep 17 00:00:00 2001 From: James Booth Date: Tue, 20 Aug 2013 23:18:23 +0100 Subject: Console module get console from windows --- src/ui/console.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/ui/console.c b/src/ui/console.c index 0e5e26af..30b6b138 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -41,8 +41,6 @@ #define CONS_WIN_TITLE "_cons" -static ProfWin* console; - static void _cons_splash_logo(void); void _show_roster_contacts(GSList *list, gboolean show_groups); @@ -50,13 +48,13 @@ ProfWin * cons_create(void) { int cols = getmaxx(stdscr); - console = win_create(CONS_WIN_TITLE, cols, WIN_CONSOLE); - return console; + return win_create(CONS_WIN_TITLE, cols, WIN_CONSOLE); } void cons_show_time(void) { + ProfWin *console = wins_get_console(); win_print_time(console, '-'); wins_refresh_console(); } @@ -64,6 +62,7 @@ cons_show_time(void) void cons_show_word(const char * const word) { + ProfWin *console = wins_get_console(); wprintw(console->win, "%s", word); wins_refresh_console(); } @@ -71,6 +70,7 @@ cons_show_word(const char * const word) void cons_debug(const char * const msg, ...) { + ProfWin *console = wins_get_console(); if (strcmp(PACKAGE_STATUS, "development") == 0) { va_list arg; va_start(arg, msg); @@ -92,6 +92,7 @@ cons_debug(const char * const msg, ...) void cons_show(const char * const msg, ...) { + ProfWin *console = wins_get_console(); va_list arg; va_start(arg, msg); GString *fmt_msg = g_string_new(NULL); @@ -106,6 +107,7 @@ cons_show(const char * const msg, ...) void cons_show_error(const char * const msg, ...) { + ProfWin *console = wins_get_console(); va_list arg; va_start(arg, msg); GString *fmt_msg = g_string_new(NULL); @@ -124,6 +126,7 @@ cons_show_error(const char * const msg, ...) void cons_show_typing(const char * const barejid) { + ProfWin *console = wins_get_console(); PContact contact = roster_get_contact(barejid); const char * display_usr = NULL; if (p_contact_name(contact) != NULL) { @@ -144,6 +147,7 @@ cons_show_typing(const char * const barejid) void cons_show_incoming_message(const char * const short_from, const int win_index) { + ProfWin *console = wins_get_console(); int ui_index = win_index + 1; if (ui_index == 10) { ui_index = 0; @@ -160,6 +164,7 @@ cons_show_incoming_message(const char * const short_from, const int win_index) void cons_about(void) { + ProfWin *console = wins_get_console(); int rows, cols; getmaxyx(stdscr, rows, cols); @@ -205,6 +210,7 @@ cons_about(void) void cons_check_version(gboolean not_available_msg) { + ProfWin *console = wins_get_console(); char *latest_release = release_get_latest(); if (latest_release != NULL) { @@ -235,6 +241,7 @@ cons_check_version(gboolean not_available_msg) void cons_show_login_success(ProfAccount *account) { + ProfWin *console = wins_get_console(); win_print_time(console, '-'); wprintw(console->win, "%s logged in successfully, ", account->jid); @@ -254,6 +261,7 @@ cons_show_login_success(ProfAccount *account) void cons_show_wins(void) { + ProfWin *console = wins_get_console(); cons_show(""); cons_show("Active windows:"); GSList *window_strings = wins_create_summary(); @@ -292,6 +300,7 @@ cons_show_room_invites(GSList *invites) void cons_show_info(PContact pcontact) { + ProfWin *console = wins_get_console(); const char *barejid = p_contact_barejid(pcontact); const char *name = p_contact_name(pcontact); const char *presence = p_contact_presence(pcontact); @@ -424,6 +433,7 @@ cons_show_info(PContact pcontact) void cons_show_caps(const char * const contact, Resource *resource) { + ProfWin *console = wins_get_console(); WINDOW *win = console->win; cons_show(""); const char *resource_presence = string_from_resource_presence(resource->presence); @@ -499,6 +509,7 @@ void cons_show_software_version(const char * const jid, const char * const presence, const char * const name, const char * const version, const char * const os) { + ProfWin *console = wins_get_console(); if ((name != NULL) || (version != NULL) || (os != NULL)) { cons_show(""); win_print_time(console, '-'); @@ -566,6 +577,7 @@ cons_show_sent_subs(void) void cons_show_room_list(GSList *rooms, const char * const conference_node) { + ProfWin *console = wins_get_console(); if ((rooms != NULL) && (g_slist_length(rooms) > 0)) { cons_show("Chat rooms at %s:", conference_node); while (rooms != NULL) { @@ -632,6 +644,7 @@ cons_show_disco_info(const char *jid, GSList *identities, GSList *features) void cons_show_disco_items(GSList *items, const char * const jid) { + ProfWin *console = wins_get_console(); if ((items != NULL) && (g_slist_length(items) > 0)) { cons_show(""); cons_show("Service discovery items for %s:", jid); @@ -656,6 +669,7 @@ cons_show_disco_items(GSList *items, const char * const jid) void cons_show_status(const char * const barejid) { + ProfWin *console = wins_get_console(); PContact pcontact = roster_get_contact(barejid); if (pcontact != NULL) { @@ -707,6 +721,7 @@ cons_show_room_invite(const char * const invitor, const char * const room, void cons_show_account_list(gchar **accounts) { + ProfWin *console = wins_get_console(); int size = g_strv_length(accounts); if (size > 0) { cons_show("Accounts:"); @@ -736,6 +751,7 @@ cons_show_account_list(gchar **accounts) void cons_show_account(ProfAccount *account) { + ProfWin *console = wins_get_console(); cons_show(""); cons_show("Account %s:", account->name); if (account->enabled) { @@ -1253,6 +1269,7 @@ cons_navigation_help(void) void _show_roster_contacts(GSList *list, gboolean show_groups) { + ProfWin *console = wins_get_console(); GSList *curr = list; while(curr) { @@ -1355,6 +1372,7 @@ cons_show_roster(GSList *list) void cons_show_contacts(GSList *list) { + ProfWin *console = wins_get_console(); GSList *curr = list; while(curr) { @@ -1381,6 +1399,7 @@ cons_alert(void) static void _cons_splash_logo(void) { + ProfWin *console = wins_get_console(); win_print_time(console, '-'); wprintw(console->win, "Welcome to\n"); -- cgit 1.4.1-2-gfad0 From 3c39befa5e565bbc3cc13a0f060a8d7a18f735f1 Mon Sep 17 00:00:00 2001 From: James Booth Date: Tue, 20 Aug 2013 23:54:41 +0100 Subject: Fixed window refresh on presence --- src/ui/core.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/ui/core.c b/src/ui/core.c index 37d0d35d..48e9ff03 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -472,8 +472,11 @@ ui_contact_online(const char * const barejid, const char * const resource, jid_destroy(jid); g_string_free(display_str, TRUE); - if (wins_is_current(window)) + if (wins_is_current(console)) { wins_refresh_current(); + } else if ((window != NULL) && (wins_is_current(window))) { + wins_refresh_current(); + } } void @@ -511,8 +514,11 @@ ui_contact_offline(const char * const from, const char * const show, jid_destroy(jidp); g_string_free(display_str, TRUE); - if (wins_is_current(window)) + if (wins_is_current(console)) { wins_refresh_current(); + } else if ((window != NULL) && (wins_is_current(window))) { + wins_refresh_current(); + } } void -- cgit 1.4.1-2-gfad0 From 38be98cde5a13140f1095bfb05793fee2fe5cea3 Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 25 Aug 2013 23:30:10 +0100 Subject: Fix console references after merging master --- src/ui/console.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ui/console.c b/src/ui/console.c index 65711b48..b7c833e0 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -611,6 +611,8 @@ cons_show_bookmarks(const GList *list) while (list != NULL) { item = list->data; + ProfWin *console = wins_get_console(); + win_print_time(console, '-'); wprintw(console->win, " %s", item->jid); if (item->nick != NULL) { @@ -623,7 +625,7 @@ cons_show_bookmarks(const GList *list) list = g_list_next(list); } - ui_console_dirty(); + wins_refresh_console(); cons_alert(); } -- cgit 1.4.1-2-gfad0 From fd8a0b49701bf17f7ce171a78073a8d7f1ae46fe Mon Sep 17 00:00:00 2001 From: James Booth Date: Mon, 26 Aug 2013 16:42:31 +0100 Subject: Fixed freeing of recipient after message sent --- src/command/command.c | 2 -- src/ui/core.c | 1 - 2 files changed, 3 deletions(-) diff --git a/src/command/command.c b/src/command/command.c index 626b108e..4235c15d 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -1189,8 +1189,6 @@ cmd_execute_default(const char * const inp) break; } - free(recipient); - return TRUE; } diff --git a/src/ui/core.c b/src/ui/core.c index df63ac2a..97825c95 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -595,7 +595,6 @@ ui_switch_win(const int i) } wins_refresh_current(); } - } void -- cgit 1.4.1-2-gfad0 From d1b3340ea523f54270b20d92fad6e4bcb9fdce21 Mon Sep 17 00:00:00 2001 From: James Booth Date: Mon, 26 Aug 2013 17:08:09 +0100 Subject: Use Jid struct to get barejid in subscriptions --- src/command/command.c | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/src/command/command.c b/src/command/command.c index 4235c15d..56b4f8a7 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -1550,7 +1550,7 @@ _cmd_sub(gchar **args, struct cmd_help_t help) return TRUE; } - char *subcmd, *jid, *bare_jid; + char *subcmd, *jid; subcmd = args[0]; jid = args[1]; @@ -1574,49 +1574,47 @@ _cmd_sub(gchar **args, struct cmd_help_t help) return TRUE; } - if (jid != NULL) { - jid = strdup(jid); - } else { + if (jid == NULL) { jid = ui_current_recipient(); } - bare_jid = strtok(jid, "/"); + Jid *jidp = jid_create(jid); if (strcmp(subcmd, "allow") == 0) { - presence_subscription(bare_jid, PRESENCE_SUBSCRIBED); - cons_show("Accepted subscription for %s", bare_jid); - log_info("Accepted subscription for %s", bare_jid); + presence_subscription(jidp->barejid, PRESENCE_SUBSCRIBED); + cons_show("Accepted subscription for %s", jidp->barejid); + log_info("Accepted subscription for %s", jidp->barejid); } else if (strcmp(subcmd, "deny") == 0) { - presence_subscription(bare_jid, PRESENCE_UNSUBSCRIBED); - cons_show("Deleted/denied subscription for %s", bare_jid); - log_info("Deleted/denied subscription for %s", bare_jid); + presence_subscription(jidp->barejid, PRESENCE_UNSUBSCRIBED); + cons_show("Deleted/denied subscription for %s", jidp->barejid); + log_info("Deleted/denied subscription for %s", jidp->barejid); } else if (strcmp(subcmd, "request") == 0) { - presence_subscription(bare_jid, PRESENCE_SUBSCRIBE); - cons_show("Sent subscription request to %s.", bare_jid); - log_info("Sent subscription request to %s.", bare_jid); + presence_subscription(jidp->barejid, PRESENCE_SUBSCRIBE); + cons_show("Sent subscription request to %s.", jidp->barejid); + log_info("Sent subscription request to %s.", jidp->barejid); } else if (strcmp(subcmd, "show") == 0) { - PContact contact = roster_get_contact(bare_jid); + PContact contact = roster_get_contact(jidp->barejid); if ((contact == NULL) || (p_contact_subscription(contact) == NULL)) { if (win_type == WIN_CHAT) { - ui_current_print_line("No subscription information for %s.", bare_jid); + ui_current_print_line("No subscription information for %s.", jidp->barejid); } else { - cons_show("No subscription information for %s.", bare_jid); + cons_show("No subscription information for %s.", jidp->barejid); } } else { if (win_type == WIN_CHAT) { if (p_contact_pending_out(contact)) { ui_current_print_line("%s subscription status: %s, request pending.", - bare_jid, p_contact_subscription(contact)); + jidp->barejid, p_contact_subscription(contact)); } else { - ui_current_print_line("%s subscription status: %s.", bare_jid, + ui_current_print_line("%s subscription status: %s.", jidp->barejid, p_contact_subscription(contact)); } } else { if (p_contact_pending_out(contact)) { cons_show("%s subscription status: %s, request pending.", - bare_jid, p_contact_subscription(contact)); + jidp->barejid, p_contact_subscription(contact)); } else { - cons_show("%s subscription status: %s.", bare_jid, + cons_show("%s subscription status: %s.", jidp->barejid, p_contact_subscription(contact)); } } @@ -1625,7 +1623,8 @@ _cmd_sub(gchar **args, struct cmd_help_t help) cons_show("Usage: %s", help.usage); } - free(jid); + jid_destroy(jidp); + return TRUE; } -- cgit 1.4.1-2-gfad0 From 48feac3e779b97b14abe260415805c5df21947af Mon Sep 17 00:00:00 2001 From: James Booth Date: Mon, 26 Aug 2013 17:29:20 +0100 Subject: Removed cons_create from console.c --- src/ui/console.c | 9 --------- src/ui/ui.h | 1 - src/ui/window.c | 2 -- src/ui/windows.c | 3 ++- 4 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/ui/console.c b/src/ui/console.c index b7c833e0..107e190d 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -40,18 +40,9 @@ #include "xmpp/xmpp.h" #include "xmpp/bookmark.h" -#define CONS_WIN_TITLE "_cons" - static void _cons_splash_logo(void); void _show_roster_contacts(GSList *list, gboolean show_groups); -ProfWin * -cons_create(void) -{ - int cols = getmaxx(stdscr); - return win_create(CONS_WIN_TITLE, cols, WIN_CONSOLE); -} - void cons_show_time(void) { diff --git a/src/ui/ui.h b/src/ui/ui.h index 54adbc13..eec4aac5 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -144,7 +144,6 @@ void title_bar_set_typing(gboolean is_typing); void title_bar_draw(void); // console window actions -ProfWin* cons_create(void); void cons_show(const char * const msg, ...); void cons_about(void); void cons_help(void); diff --git a/src/ui/window.c b/src/ui/window.c index e2e03340..b78a240f 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -35,8 +35,6 @@ #include "config/theme.h" #include "ui/window.h" -#define CONS_WIN_TITLE "_cons" - ProfWin* win_create(const char * const title, int cols, win_type_t type) { diff --git a/src/ui/windows.c b/src/ui/windows.c index fe94b482..3f5d2d6b 100644 --- a/src/ui/windows.c +++ b/src/ui/windows.c @@ -38,6 +38,7 @@ #include "ui/windows.h" #define NUM_WINS 10 +#define CONS_WIN_TITLE "_cons" static ProfWin* windows[NUM_WINS]; static int current; @@ -65,7 +66,7 @@ wins_init(void) max_cols = getmaxx(stdscr); int cols = getmaxx(stdscr); - windows[0] = win_create("_cons", cols, WIN_CONSOLE); + windows[0] = win_create(CONS_WIN_TITLE, cols, WIN_CONSOLE); current = 0; } -- cgit 1.4.1-2-gfad0 From 18d11f2bcf72f6e7959434700f088b110cd71d3b Mon Sep 17 00:00:00 2001 From: James Booth Date: Mon, 26 Aug 2013 17:34:48 +0100 Subject: Moved static function in console.c --- src/ui/console.c | 152 +++++++++++++++++++++++++++---------------------------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/src/ui/console.c b/src/ui/console.c index 107e190d..ef9787c7 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -1288,82 +1288,6 @@ cons_navigation_help(void) cons_alert(); } -void -_show_roster_contacts(GSList *list, gboolean show_groups) -{ - ProfWin *console = wins_get_console(); - GSList *curr = list; - while(curr) { - - PContact contact = curr->data; - GString *title = g_string_new(" "); - title = g_string_append(title, p_contact_barejid(contact)); - if (p_contact_name(contact) != NULL) { - title = g_string_append(title, " ("); - title = g_string_append(title, p_contact_name(contact)); - title = g_string_append(title, ")"); - } - - const char *presence = p_contact_presence(contact); - win_print_time(console, '-'); - if (p_contact_subscribed(contact)) { - win_presence_colour_on(console, presence); - wprintw(console->win, "%s\n", title->str); - win_presence_colour_off(console, presence); - } else { - win_presence_colour_on(console, "offline"); - wprintw(console->win, "%s\n", title->str); - win_presence_colour_off(console, "offline"); - } - - g_string_free(title, TRUE); - - win_print_time(console, '-'); - wprintw(console->win, " Subscription : "); - GString *sub = g_string_new(""); - sub = g_string_append(sub, p_contact_subscription(contact)); - if (p_contact_pending_out(contact)) { - sub = g_string_append(sub, ", request sent"); - } - if (presence_sub_request_exists(p_contact_barejid(contact))) { - sub = g_string_append(sub, ", request received"); - } - if (p_contact_subscribed(contact)) { - wattron(console->win, COLOUR_SUBSCRIBED); - } else { - wattron(console->win, COLOUR_UNSUBSCRIBED); - } - wprintw(console->win, "%s\n", sub->str); - if (p_contact_subscribed(contact)) { - wattroff(console->win, COLOUR_SUBSCRIBED); - } else { - wattroff(console->win, COLOUR_UNSUBSCRIBED); - } - - g_string_free(sub, TRUE); - - if (show_groups) { - GSList *groups = p_contact_groups(contact); - if (groups != NULL) { - GString *groups_str = g_string_new(" Groups : "); - while (groups != NULL) { - g_string_append(groups_str, groups->data); - if (g_slist_next(groups) != NULL) { - g_string_append(groups_str, ", "); - } - groups = g_slist_next(groups); - } - - cons_show(groups_str->str); - g_string_free(groups_str, TRUE); - } - } - - curr = g_slist_next(curr); - } - -} - void cons_show_roster_group(const char * const group, GSList *list) { @@ -1469,3 +1393,79 @@ _cons_splash_logo(void) wprintw(console->win, "Version %s\n", PACKAGE_VERSION); } } + +void +_show_roster_contacts(GSList *list, gboolean show_groups) +{ + ProfWin *console = wins_get_console(); + GSList *curr = list; + while(curr) { + + PContact contact = curr->data; + GString *title = g_string_new(" "); + title = g_string_append(title, p_contact_barejid(contact)); + if (p_contact_name(contact) != NULL) { + title = g_string_append(title, " ("); + title = g_string_append(title, p_contact_name(contact)); + title = g_string_append(title, ")"); + } + + const char *presence = p_contact_presence(contact); + win_print_time(console, '-'); + if (p_contact_subscribed(contact)) { + win_presence_colour_on(console, presence); + wprintw(console->win, "%s\n", title->str); + win_presence_colour_off(console, presence); + } else { + win_presence_colour_on(console, "offline"); + wprintw(console->win, "%s\n", title->str); + win_presence_colour_off(console, "offline"); + } + + g_string_free(title, TRUE); + + win_print_time(console, '-'); + wprintw(console->win, " Subscription : "); + GString *sub = g_string_new(""); + sub = g_string_append(sub, p_contact_subscription(contact)); + if (p_contact_pending_out(contact)) { + sub = g_string_append(sub, ", request sent"); + } + if (presence_sub_request_exists(p_contact_barejid(contact))) { + sub = g_string_append(sub, ", request received"); + } + if (p_contact_subscribed(contact)) { + wattron(console->win, COLOUR_SUBSCRIBED); + } else { + wattron(console->win, COLOUR_UNSUBSCRIBED); + } + wprintw(console->win, "%s\n", sub->str); + if (p_contact_subscribed(contact)) { + wattroff(console->win, COLOUR_SUBSCRIBED); + } else { + wattroff(console->win, COLOUR_UNSUBSCRIBED); + } + + g_string_free(sub, TRUE); + + if (show_groups) { + GSList *groups = p_contact_groups(contact); + if (groups != NULL) { + GString *groups_str = g_string_new(" Groups : "); + while (groups != NULL) { + g_string_append(groups_str, groups->data); + if (g_slist_next(groups) != NULL) { + g_string_append(groups_str, ", "); + } + groups = g_slist_next(groups); + } + + cons_show(groups_str->str); + g_string_free(groups_str, TRUE); + } + } + + curr = g_slist_next(curr); + } + +} -- cgit 1.4.1-2-gfad0 From bca379844de5b5d0cfdf2ba84fd23a4d542a0be0 Mon Sep 17 00:00:00 2001 From: James Booth Date: Mon, 26 Aug 2013 17:47:29 +0100 Subject: Free windows on exit --- src/ui/core.c | 1 + src/ui/window.c | 2 -- src/ui/windows.c | 11 +++++++++++ src/ui/windows.h | 1 + 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/ui/core.c b/src/ui/core.c index 97825c95..0f928204 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -135,6 +135,7 @@ void ui_close(void) { notifier_uninit(); + wins_destroy(); endwin(); } diff --git a/src/ui/window.c b/src/ui/window.c index b78a240f..7c6f9266 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -57,8 +57,6 @@ win_free(ProfWin* window) { delwin(window->win); free(window->from); - window->from = NULL; - window->win = NULL; free(window); window = NULL; } diff --git a/src/ui/windows.c b/src/ui/windows.c index 3f5d2d6b..c55dad74 100644 --- a/src/ui/windows.c +++ b/src/ui/windows.c @@ -455,3 +455,14 @@ wins_create_summary(void) return result; } + +void +wins_destroy(void) +{ + int i; + for (i = 0; i < NUM_WINS; i++) { + if (windows[i] != NULL) { + win_free(windows[i]); + } + } +} diff --git a/src/ui/windows.h b/src/ui/windows.h index 775cb79d..ee4d1c84 100644 --- a/src/ui/windows.h +++ b/src/ui/windows.h @@ -47,5 +47,6 @@ GSList * wins_get_prune_recipients(void); void wins_lost_connection(void); gboolean wins_tidy(void); GSList * wins_create_summary(void); +void wins_destroy(void); #endif -- cgit 1.4.1-2-gfad0 From 48572bdbcf455233392c9bf8bab5518ac0c68c5f Mon Sep 17 00:00:00 2001 From: James Booth Date: Mon, 26 Aug 2013 17:50:26 +0100 Subject: Fixed indenting in ui/core.c --- src/ui/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ui/core.c b/src/ui/core.c index 0f928204..1e13de68 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -166,7 +166,8 @@ ui_windows_full(void) return wins_full(); } -gboolean ui_win_exists(int index) +gboolean +ui_win_exists(int index) { ProfWin *window = wins_get_by_num(index); return (window != NULL); -- cgit 1.4.1-2-gfad0 From b6f1afcf224ba33a78fbfbc22e90fc9b043fdadb Mon Sep 17 00:00:00 2001 From: James Booth Date: Mon, 26 Aug 2013 17:53:25 +0100 Subject: Removed whitespace in command.c --- src/command/command.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/command/command.c b/src/command/command.c index 56b4f8a7..ad9b28b2 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -3100,7 +3100,6 @@ _cmd_close(gchar **args, struct cmd_help_t help) return TRUE; } - // handle leaving rooms, or chat if (conn_status == JABBER_CONNECTED) { ui_close_connected_win(index); -- cgit 1.4.1-2-gfad0 From 8045b949a7089be12fb7caaf2e4f355900c94e74 Mon Sep 17 00:00:00 2001 From: James Booth Date: Mon, 26 Aug 2013 18:06:33 +0100 Subject: Refactor _cmd_close --- src/command/command.c | 21 ++------------------- src/ui/core.c | 38 ++++++++++++++++++++++++++++++++++++++ src/ui/ui.h | 2 ++ 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/src/command/command.c b/src/command/command.c index ad9b28b2..c8304736 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -3035,21 +3035,12 @@ _cmd_close(gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); int index = 0; - int curr = 0; int count = 0; if (args[0] == NULL) { index = ui_current_win_index(); } else if (strcmp(args[0], "all") == 0) { - for (curr = 1; curr <= 9; curr++) { - if (ui_win_exists(curr)) { - if (conn_status == JABBER_CONNECTED) { - ui_close_connected_win(curr); - } - ui_close_win(curr); - count++; - } - } + count = ui_close_all_wins(); if (count == 0) { cons_show("No windows to close."); } else if (count == 1) { @@ -3059,15 +3050,7 @@ _cmd_close(gchar **args, struct cmd_help_t help) } return TRUE; } else if (strcmp(args[0], "read") == 0) { - for (curr = 1; curr <= 9; curr++) { - if (ui_win_exists(curr) && (ui_win_unread(curr) == 0)) { - if (conn_status == JABBER_CONNECTED) { - ui_close_connected_win(curr); - } - ui_close_win(curr); - count++; - } - } + count = ui_close_read_wins(); if (count == 0) { cons_show("No windows to close."); } else if (count == 1) { diff --git a/src/ui/core.c b/src/ui/core.c index 1e13de68..3186aba5 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -567,6 +567,44 @@ ui_close_connected_win(int index) } } +int +ui_close_all_wins(void) +{ + int curr = 0, count = 0; + jabber_conn_status_t conn_status = jabber_get_connection_status(); + + for (curr = 1; curr <= 9; curr++) { + if (ui_win_exists(curr)) { + if (conn_status == JABBER_CONNECTED) { + ui_close_connected_win(curr); + } + ui_close_win(curr); + count++; + } + } + + return count; +} + +int +ui_close_read_wins(void) +{ + int curr = 0, count = 0; + jabber_conn_status_t conn_status = jabber_get_connection_status(); + + for (curr = 1; curr <= 9; curr++) { + if (ui_win_exists(curr) && (ui_win_unread(curr) == 0)) { + if (conn_status == JABBER_CONNECTED) { + ui_close_connected_win(curr); + } + ui_close_win(curr); + count++; + } + } + + return count; +} + void ui_switch_win(const int i) { diff --git a/src/ui/ui.h b/src/ui/ui.h index eec4aac5..f3163b6e 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -60,6 +60,8 @@ void ui_print_error_from_recipient(const char * const from, const char *err_msg) void ui_print_system_msg_from_recipient(const char * const from, const char *message); gint ui_unread(void); void ui_close_connected_win(int index); +int ui_close_all_wins(void); +int ui_close_read_wins(void); // current window actions void ui_close_current(void); -- cgit 1.4.1-2-gfad0 From d9fb9ad4a759036a26d8a2ad96737469fe438e86 Mon Sep 17 00:00:00 2001 From: James Booth Date: Tue, 27 Aug 2013 20:48:15 +0100 Subject: Fixed freeing recipient after /tiny --- src/command/command.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/command/command.c b/src/command/command.c index c8304736..b6fd90ff 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -3001,16 +3001,13 @@ _cmd_tiny(gchar **args, struct cmd_help_t help) } ui_outgoing_msg("me", recipient, tiny); - free(recipient); } else if (win_type == WIN_PRIVATE) { char *recipient = ui_current_recipient(); message_send(tiny, recipient); ui_outgoing_msg("me", recipient, tiny); - free(recipient); } else { // groupchat char *recipient = ui_current_recipient(); message_send_groupchat(tiny, recipient); - free(recipient); } free(tiny); } else { -- cgit 1.4.1-2-gfad0 From 77dcd04b103682ef85979cffeda24b0585a1b563 Mon Sep 17 00:00:00 2001 From: James Booth Date: Tue, 27 Aug 2013 20:55:20 +0100 Subject: Removed all freeing of ui_current_recipient, data is owned by windows --- src/command/command.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/command/command.c b/src/command/command.c index b6fd90ff..db682a0f 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -1217,7 +1217,6 @@ _cmd_complete_parameters(char *input, int *size) if (ui_current_win_type() == WIN_MUC) { char *recipient = ui_current_recipient(); Autocomplete nick_ac = muc_get_roster_ac(recipient); - free(recipient); if (nick_ac != NULL) { gchar *nick_choices[] = { "/msg", "/info", "/caps", "/status", "/software" } ; @@ -2006,8 +2005,6 @@ _cmd_who(gchar **args, struct cmd_help_t help) ui_room_roster(room, filtered, presence); } - free(room); - // not in groupchat window } else { cons_show(""); @@ -2172,8 +2169,6 @@ _cmd_msg(gchar **args, struct cmd_help_t help) ui_current_print_line("No such participant \"%s\" in room.", usr); } - free(room_name); - return TRUE; } else { @@ -2564,8 +2559,6 @@ _cmd_info(gchar **args, struct cmd_help_t help) break; } - free(recipient); - return TRUE; } @@ -2594,7 +2587,6 @@ _cmd_caps(gchar **args, struct cmd_help_t help) } else { cons_show("No such participant \"%s\" in room.", args[0]); } - free(recipient); } else { cons_show("No nickname supplied to /caps in chat room."); } @@ -2635,7 +2627,6 @@ _cmd_caps(gchar **args, struct cmd_help_t help) cons_show_caps(jid->resourcepart, resource); jid_destroy(jid); } - free(recipient); } break; default: @@ -2672,7 +2663,6 @@ _cmd_software(gchar **args, struct cmd_help_t help) } else { cons_show("No such participant \"%s\" in room.", args[0]); } - free(recipient); } else { cons_show("No nickname supplied to /software in chat room."); } @@ -2698,7 +2688,6 @@ _cmd_software(gchar **args, struct cmd_help_t help) } else { recipient = ui_current_recipient(); iq_send_software_version(recipient); - free(recipient); } break; default: @@ -2870,7 +2859,6 @@ _cmd_bookmark(gchar **args, struct cmd_help_t help) cons_show_bookmarks(bookmark_get_list()); } else { gboolean autojoin = FALSE; - gboolean jid_release = FALSE; gchar *jid = NULL; gchar *nick = NULL; int idx = 1; @@ -2896,7 +2884,6 @@ _cmd_bookmark(gchar **args, struct cmd_help_t help) if (win_type == WIN_MUC) { jid = ui_current_recipient(); - jid_release = TRUE; nick = muc_get_room_nick(jid); } else { cons_show("Usage: %s", help.usage); @@ -2911,10 +2898,6 @@ _cmd_bookmark(gchar **args, struct cmd_help_t help) } else { cons_show("Usage: %s", help.usage); } - - if (jid_release) { - free(jid); - } } return TRUE; -- cgit 1.4.1-2-gfad0 From 42c3a1c1f7bce008c2e447fb130426264269cabb Mon Sep 17 00:00:00 2001 From: James Booth Date: Tue, 27 Aug 2013 22:02:23 +0100 Subject: Added function to get next available window number, and tests --- src/common.c | 64 ++++++++++++ src/common.h | 3 + src/ui/windows.c | 1 + tests/test_common.c | 296 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 364 insertions(+) diff --git a/src/common.c b/src/common.c index c7ec7d0b..74f35af6 100644 --- a/src/common.c +++ b/src/common.c @@ -399,6 +399,70 @@ get_unique_id(void) return result; } +int +cmp_win_num(gconstpointer a, gconstpointer b) +{ + int real_a = GPOINTER_TO_INT(a); + int real_b = GPOINTER_TO_INT(b); + + if (real_a == 0) { + real_a = 10; + } + + if (real_b == 0) { + real_b = 10; + } + + if (real_a < real_b) { + return -1; + } else if (real_a == real_b) { + return 0; + } else { + return 1; + } +} + +int +get_next_available_win_num(GSList *used) +{ + int result = 0; + used = g_slist_sort(used, cmp_win_num); + // only console used + if (g_slist_length(used) == 1) { + return 2; + } else { + int last_num = 1; + GSList *curr = used; + // skip console + curr = g_slist_next(curr); + while (curr != NULL) { + int curr_num = GPOINTER_TO_INT(curr->data); + if (((last_num != 9) && ((last_num + 1) != curr_num)) || + ((last_num == 9) && (curr_num != 0))) { + g_slist_free(curr); + result = last_num + 1; + if (result == 10) { + result = 0; + } + return (result); + } else { + last_num = curr_num; + if (last_num == 0) { + last_num = 10; + } + } + curr = g_slist_next(curr); + } + result = last_num + 1; + if (result == 10) { + result = 0; + } + + return result; + } +} + + static size_t _data_callback(void *ptr, size_t size, size_t nmemb, void *data) { diff --git a/src/common.h b/src/common.h index f2b59413..dd92e50b 100644 --- a/src/common.h +++ b/src/common.h @@ -91,4 +91,7 @@ contact_presence_t contact_presence_from_resource_presence(resource_presence_t r char * get_unique_id(void); +int cmp_win_num(gconstpointer a, gconstpointer b); +int get_next_available_win_num(GSList *used); + #endif diff --git a/src/ui/windows.c b/src/ui/windows.c index c55dad74..db75bc17 100644 --- a/src/ui/windows.c +++ b/src/ui/windows.c @@ -32,6 +32,7 @@ #include #endif +#include "common.h" #include "config/theme.h" #include "ui/ui.h" #include "ui/window.h" diff --git a/tests/test_common.c b/tests/test_common.c index 6bdcfb76..eb6b907d 100644 --- a/tests/test_common.c +++ b/tests/test_common.c @@ -146,6 +146,283 @@ void replace_when_new_null(void) assert_string_equals("hello", result); } +void compare_win_nums_less(void) +{ + gconstpointer a = GINT_TO_POINTER(2); + gconstpointer b = GINT_TO_POINTER(3); + + int result = cmp_win_num(a, b); + + assert_true(result < 0); +} + +void compare_win_nums_equal(void) +{ + gconstpointer a = GINT_TO_POINTER(5); + gconstpointer b = GINT_TO_POINTER(5); + + int result = cmp_win_num(a, b); + + assert_true(result == 0); +} + +void compare_win_nums_greater(void) +{ + gconstpointer a = GINT_TO_POINTER(7); + gconstpointer b = GINT_TO_POINTER(6); + + int result = cmp_win_num(a, b); + + assert_true(result > 0); +} + +void compare_0s_equal(void) +{ + gconstpointer a = GINT_TO_POINTER(0); + gconstpointer b = GINT_TO_POINTER(0); + + int result = cmp_win_num(a, b); + + assert_true(result == 0); +} + +void compare_0_greater_than_1(void) +{ + gconstpointer a = GINT_TO_POINTER(0); + gconstpointer b = GINT_TO_POINTER(1); + + int result = cmp_win_num(a, b); + + assert_true(result > 0); +} + +void compare_1_less_than_0(void) +{ + gconstpointer a = GINT_TO_POINTER(1); + gconstpointer b = GINT_TO_POINTER(0); + + int result = cmp_win_num(a, b); + + assert_true(result < 0); +} + +void compare_0_less_than_11(void) +{ + gconstpointer a = GINT_TO_POINTER(0); + gconstpointer b = GINT_TO_POINTER(11); + + int result = cmp_win_num(a, b); + + assert_true(result < 0); +} + +void compare_11_greater_than_0(void) +{ + gconstpointer a = GINT_TO_POINTER(11); + gconstpointer b = GINT_TO_POINTER(0); + + int result = cmp_win_num(a, b); + + assert_true(result > 0); +} + +void compare_0_greater_than_9(void) +{ + gconstpointer a = GINT_TO_POINTER(0); + gconstpointer b = GINT_TO_POINTER(9); + + int result = cmp_win_num(a, b); + + assert_true(result > 0); +} + +void compare_9_less_than_0(void) +{ + gconstpointer a = GINT_TO_POINTER(9); + gconstpointer b = GINT_TO_POINTER(0); + + int result = cmp_win_num(a, b); + + assert_true(result < 0); +} + +void next_available_when_only_console(void) +{ + GSList *used = NULL; + used = g_slist_append(used, GINT_TO_POINTER(1)); + + int result = get_next_available_win_num(used); + + assert_int_equals(2, result); +} + +void next_available_3_at_end(void) +{ + GSList *used = NULL; + used = g_slist_append(used, GINT_TO_POINTER(1)); + used = g_slist_append(used, GINT_TO_POINTER(2)); + + int result = get_next_available_win_num(used); + + assert_int_equals(3, result); +} + +void next_available_9_at_end(void) +{ + GSList *used = NULL; + used = g_slist_append(used, GINT_TO_POINTER(1)); + used = g_slist_append(used, GINT_TO_POINTER(2)); + used = g_slist_append(used, GINT_TO_POINTER(3)); + used = g_slist_append(used, GINT_TO_POINTER(4)); + used = g_slist_append(used, GINT_TO_POINTER(5)); + used = g_slist_append(used, GINT_TO_POINTER(6)); + used = g_slist_append(used, GINT_TO_POINTER(7)); + used = g_slist_append(used, GINT_TO_POINTER(8)); + + int result = get_next_available_win_num(used); + + assert_int_equals(9, result); +} + +void next_available_0_at_end(void) +{ + GSList *used = NULL; + used = g_slist_append(used, GINT_TO_POINTER(1)); + used = g_slist_append(used, GINT_TO_POINTER(2)); + used = g_slist_append(used, GINT_TO_POINTER(3)); + used = g_slist_append(used, GINT_TO_POINTER(4)); + used = g_slist_append(used, GINT_TO_POINTER(5)); + used = g_slist_append(used, GINT_TO_POINTER(6)); + used = g_slist_append(used, GINT_TO_POINTER(7)); + used = g_slist_append(used, GINT_TO_POINTER(8)); + used = g_slist_append(used, GINT_TO_POINTER(9)); + + int result = get_next_available_win_num(used); + + assert_int_equals(0, result); +} + +void next_available_2_in_first_gap(void) +{ + GSList *used = NULL; + used = g_slist_append(used, GINT_TO_POINTER(1)); + used = g_slist_append(used, GINT_TO_POINTER(3)); + used = g_slist_append(used, GINT_TO_POINTER(4)); + used = g_slist_append(used, GINT_TO_POINTER(5)); + used = g_slist_append(used, GINT_TO_POINTER(9)); + used = g_slist_append(used, GINT_TO_POINTER(0)); + + int result = get_next_available_win_num(used); + + assert_int_equals(2, result); +} + +void next_available_9_in_first_gap(void) +{ + GSList *used = NULL; + used = g_slist_append(used, GINT_TO_POINTER(1)); + used = g_slist_append(used, GINT_TO_POINTER(2)); + used = g_slist_append(used, GINT_TO_POINTER(3)); + used = g_slist_append(used, GINT_TO_POINTER(4)); + used = g_slist_append(used, GINT_TO_POINTER(5)); + used = g_slist_append(used, GINT_TO_POINTER(6)); + used = g_slist_append(used, GINT_TO_POINTER(7)); + used = g_slist_append(used, GINT_TO_POINTER(8)); + used = g_slist_append(used, GINT_TO_POINTER(0)); + used = g_slist_append(used, GINT_TO_POINTER(11)); + used = g_slist_append(used, GINT_TO_POINTER(12)); + used = g_slist_append(used, GINT_TO_POINTER(13)); + used = g_slist_append(used, GINT_TO_POINTER(20)); + + int result = get_next_available_win_num(used); + + assert_int_equals(9, result); +} + +void next_available_0_in_first_gap(void) +{ + GSList *used = NULL; + used = g_slist_append(used, GINT_TO_POINTER(1)); + used = g_slist_append(used, GINT_TO_POINTER(2)); + used = g_slist_append(used, GINT_TO_POINTER(3)); + used = g_slist_append(used, GINT_TO_POINTER(4)); + used = g_slist_append(used, GINT_TO_POINTER(5)); + used = g_slist_append(used, GINT_TO_POINTER(6)); + used = g_slist_append(used, GINT_TO_POINTER(7)); + used = g_slist_append(used, GINT_TO_POINTER(8)); + used = g_slist_append(used, GINT_TO_POINTER(9)); + used = g_slist_append(used, GINT_TO_POINTER(11)); + used = g_slist_append(used, GINT_TO_POINTER(12)); + used = g_slist_append(used, GINT_TO_POINTER(13)); + used = g_slist_append(used, GINT_TO_POINTER(20)); + + int result = get_next_available_win_num(used); + + assert_int_equals(0, result); +} + +void next_available_11_in_first_gap(void) +{ + GSList *used = NULL; + used = g_slist_append(used, GINT_TO_POINTER(1)); + used = g_slist_append(used, GINT_TO_POINTER(2)); + used = g_slist_append(used, GINT_TO_POINTER(3)); + used = g_slist_append(used, GINT_TO_POINTER(4)); + used = g_slist_append(used, GINT_TO_POINTER(5)); + used = g_slist_append(used, GINT_TO_POINTER(6)); + used = g_slist_append(used, GINT_TO_POINTER(7)); + used = g_slist_append(used, GINT_TO_POINTER(8)); + used = g_slist_append(used, GINT_TO_POINTER(9)); + used = g_slist_append(used, GINT_TO_POINTER(0)); + used = g_slist_append(used, GINT_TO_POINTER(12)); + used = g_slist_append(used, GINT_TO_POINTER(13)); + used = g_slist_append(used, GINT_TO_POINTER(20)); + + int result = get_next_available_win_num(used); + + assert_int_equals(11, result); +} + +void next_available_24_first_big_gap(void) +{ + GSList *used = NULL; + used = g_slist_append(used, GINT_TO_POINTER(1)); + used = g_slist_append(used, GINT_TO_POINTER(2)); + used = g_slist_append(used, GINT_TO_POINTER(3)); + used = g_slist_append(used, GINT_TO_POINTER(4)); + used = g_slist_append(used, GINT_TO_POINTER(5)); + used = g_slist_append(used, GINT_TO_POINTER(6)); + used = g_slist_append(used, GINT_TO_POINTER(7)); + used = g_slist_append(used, GINT_TO_POINTER(8)); + used = g_slist_append(used, GINT_TO_POINTER(9)); + used = g_slist_append(used, GINT_TO_POINTER(0)); + used = g_slist_append(used, GINT_TO_POINTER(11)); + used = g_slist_append(used, GINT_TO_POINTER(12)); + used = g_slist_append(used, GINT_TO_POINTER(13)); + used = g_slist_append(used, GINT_TO_POINTER(14)); + used = g_slist_append(used, GINT_TO_POINTER(15)); + used = g_slist_append(used, GINT_TO_POINTER(16)); + used = g_slist_append(used, GINT_TO_POINTER(17)); + used = g_slist_append(used, GINT_TO_POINTER(18)); + used = g_slist_append(used, GINT_TO_POINTER(19)); + used = g_slist_append(used, GINT_TO_POINTER(20)); + used = g_slist_append(used, GINT_TO_POINTER(21)); + used = g_slist_append(used, GINT_TO_POINTER(22)); + used = g_slist_append(used, GINT_TO_POINTER(23)); + used = g_slist_append(used, GINT_TO_POINTER(51)); + used = g_slist_append(used, GINT_TO_POINTER(52)); + used = g_slist_append(used, GINT_TO_POINTER(53)); + used = g_slist_append(used, GINT_TO_POINTER(89)); + used = g_slist_append(used, GINT_TO_POINTER(90)); + used = g_slist_append(used, GINT_TO_POINTER(100)); + used = g_slist_append(used, GINT_TO_POINTER(101)); + used = g_slist_append(used, GINT_TO_POINTER(102)); + + int result = get_next_available_win_num(used); + + assert_int_equals(24, result); +} + void register_common_tests(void) { TEST_MODULE("common tests"); @@ -162,4 +439,23 @@ void register_common_tests(void) TEST(replace_when_sub_null); TEST(replace_when_new_empty); TEST(replace_when_new_null); + TEST(compare_win_nums_less); + TEST(compare_win_nums_equal); + TEST(compare_win_nums_greater); + TEST(compare_0s_equal); + TEST(compare_0_greater_than_1); + TEST(compare_1_less_than_0); + TEST(compare_0_less_than_11); + TEST(compare_11_greater_than_0); + TEST(compare_0_greater_than_9); + TEST(compare_9_less_than_0); + TEST(next_available_when_only_console); + TEST(next_available_3_at_end); + TEST(next_available_9_at_end); + TEST(next_available_0_at_end); + TEST(next_available_2_in_first_gap); + TEST(next_available_9_in_first_gap); + TEST(next_available_0_in_first_gap); + TEST(next_available_11_in_first_gap); + TEST(next_available_24_first_big_gap); } -- cgit 1.4.1-2-gfad0 From b5eb095820e95a225f6d8a4748c291ddff236146 Mon Sep 17 00:00:00 2001 From: James Booth Date: Tue, 27 Aug 2013 23:38:25 +0100 Subject: Removed limit on number of windows, WIP --- src/command/command.c | 15 -- src/common.c | 14 +- src/common.h | 2 +- src/ui/core.c | 144 ++++++---------- src/ui/ui.h | 1 - src/ui/windows.c | 452 +++++++++++++++++++++++++------------------------- src/ui/windows.h | 1 - tests/test_common.c | 210 +++++++++++------------ 8 files changed, 389 insertions(+), 450 deletions(-) diff --git a/src/command/command.c b/src/command/command.c index db682a0f..33550e07 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -2144,11 +2144,6 @@ _cmd_msg(gchar **args, struct cmd_help_t help) return TRUE; } - if (ui_windows_full()) { - cons_show_error("Windows all used, close a window and try again."); - return TRUE; - } - if (win_type == WIN_MUC) { char *room_name = ui_current_recipient(); if (muc_nick_in_roster(room_name, usr)) { @@ -2399,11 +2394,6 @@ _cmd_duck(gchar **args, struct cmd_help_t help) return TRUE; } - if (ui_windows_full()) { - cons_show_error("Windows all used, close a window and try again."); - return TRUE; - } - // if no duck win open, create it and send a help command if (!ui_duck_exists()) { ui_create_duck_win(); @@ -2707,11 +2697,6 @@ _cmd_join(gchar **args, struct cmd_help_t help) return TRUE; } - if (ui_windows_full()) { - cons_show_error("Windows all used, close a window and try again."); - return TRUE; - } - Jid *room_arg = jid_create(args[0]); if (room_arg == NULL) { cons_show_error("Specified room has incorrect format"); diff --git a/src/common.c b/src/common.c index 74f35af6..ddb1c892 100644 --- a/src/common.c +++ b/src/common.c @@ -423,23 +423,23 @@ cmp_win_num(gconstpointer a, gconstpointer b) } int -get_next_available_win_num(GSList *used) +get_next_available_win_num(GList *used) { int result = 0; - used = g_slist_sort(used, cmp_win_num); + used = g_list_sort(used, cmp_win_num); // only console used - if (g_slist_length(used) == 1) { + if (g_list_length(used) == 1) { return 2; } else { int last_num = 1; - GSList *curr = used; + GList *curr = used; // skip console - curr = g_slist_next(curr); + curr = g_list_next(curr); while (curr != NULL) { int curr_num = GPOINTER_TO_INT(curr->data); if (((last_num != 9) && ((last_num + 1) != curr_num)) || ((last_num == 9) && (curr_num != 0))) { - g_slist_free(curr); + g_list_free(curr); result = last_num + 1; if (result == 10) { result = 0; @@ -451,7 +451,7 @@ get_next_available_win_num(GSList *used) last_num = 10; } } - curr = g_slist_next(curr); + curr = g_list_next(curr); } result = last_num + 1; if (result == 10) { diff --git a/src/common.h b/src/common.h index dd92e50b..b1b6834e 100644 --- a/src/common.h +++ b/src/common.h @@ -92,6 +92,6 @@ contact_presence_t contact_presence_from_resource_presence(resource_presence_t r char * get_unique_id(void); int cmp_win_num(gconstpointer a, gconstpointer b); -int get_next_available_win_num(GSList *used); +int get_next_available_win_num(GList *used); #endif diff --git a/src/ui/core.c b/src/ui/core.c index 3186aba5..846a7dea 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -160,12 +160,6 @@ ui_load_colours(void) } } -gboolean -ui_windows_full(void) -{ - return wins_full(); -} - gboolean ui_win_exists(int index) { @@ -278,112 +272,76 @@ ui_incoming_msg(const char * const from, const char * const message, } int num = wins_get_num(window); - // no spare windows left - if (wins_full()) { - ProfWin *console = wins_get_console(); + + // currently viewing chat window with sender + if (wins_is_current(window)) { if (tv_stamp == NULL) { - win_print_time(console, '-'); + win_print_time(window, '-'); } else { GDateTime *time = g_date_time_new_from_timeval_utc(tv_stamp); gchar *date_fmt = g_date_time_format(time, "%H:%M:%S"); - wattron(console->win, COLOUR_TIME); - wprintw(console->win, "%s - ", date_fmt); - wattroff(console->win, COLOUR_TIME); + wattron(window->win, COLOUR_TIME); + wprintw(window->win, "%s - ", date_fmt); + wattroff(window->win, COLOUR_TIME); g_date_time_unref(time); g_free(date_fmt); } if (strncmp(message, "/me ", 4) == 0) { - wattron(console->win, COLOUR_THEM); - wprintw(console->win, "*%s ", display_from); - waddstr(console->win, message + 4); - wprintw(console->win, "\n"); - wattroff(console->win, COLOUR_THEM); - } else { - _win_show_user(console->win, display_from, 1); - _win_show_message(console->win, message); - } - - cons_show("Windows all used, close a window to respond."); - - if (wins_get_current_num() == 0) { - wins_refresh_current(); + wattron(window->win, COLOUR_THEM); + wprintw(window->win, "*%s ", display_from); + waddstr(window->win, message + 4); + wprintw(window->win, "\n"); + wattroff(window->win, COLOUR_THEM); } else { - status_bar_new(0); + _win_show_user(window->win, display_from, 1); + _win_show_message(window->win, message); } + title_bar_set_typing(FALSE); + title_bar_draw(); + status_bar_active(num); + wins_refresh_current(); - // window found or created + // not currently viewing chat window with sender } else { - // currently viewing chat window with sender - if (wins_is_current(window)) { - if (tv_stamp == NULL) { - win_print_time(window, '-'); - } else { - GDateTime *time = g_date_time_new_from_timeval_utc(tv_stamp); - gchar *date_fmt = g_date_time_format(time, "%H:%M:%S"); - wattron(window->win, COLOUR_TIME); - wprintw(window->win, "%s - ", date_fmt); - wattroff(window->win, COLOUR_TIME); - g_date_time_unref(time); - g_free(date_fmt); - } + status_bar_new(num); + cons_show_incoming_message(display_from, num); + if (prefs_get_boolean(PREF_FLASH)) + flash(); - if (strncmp(message, "/me ", 4) == 0) { - wattron(window->win, COLOUR_THEM); - wprintw(window->win, "*%s ", display_from); - waddstr(window->win, message + 4); - wprintw(window->win, "\n"); - wattroff(window->win, COLOUR_THEM); - } else { - _win_show_user(window->win, display_from, 1); - _win_show_message(window->win, message); - } - title_bar_set_typing(FALSE); - title_bar_draw(); - status_bar_active(num); - wins_refresh_current(); + window->unread++; + if (prefs_get_boolean(PREF_CHLOG) && prefs_get_boolean(PREF_HISTORY)) { + _win_show_history(window->win, num, from); + } - // not currently viewing chat window with sender + if (tv_stamp == NULL) { + win_print_time(window, '-'); } else { - status_bar_new(num); - cons_show_incoming_message(display_from, num); - if (prefs_get_boolean(PREF_FLASH)) - flash(); - - window->unread++; - if (prefs_get_boolean(PREF_CHLOG) && prefs_get_boolean(PREF_HISTORY)) { - _win_show_history(window->win, num, from); - } - - if (tv_stamp == NULL) { - win_print_time(window, '-'); - } else { - // show users status first, when receiving message via delayed delivery - if (win_created) { - PContact pcontact = roster_get_contact(from); - if (pcontact != NULL) { - win_show_contact(window, pcontact); - } + // show users status first, when receiving message via delayed delivery + if (win_created) { + PContact pcontact = roster_get_contact(from); + if (pcontact != NULL) { + win_show_contact(window, pcontact); } - GDateTime *time = g_date_time_new_from_timeval_utc(tv_stamp); - gchar *date_fmt = g_date_time_format(time, "%H:%M:%S"); - wattron(window->win, COLOUR_TIME); - wprintw(window->win, "%s - ", date_fmt); - wattroff(window->win, COLOUR_TIME); - g_date_time_unref(time); - g_free(date_fmt); } + GDateTime *time = g_date_time_new_from_timeval_utc(tv_stamp); + gchar *date_fmt = g_date_time_format(time, "%H:%M:%S"); + wattron(window->win, COLOUR_TIME); + wprintw(window->win, "%s - ", date_fmt); + wattroff(window->win, COLOUR_TIME); + g_date_time_unref(time); + g_free(date_fmt); + } - if (strncmp(message, "/me ", 4) == 0) { - wattron(window->win, COLOUR_THEM); - wprintw(window->win, "*%s ", display_from); - waddstr(window->win, message + 4); - wprintw(window->win, "\n"); - wattroff(window->win, COLOUR_THEM); - } else { - _win_show_user(window->win, display_from, 1); - _win_show_message(window->win, message); - } + if (strncmp(message, "/me ", 4) == 0) { + wattron(window->win, COLOUR_THEM); + wprintw(window->win, "*%s ", display_from); + waddstr(window->win, message + 4); + wprintw(window->win, "\n"); + wattroff(window->win, COLOUR_THEM); + } else { + _win_show_user(window->win, display_from, 1); + _win_show_message(window->win, message); } } diff --git a/src/ui/ui.h b/src/ui/ui.h index f3163b6e..157f8ad3 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -52,7 +52,6 @@ void ui_idle(void); void ui_handle_special_keys(const wint_t * const ch, const char * const inp, const int size); void ui_switch_win(const int i); -gboolean ui_windows_full(void); unsigned long ui_get_idle_time(void); void ui_reset_idle_time(void); void ui_new_chat_win(const char * const to); diff --git a/src/ui/windows.c b/src/ui/windows.c index db75bc17..0cd53c55 100644 --- a/src/ui/windows.c +++ b/src/ui/windows.c @@ -38,56 +38,42 @@ #include "ui/window.h" #include "ui/windows.h" -#define NUM_WINS 10 #define CONS_WIN_TITLE "_cons" -static ProfWin* windows[NUM_WINS]; +static GHashTable *windows; static int current; static int max_cols; -//static GHashTable *windows; - void wins_init(void) { - /* windows = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, - window_free); + (GDestroyNotify)win_free); + max_cols = getmaxx(stdscr); int cols = getmaxx(stdscr); ProfWin *console = win_create(CONS_WIN_TITLE, cols, WIN_CONSOLE); - g_hash_table_insert(GINT_TO_POINTER(1), console); + g_hash_table_insert(windows, GINT_TO_POINTER(1), console); - current = console; -*/ - int i; - for (i = 0; i < NUM_WINS; i++) { - windows[i] = NULL; - } - - max_cols = getmaxx(stdscr); - int cols = getmaxx(stdscr); - windows[0] = win_create(CONS_WIN_TITLE, cols, WIN_CONSOLE); - current = 0; + current = 1; } ProfWin * wins_get_console(void) { - return windows[0]; -// return g_hash_table_lookup(windows, GINT_TO_POINTER(1)); + return g_hash_table_lookup(windows, GINT_TO_POINTER(1)); } ProfWin * wins_get_current(void) { - return windows[current]; + return g_hash_table_lookup(windows, GINT_TO_POINTER(current)); } void wins_set_current_by_num(int i) { - if (i < NUM_WINS) { + if (g_hash_table_lookup(windows, GINT_TO_POINTER(i)) != NULL) { current = i; } } @@ -95,21 +81,21 @@ wins_set_current_by_num(int i) ProfWin * wins_get_by_num(int i) { - if (i >= NUM_WINS) { - return NULL; - } else { - return windows[i]; - } + return g_hash_table_lookup(windows, GINT_TO_POINTER(i)); } ProfWin * wins_get_by_recipient(const char * const recipient) { - int i = 0; - for (i = 1; i < NUM_WINS; i++) { - if ((windows[i] != NULL) && g_strcmp0(windows[i]->from, recipient) == 0) { - return windows[i]; + GList *values = g_hash_table_get_values(windows); + GList *curr = values; + + while (curr != NULL) { + ProfWin *window = curr->data; + if (g_strcmp0(window->from, recipient) == 0) { + return window; } + curr = g_list_next(curr); } return NULL; @@ -118,14 +104,19 @@ wins_get_by_recipient(const char * const recipient) int wins_get_num(ProfWin *window) { - int i = 0; - for (i = 0; i < NUM_WINS; i++) { - if ((windows[i] != NULL) && g_strcmp0(windows[i]->from, window->from) == 0) { - return i; + GList *keys = g_hash_table_get_keys(windows); + GList *curr = keys; + + while (curr != NULL) { + gconstpointer num_p = curr->data; + ProfWin *curr_win = g_hash_table_lookup(windows, num_p); + if (g_strcmp0(curr_win->from, window->from) == 0) { + return GPOINTER_TO_INT(num_p); } + curr = g_list_next(curr); } - return 0; + return -1; } int @@ -143,35 +134,38 @@ wins_close_current(void) void wins_close_by_num(int i) { - if (i > 0 && i < NUM_WINS) { - win_free(windows[i]); - windows[i] = NULL; + if (i != 1) { if (i == current) { - current = 0; + current = 1; wins_refresh_current(); } + g_hash_table_remove(windows, GINT_TO_POINTER(i)); } } void wins_refresh_current(void) { + ProfWin *window = wins_get_current(); int rows, cols; getmaxyx(stdscr, rows, cols); - prefresh(windows[current]->win, windows[current]->y_pos, 0, 1, 0, rows-3, cols-1); + prefresh(window->win, window->y_pos, 0, 1, 0, rows-3, cols-1); } void wins_clear_current(void) { - werase(windows[current]->win); + ProfWin *window = wins_get_current(); + werase(window->win); wins_refresh_current(); } gboolean wins_is_current(ProfWin *window) { - if (g_strcmp0(windows[current]->from, window->from) == 0) { + ProfWin *current_window = wins_get_current(); + + if (g_strcmp0(current_window->from, window->from) == 0) { return TRUE; } else { return FALSE; @@ -181,31 +175,25 @@ wins_is_current(ProfWin *window) ProfWin * wins_new(const char * const from, win_type_t type) { - int i; - for (i = 1; i < NUM_WINS; i++) { - if (windows[i] == NULL) { - break; - } - } - - if (i != NUM_WINS) { - int cols = getmaxx(stdscr); - windows[i] = win_create(from, cols, type); - return windows[i]; - } else { - return NULL; - } + GList *keys = g_hash_table_get_keys(windows); + int result = get_next_available_win_num(keys); + int cols = getmaxx(stdscr); + ProfWin *new = win_create(from, cols, type); + g_hash_table_insert(windows, GINT_TO_POINTER(result), new); + return new; } int wins_get_total_unread(void) { - int i; int result = 0; - for (i = 0; i < NUM_WINS; i++) { - if (windows[i] != NULL) { - result += windows[i]->unread; - } + GList *values = g_hash_table_get_values(windows); + GList *curr = values; + + while (curr != NULL) { + ProfWin *window = curr->data; + result += window->unread; + curr = g_list_next(curr); } return result; } @@ -220,15 +208,19 @@ wins_resize_all(void) if (cols > max_cols) { max_cols = cols; - int i; - for (i = 0; i < NUM_WINS; i++) { - if (windows[i] != NULL) { - wresize(windows[i]->win, PAD_SIZE, cols); - } + GList *values = g_hash_table_get_values(windows); + GList *curr = values; + + while (curr != NULL) { + ProfWin *window = curr->data; + wresize(window->win, PAD_SIZE, cols); + curr = g_list_next(curr); } } - prefresh(windows[current]->win, windows[current]->y_pos, 0, 1, 0, rows-3, cols-1); + ProfWin *current_win = wins_get_current(); + + prefresh(current_win->win, current_win->y_pos, 0, 1, 0, rows-3, cols-1); } void @@ -239,28 +231,17 @@ wins_refresh_console(void) } } -gboolean -wins_full(void) -{ - int i; - for (i = 1; i < NUM_WINS; i++) { - if (windows[i] == NULL) { - return FALSE; - } - } - - return TRUE; -} - gboolean wins_duck_exists(void) { - int i; - for (i = 1; i < NUM_WINS; i++) { - if (windows[i] != NULL) { - if (windows[i]->type == WIN_DUCK) - return TRUE; - } + GList *values = g_hash_table_get_values(windows); + GList *curr = values; + + while (curr != NULL) { + ProfWin *window = curr->data; + if (window->type == WIN_DUCK) + return TRUE; + curr = g_list_next(curr); } return FALSE; @@ -270,11 +251,15 @@ GSList * wins_get_chat_recipients(void) { GSList *result = NULL; - int i; - for (i = 1; i < NUM_WINS; i++) { - if (windows[i] != NULL && windows[i]->type == WIN_CHAT) { - result = g_slist_append(result, windows[i]->from); + GList *values = g_hash_table_get_values(windows); + GList *curr = values; + + while (curr != NULL) { + ProfWin *window = curr->data; + if (window->type == WIN_CHAT) { + result = g_slist_append(result, window->from); } + curr = g_list_next(curr); } return result; } @@ -283,24 +268,28 @@ GSList * wins_get_prune_recipients(void) { GSList *result = NULL; - int i; - for (i = 1; i < NUM_WINS; i++) { - if (windows[i] != NULL && windows[i]->unread == 0 && windows[i]->type != WIN_MUC) { - result = g_slist_append(result, windows[i]->from); + GList *values = g_hash_table_get_values(windows); + GList *curr = values; + + while (curr != NULL) { + ProfWin *window = curr->data; + if (window->unread == 0 && window->type != WIN_MUC && window->type != WIN_CONSOLE) { + result = g_slist_append(result, window->from); } + curr = g_list_next(curr); } return result; - } void wins_lost_connection(void) { - int i; - // show message in all active chats - for (i = 1; i < NUM_WINS; i++) { - if (windows[i] != NULL) { - ProfWin *window = windows[i]; + GList *values = g_hash_table_get_values(windows); + GList *curr = values; + + while (curr != NULL) { + ProfWin *window = curr->data; + if (window->type != WIN_CONSOLE) { win_print_time(window, '-'); wattron(window->win, COLOUR_ERROR); wprintw(window->win, "%s\n", "Lost connection."); @@ -311,147 +300,161 @@ wins_lost_connection(void) wins_refresh_current(); } } + curr = g_list_next(curr); } } gboolean wins_tidy(void) { - int gap = 1; - int filler = 1; - gboolean tidied = FALSE; - - for (gap = 1; gap < NUM_WINS; gap++) { - // if a gap - if (windows[gap] == NULL) { - - // find next used window and move into gap - for (filler = gap + 1; filler < NUM_WINS; filler++) { - if (windows[filler] != NULL) { - windows[gap] = windows[filler]; - if (windows[gap]->unread > 0) { - status_bar_new(gap); - } else { - status_bar_active(gap); - } - windows[filler] = NULL; - status_bar_inactive(filler); - tidied = TRUE; - break; + gboolean tidy_required = FALSE; + // check for gaps + GList *keys = g_hash_table_get_keys(windows); + keys = g_list_sort(keys, cmp_win_num); + + // get last used + GList *last = g_list_last(keys); + int last_num = GPOINTER_TO_INT(last->data); + + // find first free num TODO - Will sort again + int next_available = get_next_available_win_num(keys); + + // found gap (next available after last window) + if (cmp_win_num(GINT_TO_POINTER(next_available), GINT_TO_POINTER(last_num)) > 0) { + tidy_required = TRUE; + } + + if (tidy_required) { + GHashTable *new_windows = g_hash_table_new_full(g_direct_hash, + g_direct_equal, NULL, (GDestroyNotify)win_free); + + int num = 1; + GList *curr = keys; + while (curr != NULL) { + ProfWin *window = g_hash_table_lookup(windows, GINT_TO_POINTER(curr->data)); + if (num == 10) { + g_hash_table_insert(windows, GINT_TO_POINTER(0), window); + if (window->unread > 0) { + status_bar_new(0); + } else { + status_bar_active(0); + } + } else { + g_hash_table_insert(windows, GINT_TO_POINTER(num), window); + if (window->unread > 0) { + status_bar_new(num); + } else { + status_bar_active(num); } } + num++; + curr = g_list_next(curr); } - } - return tidied; + windows = new_windows; + return TRUE; + } else { + return FALSE; + } } GSList * wins_create_summary(void) { GSList *result = NULL; - result = g_slist_append(result, strdup("1: Console")); - int count = 0; - int ui_index = 0; - - int i; - for (i = 1; i < NUM_WINS; i++) { - if (windows[i] != NULL) { - count++; - } - } - if (count != 0) { - for (i = 1; i < NUM_WINS; i++) { - if (windows[i] != NULL) { - ProfWin *window = windows[i]; - ui_index = i + 1; - if (ui_index == 10) { - ui_index = 0; + GList *keys = g_hash_table_get_keys(windows); + keys = g_list_sort(keys, cmp_win_num); + GList *curr = keys; + + while (curr != NULL) { + ProfWin *window = g_hash_table_lookup(windows, curr->data); + int ui_index = GPOINTER_TO_INT(curr->data); + + GString *chat_string; + GString *priv_string; + GString *muc_string; + GString *duck_string; + + switch (window->type) + { + case WIN_CONSOLE: + result = g_slist_append(result, strdup("1: Console")); + break; + case WIN_CHAT: + chat_string = g_string_new(""); + g_string_printf(chat_string, "%d: Chat %s", ui_index, window->from); + PContact contact = roster_get_contact(window->from); + + if (contact != NULL) { + if (p_contact_name(contact) != NULL) { + GString *chat_name = g_string_new(""); + g_string_printf(chat_name, " (%s)", p_contact_name(contact)); + g_string_append(chat_string, chat_name->str); + g_string_free(chat_name, TRUE); + } + GString *chat_presence = g_string_new(""); + g_string_printf(chat_presence, " - %s", p_contact_presence(contact)); + g_string_append(chat_string, chat_presence->str); + g_string_free(chat_presence, TRUE); } - GString *chat_string; - GString *priv_string; - GString *muc_string; - GString *duck_string; - - switch (window->type) - { - case WIN_CHAT: - chat_string = g_string_new(""); - g_string_printf(chat_string, "%d: Chat %s", ui_index, window->from); - PContact contact = roster_get_contact(window->from); - - if (contact != NULL) { - if (p_contact_name(contact) != NULL) { - GString *chat_name = g_string_new(""); - g_string_printf(chat_name, " (%s)", p_contact_name(contact)); - g_string_append(chat_string, chat_name->str); - g_string_free(chat_name, TRUE); - } - GString *chat_presence = g_string_new(""); - g_string_printf(chat_presence, " - %s", p_contact_presence(contact)); - g_string_append(chat_string, chat_presence->str); - g_string_free(chat_presence, TRUE); - } - - if (window->unread > 0) { - GString *chat_unread = g_string_new(""); - g_string_printf(chat_unread, ", %d unread", window->unread); - g_string_append(chat_string, chat_unread->str); - g_string_free(chat_unread, TRUE); - } - - result = g_slist_append(result, strdup(chat_string->str)); - g_string_free(chat_string, TRUE); - - break; - - case WIN_PRIVATE: - priv_string = g_string_new(""); - g_string_printf(priv_string, "%d: Private %s", ui_index, window->from); - - if (window->unread > 0) { - GString *priv_unread = g_string_new(""); - g_string_printf(priv_unread, ", %d unread", window->unread); - g_string_append(priv_string, priv_unread->str); - g_string_free(priv_unread, TRUE); - } - - result = g_slist_append(result, strdup(priv_string->str)); - g_string_free(priv_string, TRUE); - - break; - - case WIN_MUC: - muc_string = g_string_new(""); - g_string_printf(muc_string, "%d: Room %s", ui_index, window->from); - - if (window->unread > 0) { - GString *muc_unread = g_string_new(""); - g_string_printf(muc_unread, ", %d unread", window->unread); - g_string_append(muc_string, muc_unread->str); - g_string_free(muc_unread, TRUE); - } - - result = g_slist_append(result, strdup(muc_string->str)); - g_string_free(muc_string, TRUE); - - break; - - case WIN_DUCK: - duck_string = g_string_new(""); - g_string_printf(duck_string, "%d: DuckDuckGo search", ui_index); - result = g_slist_append(result, strdup(duck_string->str)); - g_string_free(duck_string, TRUE); - - break; - - default: - break; + if (window->unread > 0) { + GString *chat_unread = g_string_new(""); + g_string_printf(chat_unread, ", %d unread", window->unread); + g_string_append(chat_string, chat_unread->str); + g_string_free(chat_unread, TRUE); } - } + + result = g_slist_append(result, strdup(chat_string->str)); + g_string_free(chat_string, TRUE); + + break; + + case WIN_PRIVATE: + priv_string = g_string_new(""); + g_string_printf(priv_string, "%d: Private %s", ui_index, window->from); + + if (window->unread > 0) { + GString *priv_unread = g_string_new(""); + g_string_printf(priv_unread, ", %d unread", window->unread); + g_string_append(priv_string, priv_unread->str); + g_string_free(priv_unread, TRUE); + } + + result = g_slist_append(result, strdup(priv_string->str)); + g_string_free(priv_string, TRUE); + + break; + + case WIN_MUC: + muc_string = g_string_new(""); + g_string_printf(muc_string, "%d: Room %s", ui_index, window->from); + + if (window->unread > 0) { + GString *muc_unread = g_string_new(""); + g_string_printf(muc_unread, ", %d unread", window->unread); + g_string_append(muc_string, muc_unread->str); + g_string_free(muc_unread, TRUE); + } + + result = g_slist_append(result, strdup(muc_string->str)); + g_string_free(muc_string, TRUE); + + break; + + case WIN_DUCK: + duck_string = g_string_new(""); + g_string_printf(duck_string, "%d: DuckDuckGo search", ui_index); + result = g_slist_append(result, strdup(duck_string->str)); + g_string_free(duck_string, TRUE); + + break; + + default: + break; } + curr = g_list_next(curr); } return result; @@ -460,10 +463,5 @@ wins_create_summary(void) void wins_destroy(void) { - int i; - for (i = 0; i < NUM_WINS; i++) { - if (windows[i] != NULL) { - win_free(windows[i]); - } - } + g_hash_table_destroy(windows); } diff --git a/src/ui/windows.h b/src/ui/windows.h index ee4d1c84..f0476896 100644 --- a/src/ui/windows.h +++ b/src/ui/windows.h @@ -40,7 +40,6 @@ gboolean wins_is_current(ProfWin *window); ProfWin * wins_new(const char * const from, win_type_t type); int wins_get_total_unread(void); void wins_resize_all(void); -gboolean wins_full(void); gboolean wins_duck_exists(void); GSList * wins_get_chat_recipients(void); GSList * wins_get_prune_recipients(void); diff --git a/tests/test_common.c b/tests/test_common.c index eb6b907d..37dd37d2 100644 --- a/tests/test_common.c +++ b/tests/test_common.c @@ -248,8 +248,8 @@ void compare_9_less_than_0(void) void next_available_when_only_console(void) { - GSList *used = NULL; - used = g_slist_append(used, GINT_TO_POINTER(1)); + GList *used = NULL; + used = g_list_append(used, GINT_TO_POINTER(1)); int result = get_next_available_win_num(used); @@ -258,9 +258,9 @@ void next_available_when_only_console(void) void next_available_3_at_end(void) { - GSList *used = NULL; - used = g_slist_append(used, GINT_TO_POINTER(1)); - used = g_slist_append(used, GINT_TO_POINTER(2)); + GList *used = NULL; + used = g_list_append(used, GINT_TO_POINTER(1)); + used = g_list_append(used, GINT_TO_POINTER(2)); int result = get_next_available_win_num(used); @@ -269,15 +269,15 @@ void next_available_3_at_end(void) void next_available_9_at_end(void) { - GSList *used = NULL; - used = g_slist_append(used, GINT_TO_POINTER(1)); - used = g_slist_append(used, GINT_TO_POINTER(2)); - used = g_slist_append(used, GINT_TO_POINTER(3)); - used = g_slist_append(used, GINT_TO_POINTER(4)); - used = g_slist_append(used, GINT_TO_POINTER(5)); - used = g_slist_append(used, GINT_TO_POINTER(6)); - used = g_slist_append(used, GINT_TO_POINTER(7)); - used = g_slist_append(used, GINT_TO_POINTER(8)); + GList *used = NULL; + used = g_list_append(used, GINT_TO_POINTER(1)); + used = g_list_append(used, GINT_TO_POINTER(2)); + used = g_list_append(used, GINT_TO_POINTER(3)); + used = g_list_append(used, GINT_TO_POINTER(4)); + used = g_list_append(used, GINT_TO_POINTER(5)); + used = g_list_append(used, GINT_TO_POINTER(6)); + used = g_list_append(used, GINT_TO_POINTER(7)); + used = g_list_append(used, GINT_TO_POINTER(8)); int result = get_next_available_win_num(used); @@ -286,16 +286,16 @@ void next_available_9_at_end(void) void next_available_0_at_end(void) { - GSList *used = NULL; - used = g_slist_append(used, GINT_TO_POINTER(1)); - used = g_slist_append(used, GINT_TO_POINTER(2)); - used = g_slist_append(used, GINT_TO_POINTER(3)); - used = g_slist_append(used, GINT_TO_POINTER(4)); - used = g_slist_append(used, GINT_TO_POINTER(5)); - used = g_slist_append(used, GINT_TO_POINTER(6)); - used = g_slist_append(used, GINT_TO_POINTER(7)); - used = g_slist_append(used, GINT_TO_POINTER(8)); - used = g_slist_append(used, GINT_TO_POINTER(9)); + GList *used = NULL; + used = g_list_append(used, GINT_TO_POINTER(1)); + used = g_list_append(used, GINT_TO_POINTER(2)); + used = g_list_append(used, GINT_TO_POINTER(3)); + used = g_list_append(used, GINT_TO_POINTER(4)); + used = g_list_append(used, GINT_TO_POINTER(5)); + used = g_list_append(used, GINT_TO_POINTER(6)); + used = g_list_append(used, GINT_TO_POINTER(7)); + used = g_list_append(used, GINT_TO_POINTER(8)); + used = g_list_append(used, GINT_TO_POINTER(9)); int result = get_next_available_win_num(used); @@ -304,13 +304,13 @@ void next_available_0_at_end(void) void next_available_2_in_first_gap(void) { - GSList *used = NULL; - used = g_slist_append(used, GINT_TO_POINTER(1)); - used = g_slist_append(used, GINT_TO_POINTER(3)); - used = g_slist_append(used, GINT_TO_POINTER(4)); - used = g_slist_append(used, GINT_TO_POINTER(5)); - used = g_slist_append(used, GINT_TO_POINTER(9)); - used = g_slist_append(used, GINT_TO_POINTER(0)); + GList *used = NULL; + used = g_list_append(used, GINT_TO_POINTER(1)); + used = g_list_append(used, GINT_TO_POINTER(3)); + used = g_list_append(used, GINT_TO_POINTER(4)); + used = g_list_append(used, GINT_TO_POINTER(5)); + used = g_list_append(used, GINT_TO_POINTER(9)); + used = g_list_append(used, GINT_TO_POINTER(0)); int result = get_next_available_win_num(used); @@ -319,20 +319,20 @@ void next_available_2_in_first_gap(void) void next_available_9_in_first_gap(void) { - GSList *used = NULL; - used = g_slist_append(used, GINT_TO_POINTER(1)); - used = g_slist_append(used, GINT_TO_POINTER(2)); - used = g_slist_append(used, GINT_TO_POINTER(3)); - used = g_slist_append(used, GINT_TO_POINTER(4)); - used = g_slist_append(used, GINT_TO_POINTER(5)); - used = g_slist_append(used, GINT_TO_POINTER(6)); - used = g_slist_append(used, GINT_TO_POINTER(7)); - used = g_slist_append(used, GINT_TO_POINTER(8)); - used = g_slist_append(used, GINT_TO_POINTER(0)); - used = g_slist_append(used, GINT_TO_POINTER(11)); - used = g_slist_append(used, GINT_TO_POINTER(12)); - used = g_slist_append(used, GINT_TO_POINTER(13)); - used = g_slist_append(used, GINT_TO_POINTER(20)); + GList *used = NULL; + used = g_list_append(used, GINT_TO_POINTER(1)); + used = g_list_append(used, GINT_TO_POINTER(2)); + used = g_list_append(used, GINT_TO_POINTER(3)); + used = g_list_append(used, GINT_TO_POINTER(4)); + used = g_list_append(used, GINT_TO_POINTER(5)); + used = g_list_append(used, GINT_TO_POINTER(6)); + used = g_list_append(used, GINT_TO_POINTER(7)); + used = g_list_append(used, GINT_TO_POINTER(8)); + used = g_list_append(used, GINT_TO_POINTER(0)); + used = g_list_append(used, GINT_TO_POINTER(11)); + used = g_list_append(used, GINT_TO_POINTER(12)); + used = g_list_append(used, GINT_TO_POINTER(13)); + used = g_list_append(used, GINT_TO_POINTER(20)); int result = get_next_available_win_num(used); @@ -341,20 +341,20 @@ void next_available_9_in_first_gap(void) void next_available_0_in_first_gap(void) { - GSList *used = NULL; - used = g_slist_append(used, GINT_TO_POINTER(1)); - used = g_slist_append(used, GINT_TO_POINTER(2)); - used = g_slist_append(used, GINT_TO_POINTER(3)); - used = g_slist_append(used, GINT_TO_POINTER(4)); - used = g_slist_append(used, GINT_TO_POINTER(5)); - used = g_slist_append(used, GINT_TO_POINTER(6)); - used = g_slist_append(used, GINT_TO_POINTER(7)); - used = g_slist_append(used, GINT_TO_POINTER(8)); - used = g_slist_append(used, GINT_TO_POINTER(9)); - used = g_slist_append(used, GINT_TO_POINTER(11)); - used = g_slist_append(used, GINT_TO_POINTER(12)); - used = g_slist_append(used, GINT_TO_POINTER(13)); - used = g_slist_append(used, GINT_TO_POINTER(20)); + GList *used = NULL; + used = g_list_append(used, GINT_TO_POINTER(1)); + used = g_list_append(used, GINT_TO_POINTER(2)); + used = g_list_append(used, GINT_TO_POINTER(3)); + used = g_list_append(used, GINT_TO_POINTER(4)); + used = g_list_append(used, GINT_TO_POINTER(5)); + used = g_list_append(used, GINT_TO_POINTER(6)); + used = g_list_append(used, GINT_TO_POINTER(7)); + used = g_list_append(used, GINT_TO_POINTER(8)); + used = g_list_append(used, GINT_TO_POINTER(9)); + used = g_list_append(used, GINT_TO_POINTER(11)); + used = g_list_append(used, GINT_TO_POINTER(12)); + used = g_list_append(used, GINT_TO_POINTER(13)); + used = g_list_append(used, GINT_TO_POINTER(20)); int result = get_next_available_win_num(used); @@ -363,20 +363,20 @@ void next_available_0_in_first_gap(void) void next_available_11_in_first_gap(void) { - GSList *used = NULL; - used = g_slist_append(used, GINT_TO_POINTER(1)); - used = g_slist_append(used, GINT_TO_POINTER(2)); - used = g_slist_append(used, GINT_TO_POINTER(3)); - used = g_slist_append(used, GINT_TO_POINTER(4)); - used = g_slist_append(used, GINT_TO_POINTER(5)); - used = g_slist_append(used, GINT_TO_POINTER(6)); - used = g_slist_append(used, GINT_TO_POINTER(7)); - used = g_slist_append(used, GINT_TO_POINTER(8)); - used = g_slist_append(used, GINT_TO_POINTER(9)); - used = g_slist_append(used, GINT_TO_POINTER(0)); - used = g_slist_append(used, GINT_TO_POINTER(12)); - used = g_slist_append(used, GINT_TO_POINTER(13)); - used = g_slist_append(used, GINT_TO_POINTER(20)); + GList *used = NULL; + used = g_list_append(used, GINT_TO_POINTER(1)); + used = g_list_append(used, GINT_TO_POINTER(2)); + used = g_list_append(used, GINT_TO_POINTER(3)); + used = g_list_append(used, GINT_TO_POINTER(4)); + used = g_list_append(used, GINT_TO_POINTER(5)); + used = g_list_append(used, GINT_TO_POINTER(6)); + used = g_list_append(used, GINT_TO_POINTER(7)); + used = g_list_append(used, GINT_TO_POINTER(8)); + used = g_list_append(used, GINT_TO_POINTER(9)); + used = g_list_append(used, GINT_TO_POINTER(0)); + used = g_list_append(used, GINT_TO_POINTER(12)); + used = g_list_append(used, GINT_TO_POINTER(13)); + used = g_list_append(used, GINT_TO_POINTER(20)); int result = get_next_available_win_num(used); @@ -385,38 +385,38 @@ void next_available_11_in_first_gap(void) void next_available_24_first_big_gap(void) { - GSList *used = NULL; - used = g_slist_append(used, GINT_TO_POINTER(1)); - used = g_slist_append(used, GINT_TO_POINTER(2)); - used = g_slist_append(used, GINT_TO_POINTER(3)); - used = g_slist_append(used, GINT_TO_POINTER(4)); - used = g_slist_append(used, GINT_TO_POINTER(5)); - used = g_slist_append(used, GINT_TO_POINTER(6)); - used = g_slist_append(used, GINT_TO_POINTER(7)); - used = g_slist_append(used, GINT_TO_POINTER(8)); - used = g_slist_append(used, GINT_TO_POINTER(9)); - used = g_slist_append(used, GINT_TO_POINTER(0)); - used = g_slist_append(used, GINT_TO_POINTER(11)); - used = g_slist_append(used, GINT_TO_POINTER(12)); - used = g_slist_append(used, GINT_TO_POINTER(13)); - used = g_slist_append(used, GINT_TO_POINTER(14)); - used = g_slist_append(used, GINT_TO_POINTER(15)); - used = g_slist_append(used, GINT_TO_POINTER(16)); - used = g_slist_append(used, GINT_TO_POINTER(17)); - used = g_slist_append(used, GINT_TO_POINTER(18)); - used = g_slist_append(used, GINT_TO_POINTER(19)); - used = g_slist_append(used, GINT_TO_POINTER(20)); - used = g_slist_append(used, GINT_TO_POINTER(21)); - used = g_slist_append(used, GINT_TO_POINTER(22)); - used = g_slist_append(used, GINT_TO_POINTER(23)); - used = g_slist_append(used, GINT_TO_POINTER(51)); - used = g_slist_append(used, GINT_TO_POINTER(52)); - used = g_slist_append(used, GINT_TO_POINTER(53)); - used = g_slist_append(used, GINT_TO_POINTER(89)); - used = g_slist_append(used, GINT_TO_POINTER(90)); - used = g_slist_append(used, GINT_TO_POINTER(100)); - used = g_slist_append(used, GINT_TO_POINTER(101)); - used = g_slist_append(used, GINT_TO_POINTER(102)); + GList *used = NULL; + used = g_list_append(used, GINT_TO_POINTER(1)); + used = g_list_append(used, GINT_TO_POINTER(2)); + used = g_list_append(used, GINT_TO_POINTER(3)); + used = g_list_append(used, GINT_TO_POINTER(4)); + used = g_list_append(used, GINT_TO_POINTER(5)); + used = g_list_append(used, GINT_TO_POINTER(6)); + used = g_list_append(used, GINT_TO_POINTER(7)); + used = g_list_append(used, GINT_TO_POINTER(8)); + used = g_list_append(used, GINT_TO_POINTER(9)); + used = g_list_append(used, GINT_TO_POINTER(0)); + used = g_list_append(used, GINT_TO_POINTER(11)); + used = g_list_append(used, GINT_TO_POINTER(12)); + used = g_list_append(used, GINT_TO_POINTER(13)); + used = g_list_append(used, GINT_TO_POINTER(14)); + used = g_list_append(used, GINT_TO_POINTER(15)); + used = g_list_append(used, GINT_TO_POINTER(16)); + used = g_list_append(used, GINT_TO_POINTER(17)); + used = g_list_append(used, GINT_TO_POINTER(18)); + used = g_list_append(used, GINT_TO_POINTER(19)); + used = g_list_append(used, GINT_TO_POINTER(20)); + used = g_list_append(used, GINT_TO_POINTER(21)); + used = g_list_append(used, GINT_TO_POINTER(22)); + used = g_list_append(used, GINT_TO_POINTER(23)); + used = g_list_append(used, GINT_TO_POINTER(51)); + used = g_list_append(used, GINT_TO_POINTER(52)); + used = g_list_append(used, GINT_TO_POINTER(53)); + used = g_list_append(used, GINT_TO_POINTER(89)); + used = g_list_append(used, GINT_TO_POINTER(90)); + used = g_list_append(used, GINT_TO_POINTER(100)); + used = g_list_append(used, GINT_TO_POINTER(101)); + used = g_list_append(used, GINT_TO_POINTER(102)); int result = get_next_available_win_num(used); -- cgit 1.4.1-2-gfad0 From 9ef7e2d233733d32514420c7dd52c104d4fd3f6b Mon Sep 17 00:00:00 2001 From: James Booth Date: Wed, 28 Aug 2013 00:50:15 +0100 Subject: Changes to status bar for unlimited windows - WIP --- src/command/command.c | 4 +-- src/ui/console.c | 2 +- src/ui/core.c | 12 +++---- src/ui/inputwin.c | 20 +++++------ src/ui/statusbar.c | 93 ++++++++++++++++++++++++++++++++------------------- 5 files changed, 77 insertions(+), 54 deletions(-) diff --git a/src/command/command.c b/src/command/command.c index 33550e07..360daa07 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -1822,7 +1822,7 @@ _cmd_about(gchar **args, struct cmd_help_t help) cons_show(""); cons_about(); if (ui_current_win_type() != WIN_CONSOLE) { - status_bar_new(0); + status_bar_new(1); } return TRUE; } @@ -2124,7 +2124,7 @@ _cmd_who(gchar **args, struct cmd_help_t help) } if (win_type != WIN_CONSOLE && win_type != WIN_MUC) { - status_bar_new(0); + status_bar_new(1); } return TRUE; diff --git a/src/ui/console.c b/src/ui/console.c index ef9787c7..d0b340d9 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -1338,7 +1338,7 @@ void cons_alert(void) { if (ui_current_win_type() != WIN_CONSOLE) { - status_bar_new(0); + status_bar_new(1); } } diff --git a/src/ui/core.c b/src/ui/core.c index 846a7dea..21102eed 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -85,7 +85,7 @@ ui_init(void) refresh(); create_title_bar(); create_status_bar(); - status_bar_active(0); + status_bar_active(1); create_input_window(); wins_init(); cons_about(); @@ -574,9 +574,9 @@ ui_switch_win(const int i) new_current->unread = 0; - if (i == 0) { + if (i == 1) { title_bar_title(); - status_bar_active(0); + status_bar_active(1); } else { PContact contact = roster_get_contact(new_current->from); if (contact != NULL) { @@ -607,7 +607,7 @@ ui_close_current(void) int current_index = wins_get_current_num(); wins_close_current(); status_bar_inactive(current_index); - status_bar_active(0); + status_bar_active(1); title_bar_title(); } @@ -616,7 +616,7 @@ ui_close_win(int index) { wins_close_by_num(index); status_bar_inactive(index); - status_bar_active(0); + status_bar_active(1); title_bar_title(); wins_refresh_current(); @@ -797,7 +797,7 @@ ui_print_system_msg_from_recipient(const char * const from, const char *message) } else { num = 0; window = wins_get_console(); - status_bar_active(0); + status_bar_active(1); } } diff --git a/src/ui/inputwin.c b/src/ui/inputwin.c index 0ab53131..b6162938 100644 --- a/src/ui/inputwin.c +++ b/src/ui/inputwin.c @@ -526,34 +526,34 @@ _handle_alt_key(char *input, int *size, int key) switch (key) { case '1': - ui_switch_win(0); + ui_switch_win(1); break; case '2': - ui_switch_win(1); + ui_switch_win(2); break; case '3': - ui_switch_win(2); + ui_switch_win(3); break; case '4': - ui_switch_win(3); + ui_switch_win(4); break; case '5': - ui_switch_win(4); + ui_switch_win(5); break; case '6': - ui_switch_win(5); + ui_switch_win(6); break; case '7': - ui_switch_win(6); + ui_switch_win(7); break; case '8': - ui_switch_win(7); + ui_switch_win(8); break; case '9': - ui_switch_win(8); + ui_switch_win(9); break; case '0': - ui_switch_win(9); + ui_switch_win(0); break; case 263: case 127: diff --git a/src/ui/statusbar.c b/src/ui/statusbar.c index 6e7eae30..90430e8d 100644 --- a/src/ui/statusbar.c +++ b/src/ui/statusbar.c @@ -37,9 +37,10 @@ static WINDOW *status_bar; static char *message = NULL; -static char _active[31] = "[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]"; -static int is_active[10]; -static int is_new[10]; +// 1 2 3 4 5 6 7 8 9 0 > +static char _active[34] = "[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]"; +static int is_active[12]; +static int is_new[12]; static int dirty; static GDateTime *last_time; @@ -51,9 +52,9 @@ create_status_bar(void) int rows, cols, i; getmaxyx(stdscr, rows, cols); - is_active[0] = TRUE; - is_new[0] = FALSE; - for (i = 1; i < 10; i++) { + is_active[1] = TRUE; + is_new[1] = FALSE; + for (i = 2; i < 12; i++) { is_active[i] = FALSE; is_new[i] = FALSE; } @@ -61,7 +62,7 @@ create_status_bar(void) status_bar = newwin(1, cols, rows-2, 0); wbkgd(status_bar, COLOUR_STATUS_TEXT); wattron(status_bar, COLOUR_STATUS_BRACKET); - mvwprintw(status_bar, 0, cols - 31, _active); + mvwprintw(status_bar, 0, cols - 34, _active); wattroff(status_bar, COLOUR_STATUS_BRACKET); if (last_time != NULL) @@ -105,10 +106,10 @@ status_bar_resize(void) wbkgd(status_bar, COLOUR_STATUS_TEXT); werase(status_bar); wattron(status_bar, COLOUR_STATUS_BRACKET); - mvwprintw(status_bar, 0, cols - 31, _active); + mvwprintw(status_bar, 0, cols - 34, _active); wattroff(status_bar, COLOUR_STATUS_BRACKET); - for(i = 0; i < 10; i++) { + for(i = 1; i < 12; i++) { if (is_new[i]) status_bar_new(i); else if (is_active[i]) @@ -127,14 +128,18 @@ status_bar_resize(void) void status_bar_inactive(const int win) { - is_active[win] = FALSE; - is_new[win] = FALSE; + int true_win = win; + if (true_win == 0) { + true_win = 10; + } + is_active[true_win] = FALSE; + is_new[true_win] = FALSE; - int active_pos = 1 + (win * 3); + int active_pos = 1 + ((true_win-1) * 3); int cols = getmaxx(stdscr); - mvwaddch(status_bar, 0, cols - 31 + active_pos, ' '); + mvwaddch(status_bar, 0, cols - 34 + active_pos, ' '); dirty = TRUE; } @@ -142,18 +147,27 @@ status_bar_inactive(const int win) void status_bar_active(const int win) { - is_active[win] = TRUE; - is_new[win] = FALSE; + int true_win = win; + if (true_win == 0) { + true_win = 10; + } + is_active[true_win] = TRUE; + is_new[true_win] = FALSE; - int active_pos = 1 + (win * 3); + int active_pos = 1 + ((true_win-1) * 3); int cols = getmaxx(stdscr); wattron(status_bar, COLOUR_STATUS_ACTIVE); - if (win+1 < 10) - mvwprintw(status_bar, 0, cols - 31 + active_pos, "%d", win+1); - else - mvwprintw(status_bar, 0, cols - 31 + active_pos, "0"); + + if (true_win == 10) { + mvwprintw(status_bar, 0, cols - 34 + active_pos, "0"); + } else if (true_win > 10) { + mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); + } else { + mvwprintw(status_bar, 0, cols - 34 + active_pos, "%d", true_win); + } + wattroff(status_bar, COLOUR_STATUS_ACTIVE); dirty = TRUE; @@ -162,19 +176,28 @@ status_bar_active(const int win) void status_bar_new(const int win) { - is_active[win] = TRUE; - is_new[win] = TRUE; + int true_win = win; + if (true_win == 0) { + true_win = 10; + } + is_active[true_win] = TRUE; + is_new[true_win] = TRUE; - int active_pos = 1 + (win * 3); + int active_pos = 1 + ((true_win-1) * 3); int cols = getmaxx(stdscr); wattron(status_bar, COLOUR_STATUS_NEW); wattron(status_bar, A_BLINK); - if (win+1 < 10) - mvwprintw(status_bar, 0, cols - 31 + active_pos, "%d", win+1); - else - mvwprintw(status_bar, 0, cols - 31 + active_pos, "0"); + + if (true_win == 10) { + mvwprintw(status_bar, 0, cols - 34 + active_pos, "0"); + } else if (true_win > 10) { + mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); + } else { + mvwprintw(status_bar, 0, cols - 34 + active_pos, "%d", true_win); + } + wattroff(status_bar, COLOUR_STATUS_NEW); wattroff(status_bar, A_BLINK); @@ -203,11 +226,11 @@ status_bar_print_message(const char * const msg) int cols = getmaxx(stdscr); wattron(status_bar, COLOUR_STATUS_BRACKET); - mvwprintw(status_bar, 0, cols - 31, _active); + mvwprintw(status_bar, 0, cols - 34, _active); wattroff(status_bar, COLOUR_STATUS_BRACKET); int i; - for(i = 0; i < 10; i++) { + for(i = 1; i < 12; i++) { if (is_new[i]) status_bar_new(i); else if (is_active[i]) @@ -226,9 +249,9 @@ status_bar_clear(void) } int i; - is_active[0] = TRUE; - is_new[0] = FALSE; - for (i = 1; i < 10; i++) { + is_active[1] = TRUE; + is_new[1] = FALSE; + for (i = 2; i < 12; i++) { is_active[i] = FALSE; is_new[i] = FALSE; } @@ -238,7 +261,7 @@ status_bar_clear(void) int cols = getmaxx(stdscr); wattron(status_bar, COLOUR_STATUS_BRACKET); - mvwprintw(status_bar, 0, cols - 31, _active); + mvwprintw(status_bar, 0, cols - 34, _active); wattroff(status_bar, COLOUR_STATUS_BRACKET); dirty = TRUE; @@ -257,11 +280,11 @@ status_bar_clear_message(void) int cols = getmaxx(stdscr); wattron(status_bar, COLOUR_STATUS_BRACKET); - mvwprintw(status_bar, 0, cols - 31, _active); + mvwprintw(status_bar, 0, cols - 34, _active); wattroff(status_bar, COLOUR_STATUS_BRACKET); int i; - for(i = 0; i < 10; i++) { + for(i = 1; i < 12; i++) { if (is_new[i]) status_bar_new(i); else if (is_active[i]) -- cgit 1.4.1-2-gfad0 From c08e85193cc2da6fc7a4a79b7ee5061b5e4f970b Mon Sep 17 00:00:00 2001 From: James Booth Date: Wed, 28 Aug 2013 21:29:11 +0100 Subject: Show correct window number for incoming in console --- src/ui/console.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ui/console.c b/src/ui/console.c index d0b340d9..92671a90 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -140,7 +140,8 @@ void cons_show_incoming_message(const char * const short_from, const int win_index) { ProfWin *console = wins_get_console(); - int ui_index = win_index + 1; + + int ui_index = win_index; if (ui_index == 10) { ui_index = 0; } -- cgit 1.4.1-2-gfad0 From a81d69dc7f2fb8cdeefad2ef605e5242b66b0050 Mon Sep 17 00:00:00 2001 From: James Booth Date: Wed, 28 Aug 2013 21:34:00 +0100 Subject: Fixed window number for notify and room incoming message --- src/ui/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/core.c b/src/ui/core.c index 21102eed..9dd72c4e 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -345,7 +345,7 @@ ui_incoming_msg(const char * const from, const char * const message, } } - int ui_index = num + 1; + int ui_index = num; if (ui_index == 10) { ui_index = 0; } @@ -1226,7 +1226,7 @@ ui_room_message(const char * const room_jid, const char * const nick, window->unread++; } - int ui_index = num + 1; + int ui_index = num; if (ui_index == 10) { ui_index = 0; } -- cgit 1.4.1-2-gfad0 From 88d4cf6e94980d6e44a0a55c84b3d2b7296b6f9a Mon Sep 17 00:00:00 2001 From: James Booth Date: Wed, 28 Aug 2013 21:45:46 +0100 Subject: Fixed test for requiring window tidy --- src/ui/windows.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/windows.c b/src/ui/windows.c index 0cd53c55..59563a79 100644 --- a/src/ui/windows.c +++ b/src/ui/windows.c @@ -319,8 +319,8 @@ wins_tidy(void) // find first free num TODO - Will sort again int next_available = get_next_available_win_num(keys); - // found gap (next available after last window) - if (cmp_win_num(GINT_TO_POINTER(next_available), GINT_TO_POINTER(last_num)) > 0) { + // found gap (next available before last window) + if (cmp_win_num(GINT_TO_POINTER(next_available), GINT_TO_POINTER(last_num)) < 0) { tidy_required = TRUE; } -- cgit 1.4.1-2-gfad0 From 30a4054937a56d8efcfccb3ba095d16c7c4d8800 Mon Sep 17 00:00:00 2001 From: James Booth Date: Wed, 28 Aug 2013 22:07:40 +0100 Subject: Fixed showing active console after login fail --- src/ui/statusbar.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ui/statusbar.c b/src/ui/statusbar.c index 90430e8d..46824fbe 100644 --- a/src/ui/statusbar.c +++ b/src/ui/statusbar.c @@ -87,6 +87,13 @@ status_bar_refresh(void) if (dirty) { _status_bar_update_time(); + int i; + for(i = 1; i < 12; i++) { + if (is_new[i]) + status_bar_new(i); + else if (is_active[i]) + status_bar_active(i); + } wrefresh(status_bar); inp_put_back(); dirty = FALSE; -- cgit 1.4.1-2-gfad0 From b7e7cb9c689ad1e8dcc334aa01576c8ce95206b0 Mon Sep 17 00:00:00 2001 From: James Booth Date: Wed, 28 Aug 2013 22:11:44 +0100 Subject: Refactor updating window statuses --- src/ui/statusbar.c | 48 ++++++++++++++++++------------------------------ 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/src/ui/statusbar.c b/src/ui/statusbar.c index 46824fbe..49cb0eae 100644 --- a/src/ui/statusbar.c +++ b/src/ui/statusbar.c @@ -45,6 +45,7 @@ static int dirty; static GDateTime *last_time; static void _status_bar_update_time(void); +static void _update_win_statuses(void); void create_status_bar(void) @@ -87,13 +88,7 @@ status_bar_refresh(void) if (dirty) { _status_bar_update_time(); - int i; - for(i = 1; i < 12; i++) { - if (is_new[i]) - status_bar_new(i); - else if (is_active[i]) - status_bar_active(i); - } + _update_win_statuses(); wrefresh(status_bar); inp_put_back(); dirty = FALSE; @@ -105,7 +100,7 @@ status_bar_refresh(void) void status_bar_resize(void) { - int rows, cols, i; + int rows, cols; getmaxyx(stdscr, rows, cols); mvwin(status_bar, rows-2, 0); @@ -116,12 +111,7 @@ status_bar_resize(void) mvwprintw(status_bar, 0, cols - 34, _active); wattroff(status_bar, COLOUR_STATUS_BRACKET); - for(i = 1; i < 12; i++) { - if (is_new[i]) - status_bar_new(i); - else if (is_active[i]) - status_bar_active(i); - } + _update_win_statuses(); if (message != NULL) mvwprintw(status_bar, 0, 10, message); @@ -236,14 +226,7 @@ status_bar_print_message(const char * const msg) mvwprintw(status_bar, 0, cols - 34, _active); wattroff(status_bar, COLOUR_STATUS_BRACKET); - int i; - for(i = 1; i < 12; i++) { - if (is_new[i]) - status_bar_new(i); - else if (is_active[i]) - status_bar_active(i); - } - + _update_win_statuses(); dirty = TRUE; } @@ -290,14 +273,7 @@ status_bar_clear_message(void) mvwprintw(status_bar, 0, cols - 34, _active); wattroff(status_bar, COLOUR_STATUS_BRACKET); - int i; - for(i = 1; i < 12; i++) { - if (is_new[i]) - status_bar_new(i); - else if (is_active[i]) - status_bar_active(i); - } - + _update_win_statuses(); dirty = TRUE; } @@ -319,3 +295,15 @@ _status_bar_update_time(void) dirty = TRUE; } + +static void +_update_win_statuses(void) +{ + int i; + for(i = 1; i < 12; i++) { + if (is_new[i]) + status_bar_new(i); + else if (is_active[i]) + status_bar_active(i); + } +} -- cgit 1.4.1-2-gfad0 From 8a35bae267f9a016e5266f8e6cce1413ab0c6813 Mon Sep 17 00:00:00 2001 From: James Booth Date: Wed, 28 Aug 2013 23:09:54 +0100 Subject: Fixes to windows tidy --- src/common.c | 1 - src/ui/windows.c | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/common.c b/src/common.c index ddb1c892..1131c4c9 100644 --- a/src/common.c +++ b/src/common.c @@ -439,7 +439,6 @@ get_next_available_win_num(GList *used) int curr_num = GPOINTER_TO_INT(curr->data); if (((last_num != 9) && ((last_num + 1) != curr_num)) || ((last_num == 9) && (curr_num != 0))) { - g_list_free(curr); result = last_num + 1; if (result == 10) { result = 0; diff --git a/src/ui/windows.c b/src/ui/windows.c index 59563a79..0bfb60a8 100644 --- a/src/ui/windows.c +++ b/src/ui/windows.c @@ -331,16 +331,16 @@ wins_tidy(void) int num = 1; GList *curr = keys; while (curr != NULL) { - ProfWin *window = g_hash_table_lookup(windows, GINT_TO_POINTER(curr->data)); + ProfWin *window = g_hash_table_lookup(windows, curr->data); if (num == 10) { - g_hash_table_insert(windows, GINT_TO_POINTER(0), window); + g_hash_table_insert(new_windows, GINT_TO_POINTER(0), window); if (window->unread > 0) { status_bar_new(0); } else { status_bar_active(0); } } else { - g_hash_table_insert(windows, GINT_TO_POINTER(num), window); + g_hash_table_insert(new_windows, GINT_TO_POINTER(num), window); if (window->unread > 0) { status_bar_new(num); } else { -- cgit 1.4.1-2-gfad0 From 4bfb369d2fe8295f3da008558a5580b9282c0f3c Mon Sep 17 00:00:00 2001 From: James Booth Date: Wed, 28 Aug 2013 23:23:46 +0100 Subject: Set all inactive before tidy --- src/ui/windows.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ui/windows.c b/src/ui/windows.c index 0bfb60a8..7b463ac1 100644 --- a/src/ui/windows.c +++ b/src/ui/windows.c @@ -325,6 +325,10 @@ wins_tidy(void) } if (tidy_required) { + int i = 0; + for (i = 0; i < 12; i++) { + status_bar_inactive(i); + } GHashTable *new_windows = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)win_free); -- cgit 1.4.1-2-gfad0 From a38953b6f8968ba41aab29e77c249b7168d83bd6 Mon Sep 17 00:00:00 2001 From: James Booth Date: Wed, 28 Aug 2013 23:32:54 +0100 Subject: Fixed /close command --- src/command/command.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/command/command.c b/src/command/command.c index 360daa07..bae6a7c3 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -3026,23 +3026,22 @@ _cmd_close(gchar **args, struct cmd_help_t help) return TRUE; } else { index = atoi(args[0]); - if (index == 0) { - index = 9; - } else if (index != 10) { - index--; - } } - if (index == 0) { - cons_show("Cannot close console window."); + if (index < 0 || index == 10) { + cons_show("No such window exists."); return TRUE; } - if (index > 9 || index < 0) { - cons_show("No such window exists."); + if (index == 1) { + cons_show("Cannot close console window."); return TRUE; } + if (index == 0) { + index = 10; + } + if (!ui_win_exists(index)) { cons_show("Window is not open."); return TRUE; @@ -3055,11 +3054,7 @@ _cmd_close(gchar **args, struct cmd_help_t help) // close the window ui_close_win(index); - int ui_index = index + 1; - if (ui_index == 10) { - ui_index = 0; - } - cons_show("Closed window %d", ui_index); + cons_show("Closed window %d", index); return TRUE; } -- cgit 1.4.1-2-gfad0 From 4738a15c89998ca0cae5621be652bb401721cdd5 Mon Sep 17 00:00:00 2001 From: James Booth Date: Thu, 29 Aug 2013 21:41:10 +0100 Subject: Added /win command to access unlimited windows --- src/command/command.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/command/command.c b/src/command/command.c index bae6a7c3..ef00fae8 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -143,6 +143,7 @@ static gboolean _cmd_tiny(gchar **args, struct cmd_help_t help); static gboolean _cmd_titlebar(gchar **args, struct cmd_help_t help); static gboolean _cmd_vercheck(gchar **args, struct cmd_help_t help); static gboolean _cmd_who(gchar **args, struct cmd_help_t help); +static gboolean _cmd_win(gchar **args, struct cmd_help_t help); static gboolean _cmd_wins(gchar **args, struct cmd_help_t help); static gboolean _cmd_xa(gchar **args, struct cmd_help_t help); @@ -409,6 +410,14 @@ static struct cmd_t command_defs[] = "Example : /nick bob", NULL } } }, + { "/win", + _cmd_win, parse_args, 1, 1, NULL, + { "/win num", "View a window.", + { "/win num", + "------------------", + "Show the contents of a specific window in the main window area.", + NULL } } }, + { "/wins", _cmd_wins, parse_args, 0, 1, NULL, { "/wins [tidy|prune]", "List or tidy active windows.", @@ -1662,6 +1671,19 @@ _cmd_wins(gchar **args, struct cmd_help_t help) return TRUE; } +static gboolean +_cmd_win(gchar **args, struct cmd_help_t help) +{ + int num = atoi(args[0]); + if (ui_win_exists(num)) { + ui_switch_win(num); + } else { + cons_show("Window %d does not exist.", num); + } + + return TRUE; +} + static gint _compare_commands(Command *a, Command *b) { -- cgit 1.4.1-2-gfad0 From f99504d0ecec272cc99d6c798476905b084b8f71 Mon Sep 17 00:00:00 2001 From: James Booth Date: Thu, 29 Aug 2013 23:57:34 +0100 Subject: Handle ">" indicator when more than 10 wins open --- src/ui/statusbar.c | 214 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 167 insertions(+), 47 deletions(-) diff --git a/src/ui/statusbar.c b/src/ui/statusbar.c index 49cb0eae..88a8bb22 100644 --- a/src/ui/statusbar.c +++ b/src/ui/statusbar.c @@ -40,7 +40,9 @@ static char *message = NULL; // 1 2 3 4 5 6 7 8 9 0 > static char _active[34] = "[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]"; static int is_active[12]; +static GHashTable *remaining_active; static int is_new[12]; +static GHashTable *remaining_new; static int dirty; static GDateTime *last_time; @@ -59,6 +61,8 @@ create_status_bar(void) is_active[i] = FALSE; is_new[i] = FALSE; } + remaining_active = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); + remaining_new = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); status_bar = newwin(1, cols, rows-2, 0); wbkgd(status_bar, COLOUR_STATUS_TEXT); @@ -129,16 +133,55 @@ status_bar_inactive(const int win) if (true_win == 0) { true_win = 10; } - is_active[true_win] = FALSE; - is_new[true_win] = FALSE; - int active_pos = 1 + ((true_win-1) * 3); - - int cols = getmaxx(stdscr); - - mvwaddch(status_bar, 0, cols - 34 + active_pos, ' '); - - dirty = TRUE; + // extra windows + if (true_win > 10) { + g_hash_table_remove(remaining_active, GINT_TO_POINTER(true_win)); + g_hash_table_remove(remaining_new, GINT_TO_POINTER(true_win)); + + // still have new windows + if (g_hash_table_size(remaining_new) != 0) { + is_active[11] = TRUE; + is_new[11] = TRUE; + int active_pos = 1 + ((11-1) * 3); + int cols = getmaxx(stdscr); + wattron(status_bar, COLOUR_STATUS_NEW); + wattron(status_bar, A_BLINK); + mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); + wattroff(status_bar, COLOUR_STATUS_NEW); + wattroff(status_bar, A_BLINK); + dirty = TRUE; + + // still have active winsows + } else if (g_hash_table_size(remaining_active) != 0) { + is_active[11] = TRUE; + is_new[11] = FALSE; + int active_pos = 1 + ((11-1) * 3); + int cols = getmaxx(stdscr); + wattron(status_bar, COLOUR_STATUS_ACTIVE); + mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); + wattroff(status_bar, COLOUR_STATUS_ACTIVE); + dirty = TRUE; + + // no active or new windows + } else { + is_active[11] = FALSE; + is_new[11] = FALSE; + int active_pos = 1 + ((11-1) * 3); + int cols = getmaxx(stdscr); + mvwaddch(status_bar, 0, cols - 34 + active_pos, ' '); + dirty = TRUE; + } + + // visible window indicators + } else { + is_active[true_win] = FALSE; + is_new[true_win] = FALSE; + int active_pos = 1 + ((true_win-1) * 3); + int cols = getmaxx(stdscr); + mvwaddch(status_bar, 0, cols - 34 + active_pos, ' '); + dirty = TRUE; + } } void @@ -148,26 +191,56 @@ status_bar_active(const int win) if (true_win == 0) { true_win = 10; } - is_active[true_win] = TRUE; - is_new[true_win] = FALSE; - - int active_pos = 1 + ((true_win-1) * 3); - - int cols = getmaxx(stdscr); - - wattron(status_bar, COLOUR_STATUS_ACTIVE); - if (true_win == 10) { - mvwprintw(status_bar, 0, cols - 34 + active_pos, "0"); - } else if (true_win > 10) { - mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); + // extra windows + if (true_win > 10) { + g_hash_table_add(remaining_active, GINT_TO_POINTER(true_win)); + g_hash_table_remove(remaining_new, GINT_TO_POINTER(true_win)); + + // still have new windows + if (g_hash_table_size(remaining_new) != 0) { + is_active[11] = TRUE; + is_new[11] = TRUE; + int active_pos = 1 + ((11-1) * 3); + int cols = getmaxx(stdscr); + wattron(status_bar, COLOUR_STATUS_NEW); + wattron(status_bar, A_BLINK); + mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); + wattroff(status_bar, COLOUR_STATUS_NEW); + wattroff(status_bar, A_BLINK); + dirty = TRUE; + + // only active windows + } else { + is_active[11] = TRUE; + is_new[11] = FALSE; + int active_pos = 1 + ((11-1) * 3); + int cols = getmaxx(stdscr); + wattron(status_bar, COLOUR_STATUS_ACTIVE); + mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); + wattroff(status_bar, COLOUR_STATUS_ACTIVE); + dirty = TRUE; + } + + // visible winsow indicators } else { - mvwprintw(status_bar, 0, cols - 34 + active_pos, "%d", true_win); + is_active[true_win] = TRUE; + is_new[true_win] = FALSE; + int active_pos = 1 + ((true_win-1) * 3); + int cols = getmaxx(stdscr); + wattron(status_bar, COLOUR_STATUS_ACTIVE); + + if (true_win == 10) { + mvwprintw(status_bar, 0, cols - 34 + active_pos, "0"); + } else if (true_win > 10) { + mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); + } else { + mvwprintw(status_bar, 0, cols - 34 + active_pos, "%d", true_win); + } + + wattroff(status_bar, COLOUR_STATUS_ACTIVE); + dirty = TRUE; } - - wattroff(status_bar, COLOUR_STATUS_ACTIVE); - - dirty = TRUE; } void @@ -177,28 +250,42 @@ status_bar_new(const int win) if (true_win == 0) { true_win = 10; } - is_active[true_win] = TRUE; - is_new[true_win] = TRUE; - - int active_pos = 1 + ((true_win-1) * 3); - - int cols = getmaxx(stdscr); - wattron(status_bar, COLOUR_STATUS_NEW); - wattron(status_bar, A_BLINK); + if (true_win > 10) { + g_hash_table_add(remaining_active, GINT_TO_POINTER(true_win)); + g_hash_table_add(remaining_new, GINT_TO_POINTER(true_win)); - if (true_win == 10) { - mvwprintw(status_bar, 0, cols - 34 + active_pos, "0"); - } else if (true_win > 10) { + is_active[11] = TRUE; + is_new[11] = TRUE; + int active_pos = 1 + ((11-1) * 3); + int cols = getmaxx(stdscr); + wattron(status_bar, COLOUR_STATUS_NEW); + wattron(status_bar, A_BLINK); mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); + wattroff(status_bar, COLOUR_STATUS_NEW); + wattroff(status_bar, A_BLINK); + dirty = TRUE; + } else { - mvwprintw(status_bar, 0, cols - 34 + active_pos, "%d", true_win); + is_active[true_win] = TRUE; + is_new[true_win] = TRUE; + int active_pos = 1 + ((true_win-1) * 3); + int cols = getmaxx(stdscr); + wattron(status_bar, COLOUR_STATUS_NEW); + wattron(status_bar, A_BLINK); + + if (true_win == 10) { + mvwprintw(status_bar, 0, cols - 34 + active_pos, "0"); + } else if (true_win > 10) { + mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); + } else { + mvwprintw(status_bar, 0, cols - 34 + active_pos, "%d", true_win); + } + + wattroff(status_bar, COLOUR_STATUS_NEW); + wattroff(status_bar, A_BLINK); + dirty = TRUE; } - - wattroff(status_bar, COLOUR_STATUS_NEW); - wattroff(status_bar, A_BLINK); - - dirty = TRUE; } void @@ -301,9 +388,42 @@ _update_win_statuses(void) { int i; for(i = 1; i < 12; i++) { - if (is_new[i]) - status_bar_new(i); - else if (is_active[i]) - status_bar_active(i); + if (is_new[i]) { + int active_pos = 1 + ((i-1) * 3); + int cols = getmaxx(stdscr); + wattron(status_bar, COLOUR_STATUS_NEW); + wattron(status_bar, A_BLINK); + + if (i == 10) { + mvwprintw(status_bar, 0, cols - 34 + active_pos, "0"); + } else if (i > 10) { + mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); + } else { + mvwprintw(status_bar, 0, cols - 34 + active_pos, "%d", i); + } + + wattroff(status_bar, COLOUR_STATUS_NEW); + wattroff(status_bar, A_BLINK); + } + else if (is_active[i]) { + int active_pos = 1 + ((i-1) * 3); + int cols = getmaxx(stdscr); + wattron(status_bar, COLOUR_STATUS_ACTIVE); + + if (i == 10) { + mvwprintw(status_bar, 0, cols - 34 + active_pos, "0"); + } else if (i > 10) { + mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); + } else { + mvwprintw(status_bar, 0, cols - 34 + active_pos, "%d", i); + } + + wattroff(status_bar, COLOUR_STATUS_ACTIVE); + } + else { + int active_pos = 1 + ((i-1) * 3); + int cols = getmaxx(stdscr); + mvwaddch(status_bar, 0, cols - 34 + active_pos, ' '); + } } } -- cgit 1.4.1-2-gfad0 From 00547bd1168305db242ac41a1ec9c7427c26ab16 Mon Sep 17 00:00:00 2001 From: James Booth Date: Fri, 30 Aug 2013 00:10:05 +0100 Subject: Refactored status bar indicators --- src/ui/statusbar.c | 165 +++++++++++++++++++---------------------------------- 1 file changed, 60 insertions(+), 105 deletions(-) diff --git a/src/ui/statusbar.c b/src/ui/statusbar.c index 88a8bb22..e4d61811 100644 --- a/src/ui/statusbar.c +++ b/src/ui/statusbar.c @@ -48,6 +48,9 @@ static GDateTime *last_time; static void _status_bar_update_time(void); static void _update_win_statuses(void); +static void _mark_new(int num); +static void _mark_active(int num); +static void _mark_inactive(int num); void create_status_bar(void) @@ -143,44 +146,26 @@ status_bar_inactive(const int win) if (g_hash_table_size(remaining_new) != 0) { is_active[11] = TRUE; is_new[11] = TRUE; - int active_pos = 1 + ((11-1) * 3); - int cols = getmaxx(stdscr); - wattron(status_bar, COLOUR_STATUS_NEW); - wattron(status_bar, A_BLINK); - mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); - wattroff(status_bar, COLOUR_STATUS_NEW); - wattroff(status_bar, A_BLINK); - dirty = TRUE; + _mark_new(11); // still have active winsows } else if (g_hash_table_size(remaining_active) != 0) { is_active[11] = TRUE; is_new[11] = FALSE; - int active_pos = 1 + ((11-1) * 3); - int cols = getmaxx(stdscr); - wattron(status_bar, COLOUR_STATUS_ACTIVE); - mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); - wattroff(status_bar, COLOUR_STATUS_ACTIVE); - dirty = TRUE; + _mark_active(11); // no active or new windows } else { is_active[11] = FALSE; is_new[11] = FALSE; - int active_pos = 1 + ((11-1) * 3); - int cols = getmaxx(stdscr); - mvwaddch(status_bar, 0, cols - 34 + active_pos, ' '); - dirty = TRUE; + _mark_inactive(11); } // visible window indicators } else { is_active[true_win] = FALSE; is_new[true_win] = FALSE; - int active_pos = 1 + ((true_win-1) * 3); - int cols = getmaxx(stdscr); - mvwaddch(status_bar, 0, cols - 34 + active_pos, ' '); - dirty = TRUE; + _mark_inactive(true_win); } } @@ -201,45 +186,20 @@ status_bar_active(const int win) if (g_hash_table_size(remaining_new) != 0) { is_active[11] = TRUE; is_new[11] = TRUE; - int active_pos = 1 + ((11-1) * 3); - int cols = getmaxx(stdscr); - wattron(status_bar, COLOUR_STATUS_NEW); - wattron(status_bar, A_BLINK); - mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); - wattroff(status_bar, COLOUR_STATUS_NEW); - wattroff(status_bar, A_BLINK); - dirty = TRUE; + _mark_new(11); // only active windows } else { is_active[11] = TRUE; is_new[11] = FALSE; - int active_pos = 1 + ((11-1) * 3); - int cols = getmaxx(stdscr); - wattron(status_bar, COLOUR_STATUS_ACTIVE); - mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); - wattroff(status_bar, COLOUR_STATUS_ACTIVE); - dirty = TRUE; + _mark_active(11); } // visible winsow indicators } else { is_active[true_win] = TRUE; is_new[true_win] = FALSE; - int active_pos = 1 + ((true_win-1) * 3); - int cols = getmaxx(stdscr); - wattron(status_bar, COLOUR_STATUS_ACTIVE); - - if (true_win == 10) { - mvwprintw(status_bar, 0, cols - 34 + active_pos, "0"); - } else if (true_win > 10) { - mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); - } else { - mvwprintw(status_bar, 0, cols - 34 + active_pos, "%d", true_win); - } - - wattroff(status_bar, COLOUR_STATUS_ACTIVE); - dirty = TRUE; + _mark_active(true_win); } } @@ -257,34 +217,12 @@ status_bar_new(const int win) is_active[11] = TRUE; is_new[11] = TRUE; - int active_pos = 1 + ((11-1) * 3); - int cols = getmaxx(stdscr); - wattron(status_bar, COLOUR_STATUS_NEW); - wattron(status_bar, A_BLINK); - mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); - wattroff(status_bar, COLOUR_STATUS_NEW); - wattroff(status_bar, A_BLINK); - dirty = TRUE; + _mark_new(11); } else { is_active[true_win] = TRUE; is_new[true_win] = TRUE; - int active_pos = 1 + ((true_win-1) * 3); - int cols = getmaxx(stdscr); - wattron(status_bar, COLOUR_STATUS_NEW); - wattron(status_bar, A_BLINK); - - if (true_win == 10) { - mvwprintw(status_bar, 0, cols - 34 + active_pos, "0"); - } else if (true_win > 10) { - mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); - } else { - mvwprintw(status_bar, 0, cols - 34 + active_pos, "%d", true_win); - } - - wattroff(status_bar, COLOUR_STATUS_NEW); - wattroff(status_bar, A_BLINK); - dirty = TRUE; + _mark_new(true_win); } } @@ -389,41 +327,58 @@ _update_win_statuses(void) int i; for(i = 1; i < 12; i++) { if (is_new[i]) { - int active_pos = 1 + ((i-1) * 3); - int cols = getmaxx(stdscr); - wattron(status_bar, COLOUR_STATUS_NEW); - wattron(status_bar, A_BLINK); - - if (i == 10) { - mvwprintw(status_bar, 0, cols - 34 + active_pos, "0"); - } else if (i > 10) { - mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); - } else { - mvwprintw(status_bar, 0, cols - 34 + active_pos, "%d", i); - } - - wattroff(status_bar, COLOUR_STATUS_NEW); - wattroff(status_bar, A_BLINK); + _mark_new(i); } else if (is_active[i]) { - int active_pos = 1 + ((i-1) * 3); - int cols = getmaxx(stdscr); - wattron(status_bar, COLOUR_STATUS_ACTIVE); - - if (i == 10) { - mvwprintw(status_bar, 0, cols - 34 + active_pos, "0"); - } else if (i > 10) { - mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); - } else { - mvwprintw(status_bar, 0, cols - 34 + active_pos, "%d", i); - } - - wattroff(status_bar, COLOUR_STATUS_ACTIVE); + _mark_active(i); } else { - int active_pos = 1 + ((i-1) * 3); - int cols = getmaxx(stdscr); - mvwaddch(status_bar, 0, cols - 34 + active_pos, ' '); + _mark_inactive(i); } } } + +static void +_mark_new(int num) +{ + int active_pos = 1 + ((num-1) * 3); + int cols = getmaxx(stdscr); + wattron(status_bar, COLOUR_STATUS_NEW); + wattron(status_bar, A_BLINK); + if (num == 10) { + mvwprintw(status_bar, 0, cols - 34 + active_pos, "0"); + } else if (num > 10) { + mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); + } else { + mvwprintw(status_bar, 0, cols - 34 + active_pos, "%d", num); + } + wattroff(status_bar, COLOUR_STATUS_NEW); + wattroff(status_bar, A_BLINK); + dirty = TRUE; +} + +static void +_mark_active(int num) +{ + int active_pos = 1 + ((num-1) * 3); + int cols = getmaxx(stdscr); + wattron(status_bar, COLOUR_STATUS_ACTIVE); + if (num == 10) { + mvwprintw(status_bar, 0, cols - 34 + active_pos, "0"); + } else if (num > 10) { + mvwprintw(status_bar, 0, cols - 34 + active_pos, ">"); + } else { + mvwprintw(status_bar, 0, cols - 34 + active_pos, "%d", num); + } + wattroff(status_bar, COLOUR_STATUS_ACTIVE); + dirty = TRUE; +} + +static void +_mark_inactive(int num) +{ + int active_pos = 1 + ((num-1) * 3); + int cols = getmaxx(stdscr); + mvwaddch(status_bar, 0, cols - 34 + active_pos, ' '); + dirty = TRUE; +} -- cgit 1.4.1-2-gfad0 From 48794e324c19f2492593a440e26f8b29f4a4515e Mon Sep 17 00:00:00 2001 From: James Booth Date: Fri, 30 Aug 2013 00:21:41 +0100 Subject: Fix count on /close all, and /close read --- src/ui/core.c | 5 ++--- src/ui/windows.c | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ui/core.c b/src/ui/core.c index 9dd72c4e..c97ce67e 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -531,7 +531,7 @@ ui_close_all_wins(void) int curr = 0, count = 0; jabber_conn_status_t conn_status = jabber_get_connection_status(); - for (curr = 1; curr <= 9; curr++) { + for (curr = 2; curr <= 10; curr++) { if (ui_win_exists(curr)) { if (conn_status == JABBER_CONNECTED) { ui_close_connected_win(curr); @@ -550,7 +550,7 @@ ui_close_read_wins(void) int curr = 0, count = 0; jabber_conn_status_t conn_status = jabber_get_connection_status(); - for (curr = 1; curr <= 9; curr++) { + for (curr = 2; curr <= 10; curr++) { if (ui_win_exists(curr) && (ui_win_unread(curr) == 0)) { if (conn_status == JABBER_CONNECTED) { ui_close_connected_win(curr); @@ -615,7 +615,6 @@ void ui_close_win(int index) { wins_close_by_num(index); - status_bar_inactive(index); status_bar_active(1); title_bar_title(); diff --git a/src/ui/windows.c b/src/ui/windows.c index 7b463ac1..58e1ec59 100644 --- a/src/ui/windows.c +++ b/src/ui/windows.c @@ -140,6 +140,7 @@ wins_close_by_num(int i) wins_refresh_current(); } g_hash_table_remove(windows, GINT_TO_POINTER(i)); + status_bar_inactive(i); } } -- cgit 1.4.1-2-gfad0 From 7f476b3e2cb4739adb6b5ea02a9b86f19637b819 Mon Sep 17 00:00:00 2001 From: James Booth Date: Fri, 30 Aug 2013 00:33:46 +0100 Subject: Fixed /close all and /close read to close extra windows --- src/ui/core.c | 36 ++++++++++++++++++++++++++---------- src/ui/windows.c | 6 ++++++ src/ui/windows.h | 1 + 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/ui/core.c b/src/ui/core.c index c97ce67e..d6e17854 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -528,38 +528,54 @@ ui_close_connected_win(int index) int ui_close_all_wins(void) { - int curr = 0, count = 0; + int count = 0; jabber_conn_status_t conn_status = jabber_get_connection_status(); - for (curr = 2; curr <= 10; curr++) { - if (ui_win_exists(curr)) { + GList *win_nums = wins_get_nums(); + GList *curr = win_nums; + + while (curr != NULL) { + int num = GPOINTER_TO_INT(curr->data); + if (num != 1) { if (conn_status == JABBER_CONNECTED) { - ui_close_connected_win(curr); + ui_close_connected_win(num); } - ui_close_win(curr); + ui_close_win(num); count++; } + curr = g_list_next(curr); } + g_list_free(curr); + g_list_free(win_nums); + return count; } int ui_close_read_wins(void) { - int curr = 0, count = 0; + int count = 0; jabber_conn_status_t conn_status = jabber_get_connection_status(); - for (curr = 2; curr <= 10; curr++) { - if (ui_win_exists(curr) && (ui_win_unread(curr) == 0)) { + GList *win_nums = wins_get_nums(); + GList *curr = win_nums; + + while (curr != NULL) { + int num = GPOINTER_TO_INT(curr->data); + if ((num != 1) && (ui_win_unread(num) == 0)) { if (conn_status == JABBER_CONNECTED) { - ui_close_connected_win(curr); + ui_close_connected_win(num); } - ui_close_win(curr); + ui_close_win(num); count++; } + curr = g_list_next(curr); } + g_list_free(curr); + g_list_free(win_nums); + return count; } diff --git a/src/ui/windows.c b/src/ui/windows.c index 58e1ec59..81a6d3e6 100644 --- a/src/ui/windows.c +++ b/src/ui/windows.c @@ -70,6 +70,12 @@ wins_get_current(void) return g_hash_table_lookup(windows, GINT_TO_POINTER(current)); } +GList * +wins_get_nums(void) +{ + return g_hash_table_get_keys(windows); +} + void wins_set_current_by_num(int i) { diff --git a/src/ui/windows.h b/src/ui/windows.h index f0476896..6d93c434 100644 --- a/src/ui/windows.h +++ b/src/ui/windows.h @@ -47,5 +47,6 @@ void wins_lost_connection(void); gboolean wins_tidy(void); GSList * wins_create_summary(void); void wins_destroy(void); +GList * wins_get_nums(void); #endif -- cgit 1.4.1-2-gfad0 From 4ae817cd8292f964ef1c45bfa3b70544ce23043f Mon Sep 17 00:00:00 2001 From: James Booth Date: Fri, 30 Aug 2013 00:49:38 +0100 Subject: Fixed ">" indicator when tidying windows --- src/ui/core.c | 2 +- src/ui/statusbar.c | 14 ++++++++++++++ src/ui/ui.h | 1 + src/ui/windows.c | 5 +---- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/ui/core.c b/src/ui/core.c index d6e17854..2229d37c 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -621,8 +621,8 @@ void ui_close_current(void) { int current_index = wins_get_current_num(); - wins_close_current(); status_bar_inactive(current_index); + wins_close_current(); status_bar_active(1); title_bar_title(); } diff --git a/src/ui/statusbar.c b/src/ui/statusbar.c index e4d61811..e7456adc 100644 --- a/src/ui/statusbar.c +++ b/src/ui/statusbar.c @@ -129,6 +129,20 @@ status_bar_resize(void) dirty = TRUE; } +void +status_bar_set_all_inactive(void) +{ + int i = 0; + for (i = 0; i < 12; i++) { + is_active[i] = FALSE; + is_new[i] = FALSE; + _mark_inactive(i); + } + + g_hash_table_remove_all(remaining_active); + g_hash_table_remove_all(remaining_new); +} + void status_bar_inactive(const int win) { diff --git a/src/ui/ui.h b/src/ui/ui.h index 157f8ad3..fa74bed6 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -225,6 +225,7 @@ void status_bar_inactive(const int win); void status_bar_active(const int win); void status_bar_new(const int win); void status_bar_update_time(void); +void status_bar_set_all_inactive(void); // input window actions wint_t inp_get_char(char *input, int *size); diff --git a/src/ui/windows.c b/src/ui/windows.c index 81a6d3e6..e956068c 100644 --- a/src/ui/windows.c +++ b/src/ui/windows.c @@ -332,10 +332,7 @@ wins_tidy(void) } if (tidy_required) { - int i = 0; - for (i = 0; i < 12; i++) { - status_bar_inactive(i); - } + status_bar_set_all_inactive(); GHashTable *new_windows = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)win_free); -- cgit 1.4.1-2-gfad0