/* * core.c * vim: expandtab:ts=4:sts=4:sw=4 * * Copyright (C) 2012 - 2019 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 . * * In addition, as a special exception, the copyright holders give permission to * link the code of portions of this program with the OpenSSL library under * certain conditions as described in each individual source file, and * distribute linked combinations including the two. * * You must obey the GNU General Public License in all respects for all of the * code used other than OpenSSL. If you modify file(s) with this exception, you * may extend this exception to your version of the file(s), but you are not * obligated to do so. If you do not wish to do so, delete this exception * statement from your version. If you delete this exception statement from all * source files in the program, then also delete it here. * */ #include "config.h" #ifdef HAVE_GIT_VERSION #include "gitversion.h" #endif #include #include #include #include #include #include #ifdef HAVE_LIBXSS #include #endif #ifdef HAVE_NCURSESW_NCURSES_H #include #elif HAVE_NCURSES_H #include #endif #include "log.h" #include "common.h" #include "command/cmd_defs.h" #include "command/cmd_ac.h" #include "config/preferences.h" #include "config/theme.h" #include "ui/ui.h" #include "ui/titlebar.h" #include "ui/statusbar.h" #include "ui/inputwin.h" #include "ui/window.h" #include "ui/window_list.h" #include "xmpp/xmpp.h" #include "xmpp/muc.h" #include "xmpp/chat_session.h" #include "xmpp/contact.h" #include "xmpp/roster_list.h" #include "xmpp/jid.h" #ifdef HAVE_LIBOTR #include "otr/otr.h" #endif static char *win_title; static int inp_size; static gboolean perform_resize = FALSE; static GTimer *ui_idle_time; #ifdef HAVE_LIBXSS static Display *display; #endif static void _ui_draw_term_title(void); void ui_init(void) { log_info("Initialising UI"); initscr(); nonl(); cbreak(); noecho(); keypad(stdscr, TRUE); ui_load_colours(); refresh(); create_title_bar(); status_bar_init(); status_bar_active(1, WIN_CONSOLE, "console"); create_input_window(); wins_init(); notifier_initialise(); cons_about(); #ifdef HAVE_LIBXSS display = XOpenDisplay(0); #endif ui_idle_time = g_timer_new(); inp_size = 0; ProfWin *window = wins_get_current(); win_update_virtual(window); } void ui_sigwinch_handler(int sig) { perform_resize = TRUE; } void ui_update(void) { ProfWin *current = wins_get_current(); if (current->layout->paged == 0) { win_move_to_end(current); } win_update_virtual(current); if (prefs_get_boolean(PREF_WINTITLE_SHOW)) { _ui_draw_term_title(); } title_bar_update_virtual(); status_bar_draw(); inp_put_back(); doupdate(); if (perform_resize) { signal(SIGWINCH, SIG_IGN); ui_resize(); perform_resize = FALSE; signal(SIGWINCH, ui_sigwinch_handler); } } unsigned long ui_get_idle_time(void) { // if compiled with libxss, get the x sessions idle time #ifdef HAVE_LIBXSS XScreenSaverInfo *info = XScreenSaverAllocInfo(); if (info && display) { XScreenSaverQueryInfo(display, DefaultRootWindow(display), info); unsigned long result = info->idle; XFree(info); return result; } if (info) { XFree(info); } // if no libxss or xss idle time failed, use profanity idle time #endif gdouble seconds_elapsed = g_timer_elapsed(ui_idle_time, NULL); unsigned long ms_elapsed = seconds_elapsed * 1000.0; return ms_elapsed; } void ui_reset_idle_time(void) { g_timer_start(ui_idle_time); } void ui_close(void) { notifier_uninit(); wins_destroy(); inp_close(); status_bar_close(); endwin(); } void ui_resize(void) { struct winsize w; ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); erase(); resizeterm(w.ws_row, w.ws_col); refresh(); log_debug("Resizing UI"); title_bar_resize(); wins_resize_all(); status_bar_resize(); inp_win_resize(); ProfWin *window = wins_get_current(); win_update_virtual(window); } void ui_redraw(void) { title_bar_resize(); wins_resize_all(); status_bar_resize(); inp_win_resize(); } void ui_load_colours(void) { if (has_colors()) { use_default_
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
 <head>
  <title>Index of /~bh/61a-pages/Lectures/2.2</title>
 </head>
 <body>
<h1>Index of /~bh/61a-pages/Lectures/2.2</h1>
  <table>
   <tr><th valign="top"><img src="../../../../icons/blank.gif" alt="[ICO]"></th><th><a href="index.html?C=N%3BO=A">Name</a></th><th><a href="index.html?C=M%3BO=A">Last modified</a></th><th><a href="index.html?C=S%3BO=A">Size</a></th><th><a href="index.html?C=D%3BO=D">Description</a></th></tr>
   <tr><th colspan="5"><hr></th></tr>
<tr><td valign="top"><img src="../../../../icons/back.gif" alt="[PARENTDIR]"></td><td><a href="../../Lectures">Parent Directory</a>       </td><td>&nbsp;</td><td align="right">  - </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="../../../../icons/unknown.gif" alt="[   ]"></td><td><a href="bst.scm">bst.scm</a>                </td><td align="right">2000-05-30 12:38  </td><td align="right">604 </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="../../../../icons/unknown.gif" alt="[   ]"></td><td><a href="bst2.scm">bst2.scm</a>               </td><td align="right">2000-05-30 12:38  </td><td align="right">616 </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="../../../../icons/unknown.gif" alt="[   ]"></td><td><a href="https://people.eecs.berkeley.edu/~bh/61a-pages/Lectures/2.2/music.scm">music.scm</a>              </td><td align="right">2006-10-02 19:45  </td><td align="right">833 </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="../../../../icons/unknown.gif" alt="[   ]"></td><td><a href="print.scm">print.scm</a>              </td><td align="right">2007-02-23 14:26  </td><td align="right">485 </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="../../../../icons/unknown.gif" alt="[   ]"></td><td><a href="search.scm">search.scm</a>             </td><td align="right">2000-05-30 12:38  </td><td align="right">333 </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="../../../../icons/unknown.gif" alt="[   ]"></td><td><a href="sentence.scm">sentence.scm</a>           </td><td align="right">2000-05-30 12:38  </td><td align="right">161 </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="../../../../icons/unknown.gif" alt="[   ]"></td><td><a href="squares.scm">squares.scm</a>            </td><td align="right">2000-05-30 12:38  </td><td align="right">1.3K</td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="../../../../icons/unknown.gif" alt="[   ]"></td><td><a href="tdisp.scm">tdisp.scm</a>              </td><td align="right">2000-05-30 12:38  </td><td align="right">1.2K</td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="../../../../icons/unknown.gif" alt="[   ]"></td><td><a href="https://people.eecs.berkeley.edu/~bh/61a-pages/Lectures/2.2/tiny.scm">tiny.scm</a>               </td><td align="right">2007-10-01 15:45  </td><td align="right">453 </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="../../../../icons/unknown.gif" alt="[   ]"></td><td><a href="tree.scm">tree.scm</a>               </td><td align="right">2000-05-30 12:38  </td><td align="right">828 </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="../../../../icons/unknown.gif" alt="[   ]"></td><td><a href="tree1.scm">tree1.scm</a>              </td><td align="right">2000-05-30 12:38  </td><td align="right">520 </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="../../../../icons/unknown.gif" alt="[   ]"></td><td><a href="tree2.scm">tree2.scm</a>              </td><td align="right">2000-05-30 12:38  </td><td align="right">882 </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="../../../../icons/unknown.gif" alt="[   ]"></td><td><a href="tree3.scm">tree3.scm</a>              </td><td align="right">2007-02-23 14:26  </td><td align="right">157 </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="../../../../icons/unknown.gif" alt="[   ]"></td><td><a href="tree11.scm">tree11.scm</a>             </td><td align="right">2007-02-23 14:26  </td><td align="right">235 </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="../../../../icons/unknown.gif" alt="[   ]"></td><td><a href="https://people.eecs.berkeley.edu/~bh/61a-pages/Lectures/2.2/tree22.scm">tree22.scm</a>             </td><td align="right">2007-02-23 14:26  </td><td align="right">122 </td><td>&nbsp;</td></tr>
<tr><td valign="top"><img src="../../../../icons/unknown.gif" alt="[   ]"></td><td><a href="world.scm">world.scm</a>              </td><td align="right">2000-05-30 12:38  </td><td align="right">1.0K</td><td>&nbsp;</td></tr>
   <tr><th colspan="5"><hr></th></tr>
</table>
</body></html>
window->type, identifier); free(identifier); } void ui_close_win(int index) { ProfWin *window = wins_get_by_num(index); if (window && window->type == WIN_CONFIG) { ProfConfWin *confwin = (ProfConfWin*)window; if (confwin->form) { cmd_ac_remove_form_fields(confwin->form); } } wins_close_by_num(index); title_bar_console(); status_bar_current(1); status_bar_active(1, WIN_CONSOLE, "console"); } void ui_prune_wins(void) { jabber_conn_status_t conn_status = connection_get_status(); gboolean pruned = FALSE; GSList *wins = wins_get_prune_wins(); if (wins) { pruned = TRUE; } GSList *curr = wins; while (curr) { ProfWin *window = curr->data; if (window->type == WIN_CHAT) { if (conn_status == JABBER_CONNECTED) { ProfChatWin *chatwin = (ProfChatWin*)window; chat_session_remove(chatwin->barejid); } } int num = wins_get_num(window); ui_close_win(num); curr = g_slist_next(curr); } if (wins) { g_slist_free(wins); } wins_tidy(); if (pruned) { cons_show("Windows pruned."); } else { cons_show("No prune needed."); } } void ui_print_system_msg_from_recipient(const char *const barejid, const char *message) { if (barejid == NULL || message == NULL) return; ProfChatWin *chatwin = wins_get_chat(barejid); ProfWin *window = (ProfWin*)chatwin; if (window == NULL) { window = wins_new_chat(barejid); if (window) { chatwin = (ProfChatWin*)window; int num = wins_get_num(window); status_bar_active(num, WIN_CHAT, chatwin->barejid); } else { window = wins_get_console(); status_bar_active(1, WIN_CONSOLE, "console"); } } win_println(window, THEME_DEFAULT, "-", "*%s %s", barejid, message); } void ui_room_join(const char *const roomjid, gboolean focus) { ProfMucWin *mucwin = wins_get_muc(roomjid); if (mucwin == NULL) { mucwin = mucwin_new(roomjid); } ProfWin *window = (ProfWin*)mucwin; char *nick = muc_nick(roomjid); win_print(window, THEME_ROOMINFO, "!", "-> You have joined the room as %s", nick); if (prefs_get_boolean(PREF_MUC_PRIVILEGES)) { char *role = muc_role_str(roomjid); char *affiliation = muc_affiliation_str(roomjid); if (role) { win_append(window, THEME_ROOMINFO, ", role: %s", role); } if (affiliation) { win_append(window, THEME_ROOMINFO, ", affiliation: %s", affiliation); } } win_appendln(window, THEME_ROOMINFO, ""); if (focus) { ui_focus_win(window); } else { int num = wins_get_num(window); status_bar_active(num, WIN_MUC, mucwin->roomjid); ProfWin *console = wins_get_console(); win_println(console, THEME_TYPING, "!", "-> Autojoined %s as %s (%d).", roomjid, nick, num); } GList *privwins = wins_get_private_chats(roomjid); GList *curr = privwins; while (curr) { ProfPrivateWin *privwin = curr->data; privwin_room_joined(privwin); curr = g_list_next(curr); } g_list_free(privwins); } void ui_switch_to_room(const char *const roomjid) { ProfWin *window = (ProfWin*)wins_get_muc(roomjid); ui_focus_win(window); } void ui_room_destroy(const char *const roomjid) { ProfWin *window = (ProfWin*)wins_get_muc(roomjid); GList *privwins = wins_get_private_chats(roomjid); if (window == NULL) { log_error("Received room destroy result, but no window open for %s.", roomjid); } else { int num = wins_get_num(window); ui_close_win(num); cons_show("Room destroyed: %s", roomjid); } GList *curr = privwins; while (curr) { ProfPrivateWin *privwin = curr->data; privwin_room_destroyed(privwin); curr = g_list_next(curr); } g_list_free(privwins); } void ui_leave_room(const char *const roomjid) { ProfWin *window = (ProfWin*)wins_get_muc(roomjid); GList *privwins = wins_get_private_chats(roomjid); if (window) { int num = wins_get_num(window); ui_close_win(num); } GList *curr = privwins; while (curr) { ProfPrivateWin *privwin = curr->data; privwin_room_left(privwin); curr = g_list_next(curr); } g_list_free(privwins); } void ui_room_destroyed(const char *const roomjid, const char *const reason, const char *const new_jid, const char *const password) { ProfWin *window = (ProfWin*)wins_get_muc(roomjid); GList *privwins = wins_get_private_chats(roomjid); if (window == NULL) { log_error("Received room destroy, but no window open for %s.", roomjid); } else { int num = wins_get_num(window); ui_close_win(num); ProfWin *console = wins_get_console(); if (reason) { win_println(console, THEME_TYPING, "!", "<- Room destroyed: %s, reason: %s", roomjid, reason); } else { win_println(console, THEME_TYPING, "!", "<- Room destroyed: %s", roomjid); } if (new_jid) { if (password) { win_println(console, THEME_TYPING, "!", "Replacement room: %s, password: %s", new_jid, password); } else { win_println(console, THEME_TYPING, "!", "Replacement room: %s", new_jid); } } } GList *curr = privwins; while (curr) { ProfPrivateWin *privwin = curr->data; privwin_room_destroyed(privwin); curr = g_list_next(curr); } g_list_free(privwins); } void ui_room_kicked(const char *const roomjid, const char *const actor, const char *const reason) { ProfWin *window = (ProfWin*)wins_get_muc(roomjid); GList *privwins = wins_get_private_chats(roomjid); if (window == NULL) { log_error("Received kick, but no window open for %s.", roomjid); } else { int num = wins_get_num(window); ui_close_win(num); GString *message = g_string_new("Kicked from "); g_string_append(message, roomjid); if (actor) { g_string_append(message, " by "); g_string_append(message, actor); } if (reason) { g_string_append(message, ", reason: "); g_string_append(message, reason); } ProfWin *console = wins_get_console(); win_println(console, THEME_TYPING, "!", "<- %s", message->str); g_string_free(message, TRUE); } GList *curr = privwins; while (curr) { ProfPrivateWin *privwin = curr->data; privwin_room_kicked(privwin, actor, reason); curr = g_list_next(curr); } g_list_free(privwins); } void ui_room_banned(const char *const roomjid, const char *const actor, const char *const reason) { ProfWin *window = (ProfWin*)wins_get_muc(roomjid); GList *privwins = wins_get_private_chats(roomjid); if (window == NULL) { log_error("Received ban, but no window open for %s.", roomjid); } else { int num = wins_get_num(window); ui_close_win(num); GString *message = g_string_new("Banned from "); g_string_append(message, roomjid); if (actor) { g_string_append(message, " by "); g_string_append(message, actor); } if (reason) { g_string_append(message, ", reason: "); g_string_append(message, reason); } ProfWin *console = wins_get_console(); win_println(console, THEME_TYPING, "!", "<- %s", message->str); g_string_free(message, TRUE); } GList *curr = privwins; while (curr) { ProfPrivateWin *privwin = curr->data; privwin_room_banned(privwin, actor, reason); curr = g_list_next(curr); } g_list_free(privwins); } int ui_win_unread(int index) { ProfWin *window = wins_get_by_num(index); if (window) { return win_unread(window); } else { return 0; } } char* ui_ask_password(void) { status_bar_set_prompt("Enter password:"); return inp_get_password(); } char* ui_get_line(void) { status_bar_draw(); return inp_get_line(); } char* ui_ask_pgp_passphrase(const char *hint, int prev_fail) { ProfWin *current = wins_get_current(); win_println(current, THEME_DEFAULT, "-", ""); if (prev_fail) { win_println(current, THEME_DEFAULT, "!", "Incorrect passphrase"); } if (hint) { win_println(current, THEME_DEFAULT, "!", "Enter PGP key passphrase for %s", hint); } else { win_println(current, THEME_DEFAULT, "!", "Enter PGP key passphrase"); } ui_update(); status_bar_set_prompt("Enter password:"); return inp_get_password(); } void ui_contact_offline(char *barejid, char *resource, char *status) { char *show_console = prefs_get_string(PREF_STATUSES_CONSOLE); char *show_chat_win = prefs_get_string(PREF_STATUSES_CHAT); Jid *jid = jid_create_from_bare_and_resource(barejid, resource); PContact contact = roster_get_contact(barejid); if (p_contact_subscription(contact)) { if (strcmp(p_contact_subscription(contact), "none") != 0) { // show in console if "all" if (g_strcmp0(show_console, "all") == 0) { cons_show_contact_offline(contact, resource, status); // show in console of "online" } else if (g_strcmp0(show_console, "online") == 0) { cons_show_contact_offline(contact, resource, status); } // show in chat win if "all" if (g_strcmp0(show_chat_win, "all") == 0) { ProfChatWin *chatwin = wins_get_chat(barejid); if (chatwin) { chatwin_contact_offline(chatwin, resource, status); } // show in chat win if "online" and presence online } else if (g_strcmp0(show_chat_win, "online") == 0) { ProfChatWin *chatwin = wins_get_chat(barejid); if (chatwin) { chatwin_contact_offline(chatwin, resource, status); } } } } ProfChatWin *chatwin = wins_get_chat(barejid); if (chatwin && chatwin->resource_override && (g_strcmp0(resource, chatwin->resource_override) == 0)) { FREE_SET_NULL(chatwin->resource_override); } prefs_free_string(show_console); prefs_free_string(show_chat_win); jid_destroy(jid); } void ui_clear_win_title(void) { printf("%c]0;%c", '\033', '\007'); } void ui_goodbye_title(void) { int result = system("/bin/echo -ne \"\033]0;Thanks for using Profanity\007\""); if(result == -1) log_error("Error printing title on shutdown"); } static void _ui_draw_term_title(void) { char new_win_title[100]; jabber_conn_status_t status = connection_get_status(); if (status == JABBER_CONNECTED) { const char * const jid = connection_get_fulljid(); gint unread = wins_get_total_unread(); if (unread != 0) { snprintf(new_win_title, sizeof(new_win_title), "/bin/echo -n \"%c]0;%s (%d) - %s%c\"", '\033', "Profanity", unread, jid, '\007'); } else { snprintf(new_win_title, sizeof(new_win_title), "/bin/echo -n \"%c]0;%s - %s%c\"", '\033', "Profanity", jid, '\007'); } } else { snprintf(new_win_title, sizeof(new_win_title), "/bin/echo -n \"%c]0;%s%c\"", '\033', "Profanity", '\007'); } if (g_strcmp0(win_title, new_win_title) != 0) { // print to x-window title bar int res = system(new_win_title); if (res == -1) { log_error("Error writing terminal window title."); } if (win_title) { free(win_title); } win_title = strdup(new_win_title); } } void ui_handle_room_configuration_form_error(const char *const roomjid, const char *const message) { ProfWin *window = NULL; GString *message_str = g_string_new(""); if (roomjid) { window = (ProfWin*)wins_get_muc(roomjid); g_string_printf(message_str, "Could not get room configuration for %s", roomjid); } else { window = wins_get_console(); g_string_printf(message_str, "Could not get room configuration"); } if (message) { g_string_append(message_str, ": "); g_string_append(message_str, message); } win_println(window, THEME_ERROR, "-", "%s", message_str->str); g_string_free(message_str, TRUE); } void ui_handle_room_config_submit_result(const char *const roomjid) { if (roomjid) { ProfWin *form_window = NULL; ProfWin *muc_window = (ProfWin*)wins_get_muc(roomjid); GString *form_recipient = g_string_new(roomjid); g_string_append(form_recipient, " config"); form_window = (ProfWin*) wins_get_conf(form_recipient->str); g_string_free(form_recipient, TRUE); if (form_window) { int num = wins_get_num(form_window); wins_close_by_num(num); } if (muc_window) { ui_focus_win((ProfWin*)muc_window); win_println(muc_window, THEME_ROOMINFO, "!", "Room configuration successful"); } else { ProfWin *console = wins_get_console(); ui_focus_win(console); cons_show("Room configuration successful: %s", roomjid); } } else { cons_show("Room configuration successful"); } } void ui_handle_room_config_submit_result_error(const char *const roomjid, const char *const message) { ProfWin *console = wins_get_console(); if (roomjid) { ProfWin *muc_window = NULL; ProfWin *form_window = NULL; muc_window = (ProfWin*)wins_get_muc(roomjid); GString *form_recipient = g_string_new(roomjid); g_string_append(form_recipient, " config"); form_window = (ProfWin*) wins_get_conf(form_recipient->str); g_string_free(form_recipient, TRUE); if (form_window) { if (message) { win_println(form_window, THEME_ERROR, "!", "Configuration error: %s", message); } else { win_println(form_window, THEME_ERROR, "!", "Configuration error"); } } else if (muc_window) { if (message) { win_println(muc_window, THEME_ERROR, "!", "Configuration error: %s", message); } else { win_println(muc_window, THEME_ERROR, "!", "Configuration error"); } } else { if (message) { win_println(console, THEME_ERROR, "!", "Configuration error for %s: %s", roomjid, message); } else { win_println(console, THEME_ERROR, "!", "Configuration error for %s", roomjid); } } } else { win_println(console, THEME_ERROR, "!", "Configuration error"); } } void ui_show_lines(ProfWin *window, gchar** lines) { if (lines) { int i; for (i = 0; lines[i] != NULL; i++) { win_println(window, THEME_DEFAULT, "-", "%s", lines[i]); } } } void ui_show_roster(void) { ProfWin *window = wins_get_console(); if (window && !win_has_active_subwin(window)) { wins_show_subwin(window); rosterwin_roster(); } } void ui_hide_roster(void) { ProfWin *window = wins_get_console(); if (window && win_has_active_subwin(window)) { wins_hide_subwin(window); } } void ui_handle_software_version_error(const char *const roomjid, const char *const message) { GString *message_str = g_string_new(""); ProfWin *window = wins_get_console(); g_string_printf(message_str, "Could not get software version"); if (message) { g_string_append(message_str, ": "); g_string_append(message_str, message); } win_println(window, THEME_ERROR, "-", "%s", message_str->str); g_string_free(message_str, TRUE); } void ui_show_software_version(const char *const jid, const char *const presence, const char *const name, const char *const version, const char *const os) { Jid *jidp = jid_create(jid); ProfWin *window = NULL; ProfWin *chatwin = (ProfWin*)wins_get_chat(jidp->barejid); ProfWin *mucwin = (ProfWin*)wins_get_muc(jidp->barejid); ProfWin *privwin = (ProfWin*)wins_get_private(jidp->fulljid); ProfWin *console = wins_get_console(); jid_destroy(jidp); if (chatwin) { if (wins_is_current(chatwin)) { window = chatwin; } else { window = console; } } else if (privwin) { if (wins_is_current(privwin)) { window = privwin; } else { window = console; } } else if (mucwin) { if (wins_is_current(mucwin)) { window = mucwin; } else { window = console; } } else { window = console; } if (name || version || os) { win_println(window, THEME_DEFAULT, "-", ""); theme_item_t presence_colour = theme_main_presence_attrs(presence); win_print(window, presence_colour, "-", "%s", jid); win_appendln(window, THEME_DEFAULT, ":"); } if (name) { win_println(window, THEME_DEFAULT, "-", "Name : %s", name); } if (version) { win_println(window, THEME_DEFAULT, "-", "Version : %s", version); } if (os) { win_println(window, THEME_DEFAULT, "-", "OS : %s", os); } }