diff --git a/Makefile.am b/Makefile.am
index fade94a3..fae529e9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -14,6 +14,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 \
@@ -42,6 +43,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/command/command.c b/src/command/command.c
index 83f0e5b5..586cdb52 100644
--- a/src/command/command.c
+++ b/src/command/command.c
@@ -144,6 +144,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);
@@ -410,6 +411,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.",
@@ -1196,8 +1205,6 @@ cmd_execute_default(const char * const inp)
break;
}
- free(recipient);
-
return TRUE;
}
@@ -1226,7 +1233,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" } ;
@@ -1559,7 +1565,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];
@@ -1583,49 +1589,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));
}
}
@@ -1634,7 +1638,8 @@ _cmd_sub(gchar **args, struct cmd_help_t help)
cons_show("Usage: %s", help.usage);
}
- free(jid);
+ jid_destroy(jidp);
+
return TRUE;
}
@@ -1673,6 +1678,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)
{
@@ -1833,7 +1851,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;
}
@@ -2016,8 +2034,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("");
@@ -2137,7 +2153,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;
@@ -2157,11 +2173,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)) {
@@ -2182,8 +2193,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 {
@@ -2421,11 +2430,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();
@@ -2581,8 +2585,6 @@ _cmd_info(gchar **args, struct cmd_help_t help)
break;
}
- free(recipient);
-
return TRUE;
}
@@ -2611,7 +2613,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.");
}
@@ -2652,7 +2653,6 @@ _cmd_caps(gchar **args, struct cmd_help_t help)
cons_show_caps(jid->resourcepart, resource);
jid_destroy(jid);
}
- free(recipient);
}
break;
default:
@@ -2689,7 +2689,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.");
}
@@ -2715,7 +2714,6 @@ _cmd_software(gchar **args, struct cmd_help_t help)
} else {
recipient = ui_current_recipient();
iq_send_software_version(recipient);
- free(recipient);
}
break;
default:
@@ -2735,11 +2733,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");
@@ -2887,7 +2880,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;
@@ -2913,7 +2905,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);
@@ -2928,10 +2919,6 @@ _cmd_bookmark(gchar **args, struct cmd_help_t help)
} else {
cons_show("Usage: %s", help.usage);
}
-
- if (jid_release) {
- free(jid);
- }
}
return TRUE;
@@ -3024,16 +3011,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 {
@@ -3058,21 +3042,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) {
@@ -3082,15 +3057,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) {
@@ -3101,21 +3068,20 @@ _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) {
+ if (index < 0 || index == 10) {
+ cons_show("No such window exists.");
+ return TRUE;
+ }
+
+ if (index == 1) {
cons_show("Cannot close console window.");
return TRUE;
}
- if (index > 9 || index < 0) {
- cons_show("No such window exists.");
- return TRUE;
+ if (index == 0) {
+ index = 10;
}
if (!ui_win_exists(index)) {
@@ -3123,7 +3089,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);
@@ -3131,11 +3096,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;
}
diff --git a/src/common.c b/src/common.c
index c7ec7d0b..1131c4c9 100644
--- a/src/common.c
+++ b/src/common.c
@@ -399,6 +399,69 @@ 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(GList *used)
+{
+ int result = 0;
+ used = g_list_sort(used, cmp_win_num);
+ // only console used
+ if (g_list_length(used) == 1) {
+ return 2;
+ } else {
+ int last_num = 1;
+ GList *curr = used;
+ // skip console
+ 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))) {
+ 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_list_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..b1b6834e 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(GList *used);
+
#endif
diff --git a/src/ui/console.c b/src/ui/console.c
index 42c4e080..92671a90 100644
--- a/src/ui/console.c
+++ b/src/ui/console.c
@@ -35,42 +35,34 @@
#include "config/theme.h"
#include "ui/notifier.h"
#include "ui/window.h"
+#include "ui/windows.h"
#include "ui/ui.h"
#include "xmpp/xmpp.h"
#include "xmpp/bookmark.h"
-#define CONS_WIN_TITLE "_cons"
-
-static ProfWin* console;
-
static void _cons_splash_logo(void);
void _show_roster_contacts(GSList *list, gboolean show_groups);
-ProfWin *
-cons_create(void)
-{
- int cols = getmaxx(stdscr);
- console = win_create(CONS_WIN_TITLE, cols, WIN_CONSOLE);
- return console;
-}
-
void
cons_show_time(void)
{
+ ProfWin *console = wins_get_console();
win_print_time(console, '-');
- ui_console_dirty();
+ wins_refresh_console();
}
void
cons_show_word(const char * const word)
{
+ ProfWin *console = wins_get_console();
wprintw(console->win, "%s", word);
- ui_console_dirty();
+ wins_refresh_console();
}
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);
@@ -81,7 +73,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();
@@ -92,6 +84,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);
@@ -100,12 +93,13 @@ 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
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);
@@ -117,13 +111,14 @@ cons_show_error(const char * const msg, ...)
g_string_free(fmt_msg, TRUE);
va_end(arg);
- ui_console_dirty();
+ wins_refresh_console();
cons_alert();
}
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) {
@@ -137,14 +132,16 @@ 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();
}
void
cons_show_incoming_message(const char * const short_from, const int win_index)
{
- int ui_index = win_index + 1;
+ ProfWin *console = wins_get_console();
+
+ int ui_index = win_index;
if (ui_index == 10) {
ui_index = 0;
}
@@ -153,13 +150,14 @@ 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();
}
void
cons_about(void)
{
+ ProfWin *console = wins_get_console();
int rows, cols;
getmaxyx(stdscr, rows, cols);
@@ -198,13 +196,14 @@ cons_about(void)
prefresh(console->win, 0, 0, 1, 0, rows-3, cols-1);
- ui_console_dirty();
+ wins_refresh_console();
cons_alert();
}
void
cons_check_version(gboolean not_available_msg)
{
+ ProfWin *console = wins_get_console();
char *latest_release = release_get_latest();
if (latest_release != NULL) {
@@ -226,7 +225,7 @@ cons_check_version(gboolean not_available_msg)
}
}
- ui_console_dirty();
+ wins_refresh_console();
cons_alert();
}
}
@@ -235,6 +234,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);
@@ -247,91 +247,28 @@ 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;
-
+ ProfWin *console = wins_get_console();
cons_show("");
cons_show("Active windows:");
- win_print_time(console, '-');
- wprintw(console->win, "1: Console\n");
+ GSList *window_strings = wins_create_summary();
- 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);
- }
-
- 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();
}
@@ -349,13 +286,14 @@ cons_show_room_invites(GSList *invites)
}
}
- ui_console_dirty();
+ wins_refresh_console();
cons_alert();
}
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);
@@ -481,13 +419,14 @@ cons_show_info(PContact pcontact)
ordered_resources = g_list_next(ordered_resources);
}
- ui_console_dirty();
+ wins_refresh_console();
cons_alert();
}
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);
@@ -555,7 +494,7 @@ cons_show_caps(const char * const contact, Resource *resource)
}
}
- ui_console_dirty();
+ wins_refresh_console();
cons_alert();
}
@@ -563,6 +502,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, '-');
@@ -581,7 +521,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();
}
@@ -600,6 +540,9 @@ cons_show_received_subs(void)
}
g_slist_free_full(received, g_free);
}
+
+ wins_refresh_console();
+ cons_alert();
}
void
@@ -619,11 +562,15 @@ cons_show_sent_subs(void)
} else {
cons_show("No pending requests sent.");
}
+
+ wins_refresh_console();
+ cons_alert();
}
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) {
@@ -640,7 +587,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();
}
@@ -656,6 +603,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) {
@@ -668,7 +617,7 @@ cons_show_bookmarks(const GList *list)
list = g_list_next(list);
}
- ui_console_dirty();
+ wins_refresh_console();
cons_alert();
}
@@ -710,7 +659,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();
}
}
@@ -718,6 +667,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);
@@ -735,13 +685,14 @@ 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();
}
void
cons_show_status(const char * const barejid)
{
+ ProfWin *console = wins_get_console();
PContact pcontact = roster_get_contact(barejid);
if (pcontact != NULL) {
@@ -749,7 +700,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();
}
@@ -786,13 +737,14 @@ cons_show_room_invite(const char * const invitor, const char * const room,
free(display_from);
- ui_console_dirty();
+ wins_refresh_console();
cons_alert();
}
void
cons_show_account_list(gchar **accounts)
{
+ ProfWin *console = wins_get_console();
int size = g_strv_length(accounts);
if (size > 0) {
cons_show("Accounts:");
@@ -815,13 +767,14 @@ cons_show_account_list(gchar **accounts)
cons_show("");
}
- ui_console_dirty();
+ wins_refresh_console();
cons_alert();
}
void
cons_show_account(ProfAccount *account)
{
+ ProfWin *console = wins_get_console();
cons_show("");
cons_show("Account %s:", account->name);
if (account->enabled) {
@@ -928,7 +881,7 @@ cons_show_account(ProfAccount *account)
}
}
- ui_console_dirty();
+ wins_refresh_console();
cons_alert();
}
@@ -1021,7 +974,7 @@ cons_show_ui_prefs(void)
cons_statuses_setting();
cons_titlebar_setting();
- ui_console_dirty();
+ wins_refresh_console();
cons_alert();
}
@@ -1065,7 +1018,7 @@ cons_show_desktop_prefs(void)
cons_show("");
cons_notify_setting();
- ui_console_dirty();
+ wins_refresh_console();
cons_alert();
}
@@ -1129,7 +1082,7 @@ cons_show_chat_prefs(void)
cons_gone_setting();
cons_history_setting();
- ui_console_dirty();
+ wins_refresh_console();
cons_alert();
}
@@ -1166,7 +1119,7 @@ cons_show_log_prefs(void)
cons_chlog_setting();
cons_grlog_setting();
- ui_console_dirty();
+ wins_refresh_console();
cons_alert();
}
@@ -1202,7 +1155,7 @@ cons_show_presence_prefs(void)
cons_show("");
cons_autoaway_setting();
- ui_console_dirty();
+ wins_refresh_console();
cons_alert();
}
@@ -1247,7 +1200,7 @@ cons_show_connection_prefs(void)
cons_reconnect_setting();
cons_autoping_setting();
- ui_console_dirty();
+ wins_refresh_console();
cons_alert();
}
@@ -1266,7 +1219,7 @@ cons_show_themes(GSList *themes)
}
}
- ui_console_dirty();
+ wins_refresh_console();
cons_alert();
}
@@ -1287,7 +1240,7 @@ cons_prefs(void)
cons_show_connection_prefs();
cons_show("");
- ui_console_dirty();
+ wins_refresh_console();
cons_alert();
}
@@ -1310,7 +1263,7 @@ cons_help(void)
cons_show("/help [command] - Detailed help on a specific command.");
cons_show("");
- ui_console_dirty();
+ wins_refresh_console();
cons_alert();
}
@@ -1332,13 +1285,120 @@ cons_navigation_help(void)
cons_show("PAGE UP, PAGE DOWN : Page the main window.");
cons_show("");
- ui_console_dirty();
+ wins_refresh_console();
cons_alert();
}
+void
+cons_show_roster_group(const char * const group, GSList *list)
+{
+ cons_show("");
+
+ if (list != NULL) {
+ cons_show("%s:", group);
+ } else {
+ cons_show("No group named %s exists.", group);
+ }
+
+ _show_roster_contacts(list, FALSE);
+ wins_refresh_console();
+ cons_alert();
+}
+
+void
+cons_show_roster(GSList *list)
+{
+ cons_show("");
+ cons_show("Roster:");
+
+ _show_roster_contacts(list, TRUE);
+ wins_refresh_console();
+ cons_alert();
+}
+
+void
+cons_show_contacts(GSList *list)
+{
+ ProfWin *console = wins_get_console();
+ GSList *curr = list;
+
+ while(curr) {
+ PContact contact = curr->data;
+ if ((strcmp(p_contact_subscription(contact), "to") == 0) ||
+ (strcmp(p_contact_subscription(contact), "both") == 0)) {
+ win_show_contact(console, contact);
+ }
+ curr = g_slist_next(curr);
+ }
+
+ wins_refresh_console();
+ cons_alert();
+}
+
+void
+cons_alert(void)
+{
+ if (ui_current_win_type() != WIN_CONSOLE) {
+ status_bar_new(1);
+ }
+}
+
+static void
+_cons_splash_logo(void)
+{
+ ProfWin *console = wins_get_console();
+ win_print_time(console, '-');
+ wprintw(console->win, "Welcome to\n");
+
+ win_print_time(console, '-');
+ wattron(console->win, COLOUR_SPLASH);
+ wprintw(console->win, " ___ _ \n");
+ wattroff(console->win, COLOUR_SPLASH);
+
+ win_print_time(console, '-');
+ wattron(console->win, COLOUR_SPLASH);
+ wprintw(console->win, " / __) (_)_ \n");
+ wattroff(console->win, COLOUR_SPLASH);
+
+ win_print_time(console, '-');
+ wattron(console->win, COLOUR_SPLASH);
+ wprintw(console->win, " ____ ____ ___ | |__ ____ ____ _| |_ _ _ \n");
+ wattroff(console->win, COLOUR_SPLASH);
+
+ win_print_time(console, '-');
+ wattron(console->win, COLOUR_SPLASH);
+ wprintw(console->win, "| _ \\ / ___) _ \\| __) _ | _ \\| | _) | | |\n");
+ wattroff(console->win, COLOUR_SPLASH);
+
+ win_print_time(console, '-');
+ wattron(console->win, COLOUR_SPLASH);
+ wprintw(console->win, "| | | | | | |_| | | ( ( | | | | | | |_| |_| |\n");
+ wattroff(console->win, COLOUR_SPLASH);
+
+ win_print_time(console, '-');
+ wattron(console->win, COLOUR_SPLASH);
+ wprintw(console->win, "| ||_/|_| \\___/|_| \\_||_|_| |_|_|\\___)__ |\n");
+ wattroff(console->win, COLOUR_SPLASH);
+
+ win_print_time(console, '-');
+ wattron(console->win, COLOUR_SPLASH);
+ wprintw(console->win, "|_| (____/ \n");
+ wattroff(console->win, COLOUR_SPLASH);
+
+ win_print_time(console, '-');
+ wprintw(console->win, "\n");
+ win_print_time(console, '-');
+ if (strcmp(PACKAGE_STATUS, "development") == 0) {
+ wprintw(console->win, "Version %sdev\n", PACKAGE_VERSION);
+ } else {
+ 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) {
@@ -1410,107 +1470,3 @@ _show_roster_contacts(GSList *list, gboolean show_groups)
}
}
-
-void
-cons_show_roster_group(const char * const group, GSList *list)
-{
- cons_show("");
-
- if (list != NULL) {
- cons_show("%s:", group);
- } else {
- cons_show("No group named %s exists.", group);
- }
-
- _show_roster_contacts(list, FALSE);
- ui_console_dirty();
- cons_alert();
-}
-
-void
-cons_show_roster(GSList *list)
-{
- cons_show("");
- cons_show("Roster:");
-
- _show_roster_contacts(list, TRUE);
- ui_console_dirty();
- cons_alert();
-}
-
-void
-cons_show_contacts(GSList *list)
-{
- GSList *curr = list;
-
- while(curr) {
- PContact contact = curr->data;
- if ((strcmp(p_contact_subscription(contact), "to") == 0) ||
- (strcmp(p_contact_subscription(contact), "both") == 0)) {
- win_show_contact(console, contact);
- }
- curr = g_slist_next(curr);
- }
-
- ui_console_dirty();
- cons_alert();
-}
-
-void
-cons_alert(void)
-{
- if (ui_current_win_type() != WIN_CONSOLE) {
- status_bar_new(0);
- }
-}
-
-static void
-_cons_splash_logo(void)
-{
- win_print_time(console, '-');
- wprintw(console->win, "Welcome to\n");
-
- win_print_time(console, '-');
- wattron(console->win, COLOUR_SPLASH);
- wprintw(console->win, " ___ _ \n");
- wattroff(console->win, COLOUR_SPLASH);
-
- win_print_time(console, '-');
- wattron(console->win, COLOUR_SPLASH);
- wprintw(console->win, " / __) (_)_ \n");
- wattroff(console->win, COLOUR_SPLASH);
-
- win_print_time(console, '-');
- wattron(console->win, COLOUR_SPLASH);
- wprintw(console->win, " ____ ____ ___ | |__ ____ ____ _| |_ _ _ \n");
- wattroff(console->win, COLOUR_SPLASH);
-
- win_print_time(console, '-');
- wattron(console->win, COLOUR_SPLASH);
- wprintw(console->win, "| _ \\ / ___) _ \\| __) _ | _ \\| | _) | | |\n");
- wattroff(console->win, COLOUR_SPLASH);
-
- win_print_time(console, '-');
- wattron(console->win, COLOUR_SPLASH);
- wprintw(console->win, "| | | | | | |_| | | ( ( | | | | | | |_| |_| |\n");
- wattroff(console->win, COLOUR_SPLASH);
-
- win_print_time(console, '-');
- wattron(console->win, COLOUR_SPLASH);
- wprintw(console->win, "| ||_/|_| \\___/|_| \\_||_|_| |_|_|\\___)__ |\n");
- wattroff(console->win, COLOUR_SPLASH);
-
- win_print_time(console, '-');
- wattron(console->win, COLOUR_SPLASH);
- wprintw(console->win, "|_| (____/ \n");
- wattroff(console->win, COLOUR_SPLASH);
-
- win_print_time(console, '-');
- wprintw(console->win, "\n");
- win_print_time(console, '-');
- if (strcmp(PACKAGE_STATUS, "development") == 0) {
- wprintw(console->win, "Version %sdev\n", PACKAGE_VERSION);
- } else {
- wprintw(console->win, "Version %s\n", PACKAGE_VERSION);
- }
-}
diff --git a/src/ui/core.c b/src/ui/core.c
index e73c0a67..2229d37c 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)
@@ -101,45 +85,27 @@ ui_init(void)
refresh();
create_title_bar();
create_status_bar();
- status_bar_active(0);
+ status_bar_active(1);
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)
{
@@ -169,6 +135,7 @@ void
ui_close(void)
{
notifier_uninit();
+ wins_destroy();
endwin();
}
@@ -178,9 +145,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
@@ -194,59 +161,41 @@ ui_load_colours(void)
}
gboolean
-ui_windows_full(void)
+ui_win_exists(int index)
{
- int i;
- for (i = 1; i < NUM_WINS; i++) {
- if (windows[i] == NULL) {
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-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 +214,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);
- // 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);
-
- 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 (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);
}
+
+ curr = g_slist_next(curr);
+ }
+
+ if (recipients != NULL) {
+ g_slist_free(recipients);
}
}
@@ -313,123 +265,87 @@ 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;
}
- // no spare windows left
- if (win_index == 0) {
+ int num = wins_get_num(window);
+
+ // 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);
+ 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(console->win, display_from, 1);
- _win_show_message(console->win, message);
+ _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();
- cons_show("Windows all used, close a window to respond.");
-
- if (current_index == 0) {
- current_win_dirty = TRUE;
- } else {
- status_bar_new(0);
- }
-
- // window found or created
+ // not currently viewing chat window with sender
} else {
- ProfWin *window = windows[win_index];
+ status_bar_new(num);
+ cons_show_incoming_message(display_from, num);
+ if (prefs_get_boolean(PREF_FLASH))
+ flash();
- // currently viewing chat window with sender
- if (win_index == current_index) {
- 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);
- }
+ window->unread++;
+ if (prefs_get_boolean(PREF_CHLOG) && prefs_get_boolean(PREF_HISTORY)) {
+ _win_show_history(window->win, num, from);
+ }
- 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(win_index);
- current_win_dirty = TRUE;
-
- // not currently viewing chat window with sender
+ if (tv_stamp == NULL) {
+ win_print_time(window, '-');
} else {
- status_bar_new(win_index);
- cons_show_incoming_message(display_from, win_index);
- if (prefs_get_boolean(PREF_FLASH))
- flash();
-
- windows[win_index]->unread++;
- if (prefs_get_boolean(PREF_CHLOG) && prefs_get_boolean(PREF_HISTORY)) {
- _win_show_history(window->win, win_index, 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);
}
}
- int ui_index = win_index + 1;
+ int ui_index = num;
if (ui_index == 10) {
ui_index = 0;
}
@@ -504,12 +420,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");
}
@@ -517,8 +433,11 @@ 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(console)) {
+ wins_refresh_current();
+ } else if ((window != NULL) && (wins_is_current(window))) {
+ wins_refresh_current();
+ }
}
void
@@ -543,12 +462,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");
}
@@ -556,30 +475,17 @@ 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(console)) {
+ wins_refresh_current();
+ } else if ((window != NULL) && (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();
@@ -619,84 +525,122 @@ ui_close_connected_win(int index)
}
}
+int
+ui_close_all_wins(void)
+{
+ int count = 0;
+ jabber_conn_status_t conn_status = jabber_get_connection_status();
+
+ 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(num);
+ }
+ 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 count = 0;
+ jabber_conn_status_t conn_status = jabber_get_connection_status();
+
+ 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(num);
+ }
+ ui_close_win(num);
+ count++;
+ }
+ curr = g_list_next(curr);
+ }
+
+ g_list_free(curr);
+ g_list_free(win_nums);
+
+ return count;
+}
+
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) {
+ if (i == 1) {
title_bar_title();
- status_bar_active(0);
+ status_bar_active(1);
} 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();
status_bar_inactive(current_index);
-
- // go back to console window
- _set_current(0);
- status_bar_active(0);
+ wins_close_current();
+ status_bar_active(1);
title_bar_title();
-
- current_win_dirty = TRUE;
}
void
ui_close_win(int index)
{
- win_free(windows[index]);
- windows[index] = NULL;
- status_bar_inactive(index);
-
- if (index == current_index) {
- _set_current(0);
- }
-
- status_bar_active(0);
+ wins_close_by_num(index);
+ status_bar_active(1);
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.");
@@ -709,23 +653,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);
}
- _tidy();
+ if (recipients != NULL) {
+ g_slist_free(recipients);
+ }
+
+ wins_tidy();
if (pruned) {
cons_show("Windows pruned.");
} else {
@@ -736,36 +697,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);
@@ -775,56 +741,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)
{
+ ProfWin *current = wins_get_current();
+ current->paged = 0;
+
int rows = getmaxy(stdscr);
- ProfWin *window = windows[current_index];
-
- window->paged = 0;
-
- int y = getcury(window->win);
-
+ 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();
}
}
}
@@ -832,8 +793,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;
@@ -843,29 +803,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(1);
+ }
}
- 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;
@@ -877,18 +839,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();
}
}
}
@@ -898,25 +858,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) {
@@ -926,71 +885,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);
}
}
@@ -998,7 +957,7 @@ ui_duck_result(const char * const result)
offset++;
}
- wprintw(windows[win_index]->win, "\n");
+ wprintw(window->win, "\n");
}
}
@@ -1006,27 +965,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) {
@@ -1039,7 +996,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, '-');
@@ -1053,27 +1010,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)) {
@@ -1120,118 +1078,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) {
@@ -1260,16 +1220,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) {
@@ -1278,10 +1238,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;
if (ui_index == 10) {
ui_index = 0;
}
@@ -1301,8 +1261,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);
@@ -1311,21 +1271,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);
@@ -1334,13 +1294,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);
}
}
@@ -1349,6 +1309,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);
@@ -1361,8 +1322,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);
@@ -1377,6 +1338,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);
@@ -1388,21 +1350,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;
}
@@ -1450,38 +1406,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)
{
@@ -1511,36 +1435,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,
@@ -1656,6 +1550,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);
@@ -1684,7 +1579,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;
@@ -1693,7 +1588,7 @@ _win_handle_page(const wint_t * const ch)
*page_start = 0;
current->paged = 1;
- current_win_dirty = TRUE;
+ wins_refresh_current();
}
}
}
@@ -1708,7 +1603,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) {
@@ -1723,14 +1618,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);
@@ -1739,48 +1635,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/inputwin.c b/src/ui/inputwin.c
index 0ab53131..b6162938 100644
--- a/src/ui/inputwin.c
+++ b/src/ui/inputwin.c
@@ -526,35 +526,35 @@ _handle_alt_key(char *input, int *size, int key)
switch (key)
{
case '1':
- ui_switch_win(0);
- break;
- case '2':
ui_switch_win(1);
break;
- case '3':
+ case '2':
ui_switch_win(2);
break;
- case '4':
+ case '3':
ui_switch_win(3);
break;
- case '5':
+ case '4':
ui_switch_win(4);
break;
- case '6':
+ case '5':
ui_switch_win(5);
break;
- case '7':
+ case '6':
ui_switch_win(6);
break;
- case '8':
+ case '7':
ui_switch_win(7);
break;
- case '9':
+ case '8':
ui_switch_win(8);
break;
- case '0':
+ case '9':
ui_switch_win(9);
break;
+ case '0':
+ ui_switch_win(0);
+ break;
case 263:
case 127:
input[*size] = '\0';
diff --git a/src/ui/statusbar.c b/src/ui/statusbar.c
index 6e7eae30..e7456adc 100644
--- a/src/ui/statusbar.c
+++ b/src/ui/statusbar.c
@@ -37,13 +37,20 @@
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 GHashTable *remaining_active;
+static int is_new[12];
+static GHashTable *remaining_new;
static int dirty;
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)
@@ -51,17 +58,19 @@ 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;
}
+ 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);
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)
@@ -86,6 +95,7 @@ status_bar_refresh(void)
if (dirty) {
_status_bar_update_time();
+ _update_win_statuses();
wrefresh(status_bar);
inp_put_back();
dirty = FALSE;
@@ -97,7 +107,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);
@@ -105,15 +115,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++) {
- 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);
@@ -124,61 +129,115 @@ 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)
{
- is_active[win] = FALSE;
- is_new[win] = FALSE;
+ int true_win = win;
+ if (true_win == 0) {
+ true_win = 10;
+ }
- int active_pos = 1 + (win * 3);
+ // 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));
- int cols = getmaxx(stdscr);
+ // still have new windows
+ if (g_hash_table_size(remaining_new) != 0) {
+ is_active[11] = TRUE;
+ is_new[11] = TRUE;
+ _mark_new(11);
- mvwaddch(status_bar, 0, cols - 31 + active_pos, ' ');
+ // still have active winsows
+ } else if (g_hash_table_size(remaining_active) != 0) {
+ is_active[11] = TRUE;
+ is_new[11] = FALSE;
+ _mark_active(11);
- dirty = TRUE;
+ // no active or new windows
+ } else {
+ is_active[11] = FALSE;
+ is_new[11] = FALSE;
+ _mark_inactive(11);
+ }
+
+ // visible window indicators
+ } else {
+ is_active[true_win] = FALSE;
+ is_new[true_win] = FALSE;
+ _mark_inactive(true_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;
+ }
- int active_pos = 1 + (win * 3);
+ // 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));
- int cols = getmaxx(stdscr);
+ // still have new windows
+ if (g_hash_table_size(remaining_new) != 0) {
+ is_active[11] = TRUE;
+ is_new[11] = TRUE;
+ _mark_new(11);
- 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");
- wattroff(status_bar, COLOUR_STATUS_ACTIVE);
+ // only active windows
+ } else {
+ is_active[11] = TRUE;
+ is_new[11] = FALSE;
+ _mark_active(11);
+ }
- dirty = TRUE;
+ // visible winsow indicators
+ } else {
+ is_active[true_win] = TRUE;
+ is_new[true_win] = FALSE;
+ _mark_active(true_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;
+ }
- int active_pos = 1 + (win * 3);
+ 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));
- int cols = getmaxx(stdscr);
+ is_active[11] = TRUE;
+ is_new[11] = TRUE;
+ _mark_new(11);
- 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");
- wattroff(status_bar, COLOUR_STATUS_NEW);
- wattroff(status_bar, A_BLINK);
-
- dirty = TRUE;
+ } else {
+ is_active[true_win] = TRUE;
+ is_new[true_win] = TRUE;
+ _mark_new(true_win);
+ }
}
void
@@ -203,17 +262,10 @@ 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++) {
- if (is_new[i])
- status_bar_new(i);
- else if (is_active[i])
- status_bar_active(i);
- }
-
+ _update_win_statuses();
dirty = TRUE;
}
@@ -226,9 +278,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 +290,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,17 +309,10 @@ 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++) {
- if (is_new[i])
- status_bar_new(i);
- else if (is_active[i])
- status_bar_active(i);
- }
-
+ _update_win_statuses();
dirty = TRUE;
}
@@ -289,3 +334,65 @@ _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]) {
+ _mark_new(i);
+ }
+ else if (is_active[i]) {
+ _mark_active(i);
+ }
+ else {
+ _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;
+}
diff --git a/src/ui/ui.h b/src/ui/ui.h
index f0601753..fa74bed6 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);
@@ -56,15 +52,15 @@ 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);
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);
+int ui_close_all_wins(void);
+int ui_close_read_wins(void);
// current window actions
void ui_close_current(void);
@@ -149,7 +145,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);
@@ -230,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/window.c b/src/ui/window.c
index e2e03340..7c6f9266 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)
{
@@ -59,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/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..e956068c
--- /dev/null
+++ b/src/ui/windows.c
@@ -0,0 +1,475 @@
+/*
+ * 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 "common.h"
+#include "config/theme.h"
+#include "ui/ui.h"
+#include "ui/window.h"
+#include "ui/windows.h"
+
+#define CONS_WIN_TITLE "_cons"
+
+static GHashTable *windows;
+static int current;
+static int max_cols;
+
+void
+wins_init(void)
+{
+ windows = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
+ (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(windows, GINT_TO_POINTER(1), console);
+
+ current = 1;
+}
+
+ProfWin *
+wins_get_console(void)
+{
+ return g_hash_table_lookup(windows, GINT_TO_POINTER(1));
+}
+
+ProfWin *
+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)
+{
+ if (g_hash_table_lookup(windows, GINT_TO_POINTER(i)) != NULL) {
+ current = i;
+ }
+}
+
+ProfWin *
+wins_get_by_num(int i)
+{
+ return g_hash_table_lookup(windows, GINT_TO_POINTER(i));
+}
+
+ProfWin *
+wins_get_by_recipient(const char * const recipient)
+{
+ 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;
+}
+
+int
+wins_get_num(ProfWin *window)
+{
+ 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 -1;
+}
+
+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 != 1) {
+ if (i == current) {
+ current = 1;
+ wins_refresh_current();
+ }
+ g_hash_table_remove(windows, GINT_TO_POINTER(i));
+ status_bar_inactive(i);
+ }
+}
+
+void
+wins_refresh_current(void)
+{
+ ProfWin *window = wins_get_current();
+ int rows, cols;
+ getmaxyx(stdscr, rows, cols);
+ prefresh(window->win, window->y_pos, 0, 1, 0, rows-3, cols-1);
+}
+
+void
+wins_clear_current(void)
+{
+ ProfWin *window = wins_get_current();
+ werase(window->win);
+ wins_refresh_current();
+}
+
+gboolean
+wins_is_current(ProfWin *window)
+{
+ ProfWin *current_window = wins_get_current();
+
+ if (g_strcmp0(current_window->from, window->from) == 0) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+ProfWin *
+wins_new(const char * const from, win_type_t type)
+{
+ 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 result = 0;
+ 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;
+}
+
+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;
+
+ 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);
+ }
+ }
+
+ ProfWin *current_win = wins_get_current();
+
+ prefresh(current_win->win, current_win->y_pos, 0, 1, 0, rows-3, cols-1);
+}
+
+void
+wins_refresh_console(void)
+{
+ if (current == 0) {
+ wins_refresh_current();
+ }
+}
+
+gboolean
+wins_duck_exists(void)
+{
+ 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;
+}
+
+GSList *
+wins_get_chat_recipients(void)
+{
+ GSList *result = NULL;
+ 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;
+}
+
+GSList *
+wins_get_prune_recipients(void)
+{
+ GSList *result = NULL;
+ 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)
+{
+ 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.");
+ wattroff(window->win, COLOUR_ERROR);
+
+ // if current win, set current_win_dirty
+ if (wins_is_current(window)) {
+ wins_refresh_current();
+ }
+ }
+ curr = g_list_next(curr);
+ }
+}
+
+gboolean
+wins_tidy(void)
+{
+ 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 before last window)
+ if (cmp_win_num(GINT_TO_POINTER(next_available), GINT_TO_POINTER(last_num)) < 0) {
+ tidy_required = TRUE;
+ }
+
+ if (tidy_required) {
+ status_bar_set_all_inactive();
+ 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, curr->data);
+ if (num == 10) {
+ 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(new_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);
+ }
+
+ windows = new_windows;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+GSList *
+wins_create_summary(void)
+{
+ GSList *result = NULL;
+
+ 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);
+ }
+
+ 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;
+}
+
+void
+wins_destroy(void)
+{
+ g_hash_table_destroy(windows);
+}
diff --git a/src/ui/windows.h b/src/ui/windows.h
new file mode 100644
index 00000000..6d93c434
--- /dev/null
+++ b/src/ui/windows.h
@@ -0,0 +1,52 @@
+/*
+ * 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_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);
+void wins_destroy(void);
+GList * wins_get_nums(void);
+
+#endif
diff --git a/tests/test_common.c b/tests/test_common.c
index 6bdcfb76..37dd37d2 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)
+{
+ GList *used = NULL;
+ used = g_list_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)
+{
+ 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);
+
+ assert_int_equals(3, result);
+}
+
+void next_available_9_at_end(void)
+{
+ 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);
+
+ assert_int_equals(9, result);
+}
+
+void next_available_0_at_end(void)
+{
+ 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);
+
+ assert_int_equals(0, result);
+}
+
+void next_available_2_in_first_gap(void)
+{
+ 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);
+
+ assert_int_equals(2, result);
+}
+
+void next_available_9_in_first_gap(void)
+{
+ 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);
+
+ assert_int_equals(9, result);
+}
+
+void next_available_0_in_first_gap(void)
+{
+ 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);
+
+ assert_int_equals(0, result);
+}
+
+void next_available_11_in_first_gap(void)
+{
+ 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);
+
+ assert_int_equals(11, result);
+}
+
+void next_available_24_first_big_gap(void)
+{
+ 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);
+
+ 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);
}