1
0
mirror of https://github.com/profanity-im/profanity.git synced 2024-11-03 19:37:16 -05:00

Merge branch 'master' into wheel

This commit is contained in:
James Booth 2012-11-25 02:20:26 +00:00
commit a28e0ee650
24 changed files with 1334 additions and 799 deletions

View File

@ -8,7 +8,8 @@ profanity_SOURCES = src/command.c src/contact.c src/history.c src/jabber.h \
src/main.c src/profanity.h src/prof_history.h src/chat_log.c \ src/main.c src/profanity.h src/prof_history.h src/chat_log.c \
src/chat_log.h src/tinyurl.c src/tinyurl.h src/chat_session.c \ src/chat_log.h src/tinyurl.c src/tinyurl.h src/chat_session.c \
src/chat_session.h src/release.c src/release.h src/room_chat.c \ src/chat_session.h src/release.c src/release.h src/room_chat.c \
src/room_chat.h src/stanza.c src/stanza.h src/parser.c src/parser.h src/room_chat.h src/stanza.c src/stanza.h src/parser.c src/parser.h \
src/theme.c src/theme.h src/window.c src/window.h
TESTS = tests/testsuite TESTS = tests/testsuite
check_PROGRAMS = tests/testsuite check_PROGRAMS = tests/testsuite

View File

@ -1,17 +1,17 @@
.TH Profanity 1 "August 2012" "Profanity XMPP client" .TH Profanity 1 "August 2012" "Profanity XMPP client"
.SH NAME .SH NAME
Profanity \- a simple console based XMPP chat client for Linux. Profanity \- a simple console based XMPP chat client.
.SH SYNOPSIS .SH SYNOPSIS
.B profanity .B profanity
[-vhd] [-l level] [-vhd] [-l level]
.SH DESCRIPTION .SH DESCRIPTION
.B Profanity .B Profanity
is a simple lightweight console based XMPP chat client. It's emphasis is is a simple lightweight console based XMPP chat client. It's emphasis is
on having a simple and configurable UI, see the homepage on having a simple and configurable command driven UI, see the homepage
at: at:
.br .br
.PP .PP
<http://www.boothj5.com/profanity.shtml> <http://www.profanity.im>
.SH OPTIONS .SH OPTIONS
.TP .TP
.BI "\-v, \-\-version" .BI "\-v, \-\-version"
@ -66,6 +66,8 @@ beep=false
.br .br
flash=false flash=false
.br .br
theme=mytheme
.br
showsplash=false showsplash=false
.br .br
notify=true notify=true
@ -81,6 +83,26 @@ remind=15
vercheck=true vercheck=true
.br .br
.PP .PP
[connections]
.br
logins=user1@server1.org;myuser@server2.com;
.PP
.RE
The [ui] section contains basic preferences, you can find more help on these
settings by typing "/help beep" for example in Profanity.
.PP
The [connections] section is the list of users that will appear in tab
completion for the /connect command. This list is automatically populated
when you successfully log in as a user.
.SH THEMES
Themes files for
.B Profanity
are stored in
.I ~/.profanity/themes
, see the following example:
.br
.RS
.PP
[colours] [colours]
.br .br
bkgnd=default bkgnd=default
@ -117,23 +139,27 @@ xa=cyan
.br .br
offline=red offline=red
.br .br
.PP typing=yellow
[connections] .br
gone=red
.br
error=red
.br
incoming=yellow
.br
roominfo=yellow
.br
me=yellow
.br
them=green
.br .br
logins=user1@server1.org;myuser@server2.com;
.PP .PP
.RE .RE
The [ui] section contains basic preferences, you can find more help on these
settings by typing "/help beep" for example in Profanity.
.PP
The [colours] section allows you to tailor the colours used in Profanity to The [colours] section allows you to tailor the colours used in Profanity to
suit your terminal preferences. Available colours are black, white, red, suit your terminal preferences. Available colours are black, white, red,
green, blue, yellow, cyan, magenta and default, where default is the default green, blue, yellow, cyan, magenta and default, where default is the default
forground or background colour on your terminal. forground or background colour on your terminal.
.PP .PP
The [connections] section is the list of users that will appear in tab
completion for the /connect command. This list is automatically populated
when you successfully log in as a user.
.SH BUGS .SH BUGS
Bugs can either be reported by sending a mail directly to: Bugs can either be reported by sending a mail directly to:
.br .br

View File

@ -95,9 +95,7 @@ chat_session_set_composing(const char * const recipient)
{ {
ChatSession session = g_hash_table_lookup(sessions, recipient); ChatSession session = g_hash_table_lookup(sessions, recipient);
if (session == NULL) { if (session != NULL) {
log_error("No chat session found for %s.", recipient);
} else {
if (session->state != CHAT_STATE_COMPOSING) { if (session->state != CHAT_STATE_COMPOSING) {
session->sent = FALSE; session->sent = FALSE;
} }
@ -111,9 +109,7 @@ chat_session_no_activity(const char * const recipient)
{ {
ChatSession session = g_hash_table_lookup(sessions, recipient); ChatSession session = g_hash_table_lookup(sessions, recipient);
if (session == NULL) { if (session != NULL) {
log_error("No chat session found for %s.", recipient);
} else {
if (session->active_timer != NULL) { if (session->active_timer != NULL) {
gdouble elapsed = g_timer_elapsed(session->active_timer, NULL); gdouble elapsed = g_timer_elapsed(session->active_timer, NULL);
@ -146,9 +142,7 @@ chat_session_set_sent(const char * const recipient)
{ {
ChatSession session = g_hash_table_lookup(sessions, recipient); ChatSession session = g_hash_table_lookup(sessions, recipient);
if (session == NULL) { if (session != NULL) {
log_error("No chat session found for %s.", recipient);
} else {
session->sent = TRUE; session->sent = TRUE;
} }
} }
@ -159,7 +153,6 @@ chat_session_get_sent(const char * const recipient)
ChatSession session = g_hash_table_lookup(sessions, recipient); ChatSession session = g_hash_table_lookup(sessions, recipient);
if (session == NULL) { if (session == NULL) {
log_error("No chat session found for %s.", recipient);
return FALSE; return FALSE;
} else { } else {
return session->sent; return session->sent;
@ -178,7 +171,6 @@ chat_session_is_inactive(const char * const recipient)
ChatSession session = g_hash_table_lookup(sessions, recipient); ChatSession session = g_hash_table_lookup(sessions, recipient);
if (session == NULL) { if (session == NULL) {
log_error("No chat session found for %s.", recipient);
return FALSE; return FALSE;
} else { } else {
return (session->state == CHAT_STATE_INACTIVE); return (session->state == CHAT_STATE_INACTIVE);
@ -191,7 +183,6 @@ chat_session_is_active(const char * const recipient)
ChatSession session = g_hash_table_lookup(sessions, recipient); ChatSession session = g_hash_table_lookup(sessions, recipient);
if (session == NULL) { if (session == NULL) {
log_error("No chat session found for %s.", recipient);
return FALSE; return FALSE;
} else { } else {
return (session->state == CHAT_STATE_ACTIVE); return (session->state == CHAT_STATE_ACTIVE);
@ -203,9 +194,7 @@ chat_session_set_active(const char * const recipient)
{ {
ChatSession session = g_hash_table_lookup(sessions, recipient); ChatSession session = g_hash_table_lookup(sessions, recipient);
if (session == NULL) { if (session != NULL) {
log_error("No chat session found for %s.", recipient);
} else {
session->state = CHAT_STATE_ACTIVE; session->state = CHAT_STATE_ACTIVE;
g_timer_start(session->active_timer); g_timer_start(session->active_timer);
session->sent = TRUE; session->sent = TRUE;
@ -218,7 +207,6 @@ chat_session_is_paused(const char * const recipient)
ChatSession session = g_hash_table_lookup(sessions, recipient); ChatSession session = g_hash_table_lookup(sessions, recipient);
if (session == NULL) { if (session == NULL) {
log_error("No chat session found for %s.", recipient);
return FALSE; return FALSE;
} else { } else {
return (session->state == CHAT_STATE_PAUSED); return (session->state == CHAT_STATE_PAUSED);
@ -231,7 +219,6 @@ chat_session_is_gone(const char * const recipient)
ChatSession session = g_hash_table_lookup(sessions, recipient); ChatSession session = g_hash_table_lookup(sessions, recipient);
if (session == NULL) { if (session == NULL) {
log_error("No chat session found for %s.", recipient);
return FALSE; return FALSE;
} else { } else {
return (session->state == CHAT_STATE_GONE); return (session->state == CHAT_STATE_GONE);
@ -243,9 +230,7 @@ chat_session_set_gone(const char * const recipient)
{ {
ChatSession session = g_hash_table_lookup(sessions, recipient); ChatSession session = g_hash_table_lookup(sessions, recipient);
if (session == NULL) { if (session != NULL) {
log_error("No chat session found for %s.", recipient);
} else {
session->state = CHAT_STATE_GONE; session->state = CHAT_STATE_GONE;
} }
} }
@ -256,7 +241,6 @@ chat_session_get_recipient_supports(const char * const recipient)
ChatSession session = g_hash_table_lookup(sessions, recipient); ChatSession session = g_hash_table_lookup(sessions, recipient);
if (session == NULL) { if (session == NULL) {
log_error("No chat session found for %s.", recipient);
return FALSE; return FALSE;
} else { } else {
return session->recipient_supports; return session->recipient_supports;
@ -269,9 +253,7 @@ chat_session_set_recipient_supports(const char * const recipient,
{ {
ChatSession session = g_hash_table_lookup(sessions, recipient); ChatSession session = g_hash_table_lookup(sessions, recipient);
if (session == NULL) { if (session != NULL) {
log_error("No chat session found for %s.", recipient);
} else {
session->recipient_supports = recipient_supports; session->recipient_supports = recipient_supports;
} }
} }

View File

@ -40,6 +40,7 @@
#include "preferences.h" #include "preferences.h"
#include "prof_autocomplete.h" #include "prof_autocomplete.h"
#include "profanity.h" #include "profanity.h"
#include "theme.h"
#include "tinyurl.h" #include "tinyurl.h"
#include "ui.h" #include "ui.h"
@ -108,6 +109,7 @@ static gboolean _cmd_set_beep(gchar **args, struct cmd_help_t help);
static gboolean _cmd_set_notify(gchar **args, struct cmd_help_t help); static gboolean _cmd_set_notify(gchar **args, struct cmd_help_t help);
static gboolean _cmd_set_log(gchar **args, struct cmd_help_t help); static gboolean _cmd_set_log(gchar **args, struct cmd_help_t help);
static gboolean _cmd_set_priority(gchar **args, struct cmd_help_t help); static gboolean _cmd_set_priority(gchar **args, struct cmd_help_t help);
static gboolean _cmd_set_reconnect(gchar **args, struct cmd_help_t help);
static gboolean _cmd_set_intype(gchar **args, struct cmd_help_t help); static gboolean _cmd_set_intype(gchar **args, struct cmd_help_t help);
static gboolean _cmd_set_flash(gchar **args, struct cmd_help_t help); static gboolean _cmd_set_flash(gchar **args, struct cmd_help_t help);
static gboolean _cmd_set_showsplash(gchar **args, struct cmd_help_t help); static gboolean _cmd_set_showsplash(gchar **args, struct cmd_help_t help);
@ -124,6 +126,7 @@ static gboolean _cmd_xa(gchar **args, struct cmd_help_t help);
static gboolean _cmd_info(gchar **args, struct cmd_help_t help); static gboolean _cmd_info(gchar **args, struct cmd_help_t help);
static gboolean _cmd_wins(gchar **args, struct cmd_help_t help); static gboolean _cmd_wins(gchar **args, struct cmd_help_t help);
static gboolean _cmd_nick(gchar **args, struct cmd_help_t help); static gboolean _cmd_nick(gchar **args, struct cmd_help_t help);
static gboolean _cmd_theme(gchar **args, struct cmd_help_t help);
/* /*
* The commands are broken down into three groups: * The commands are broken down into three groups:
@ -191,6 +194,18 @@ static struct cmd_t main_commands[] =
"you will need to restart Profanity for config file edits to take effect.", "you will need to restart Profanity for config file edits to take effect.",
NULL } } }, NULL } } },
{ "/theme",
_cmd_theme, parse_args, 1, 1,
{ "/theme [theme-name]", "Change colour theme.",
{ "/theme [theme-name]",
"--------------",
"Change the colour setting as defined in:",
"",
" ~/.profanity/themes/theme-name",
"",
"Using \"default\" as the theme name will reset to the default colours.",
NULL } } },
{ "/msg", { "/msg",
_cmd_msg, parse_args_with_freetext, 2, 2, _cmd_msg, parse_args_with_freetext, 2, 2,
{ "/msg user@host mesg", "Send mesg to user.", { "/msg user@host mesg", "Send mesg to user.",
@ -471,6 +486,18 @@ static struct cmd_t setting_commands[] =
"Config file value : maxsize=bytes", "Config file value : maxsize=bytes",
NULL } } }, NULL } } },
{ "/reconnect",
_cmd_set_reconnect, parse_args, 1, 1,
{ "/reconnect seconds", "Set reconnect interval.",
{ "/reconnect seconds",
"--------------------",
"Set the reconnect attempt interval in seconds for when the connection is lost.",
"A value of 0 will switch of reconnect attempts.",
"",
"Config file section : [jabber]",
"Config file value : reconnect=seconds",
NULL } } },
{ "/priority", { "/priority",
_cmd_set_priority, parse_args, 1, 1, _cmd_set_priority, parse_args, 1, 1,
{ "/priority <value>", "Set priority for connection.", { "/priority <value>", "Set priority for connection.",
@ -1077,6 +1104,20 @@ _cmd_prefs(gchar **args, struct cmd_help_t help)
return TRUE; return TRUE;
} }
static gboolean
_cmd_theme(gchar **args, struct cmd_help_t help)
{
if (theme_change(args[0])) {
win_load_colours();
prefs_set_theme(args[0]);
cons_show("Loaded theme: %s", args[0]);
} else {
cons_show("Couldn't find theme: %s", args[0]);
}
return TRUE;
}
static gboolean static gboolean
_cmd_who(gchar **args, struct cmd_help_t help) _cmd_who(gchar **args, struct cmd_help_t help)
{ {
@ -1439,6 +1480,28 @@ _cmd_set_log(gchar **args, struct cmd_help_t help)
return TRUE; return TRUE;
} }
static gboolean
_cmd_set_reconnect(gchar **args, struct cmd_help_t help)
{
char *value = args[0];
int intval;
if (_strtoi(value, &intval, 0, INT_MAX) == 0) {
prefs_set_reconnect(intval);
if (intval == 0) {
cons_show("Reconnect disabled.", intval);
} else {
cons_show("Reconnect interval set to %d seconds.", intval);
}
} else {
cons_show("Usage: %s", help.usage);
}
/* TODO: make 'level' subcommand for debug level */
return TRUE;
}
static gboolean static gboolean
_cmd_set_priority(gchar **args, struct cmd_help_t help) _cmd_set_priority(gchar **args, struct cmd_help_t help)
{ {

View File

@ -58,6 +58,7 @@
#include "log.h" #include "log.h"
#include "preferences.h" #include "preferences.h"
#include "profanity.h" #include "profanity.h"
#include "theme.h"
#include "ui.h" #include "ui.h"
static WINDOW *inp_win; static WINDOW *inp_win;
@ -65,6 +66,7 @@ static int pad_start = 0;
static int _handle_edit(const int ch, char *input, int *size); static int _handle_edit(const int ch, char *input, int *size);
static int _printable(const int ch); static int _printable(const int ch);
static gboolean _special_key(const int ch);
void void
create_input_window(void) create_input_window(void)
@ -79,7 +81,7 @@ create_input_window(void)
getmaxyx(stdscr, rows, cols); getmaxyx(stdscr, rows, cols);
inp_win = newpad(1, INP_WIN_MAX); inp_win = newpad(1, INP_WIN_MAX);
wbkgd(inp_win, COLOR_PAIR(1)); wbkgd(inp_win, COLOUR_INPUT_TEXT);
keypad(inp_win, TRUE); keypad(inp_win, TRUE);
wmove(inp_win, 0, 0); wmove(inp_win, 0, 0);
prefresh(inp_win, 0, pad_start, rows-1, 0, rows-1, cols-1); prefresh(inp_win, 0, pad_start, rows-1, 0, rows-1, cols-1);
@ -214,6 +216,12 @@ inp_put_back(void)
prefresh(inp_win, 0, pad_start, rows-1, 0, rows-1, cols-1); prefresh(inp_win, 0, pad_start, rows-1, 0, rows-1, cols-1);
} }
int
inp_get_next_char(void)
{
return wgetch(inp_win);
}
void void
inp_replace_input(char *input, const char * const new_input, int *size) inp_replace_input(char *input, const char * const new_input, int *size)
{ {
@ -240,6 +248,7 @@ _handle_edit(const int ch, char *input, int *size)
char *next = NULL; char *next = NULL;
int inp_y = 0; int inp_y = 0;
int inp_x = 0; int inp_x = 0;
int next_ch;
getmaxyx(stdscr, rows, cols); getmaxyx(stdscr, rows, cols);
getyx(inp_win, inp_y, inp_x); getyx(inp_win, inp_y, inp_x);
@ -247,9 +256,50 @@ _handle_edit(const int ch, char *input, int *size)
switch(ch) { switch(ch) {
case 27: // ESC case 27: // ESC
*size = 0; // check for ALT-num
inp_clear(); next_ch = inp_get_next_char();
return 1; if (next_ch != ERR) {
switch (next_ch)
{
case '1':
win_switch_if_active(0);
break;
case '2':
win_switch_if_active(1);
break;
case '3':
win_switch_if_active(2);
break;
case '4':
win_switch_if_active(3);
break;
case '5':
win_switch_if_active(4);
break;
case '6':
win_switch_if_active(5);
break;
case '7':
win_switch_if_active(6);
break;
case '8':
win_switch_if_active(7);
break;
case '9':
win_switch_if_active(8);
break;
case '0':
win_switch_if_active(9);
break;
default:
break;
}
return 1;
} else {
*size = 0;
inp_clear();
return 1;
}
case 127: case 127:
case KEY_BACKSPACE: case KEY_BACKSPACE:
@ -372,6 +422,13 @@ _printable(const int ch)
ch != KEY_F(4) && ch != KEY_F(5) && ch != KEY_F(6) && ch != KEY_F(4) && ch != KEY_F(5) && ch != KEY_F(6) &&
ch != KEY_F(7) && ch != KEY_F(8) && ch != KEY_F(9) && ch != KEY_F(7) && ch != KEY_F(8) && ch != KEY_F(9) &&
ch != KEY_F(10) && ch!= KEY_F(11) && ch != KEY_F(12) && ch != KEY_F(10) && ch!= KEY_F(11) && ch != KEY_F(12) &&
ch != KEY_IC && ch != KEY_EIC && ch != KEY_RESIZE); ch != KEY_IC && ch != KEY_EIC && ch != KEY_RESIZE &&
!_special_key(ch));
} }
static gboolean
_special_key(const int ch)
{
char *str = unctrl(ch);
return ((strlen(str) > 1) && g_str_has_prefix(str, "^"));
}

View File

@ -48,6 +48,11 @@ static struct _jabber_conn_t {
int priority; int priority;
} jabber_conn; } jabber_conn;
// for auto reconnect
static char *saved_user;
static char *saved_password;
static GTimer *reconnect_timer;
static log_level_t _get_log_level(xmpp_log_level_t xmpp_level); static log_level_t _get_log_level(xmpp_log_level_t xmpp_level);
static xmpp_log_level_t _get_xmpp_log_level(); static xmpp_log_level_t _get_xmpp_log_level();
static void _xmpp_file_logger(void * const userdata, static void _xmpp_file_logger(void * const userdata,
@ -98,15 +103,22 @@ jabber_conn_status_t
jabber_connect(const char * const user, jabber_connect(const char * const user,
const char * const passwd) const char * const passwd)
{ {
log_info("Connecting as %s", user); if (saved_user == NULL) {
saved_user = strdup(user);
}
if (saved_password == NULL) {
saved_password = strdup(passwd);
}
log_info("Connecting as %s", saved_user);
xmpp_initialize(); xmpp_initialize();
jabber_conn.log = _xmpp_get_file_logger(); jabber_conn.log = _xmpp_get_file_logger();
jabber_conn.ctx = xmpp_ctx_new(NULL, jabber_conn.log); jabber_conn.ctx = xmpp_ctx_new(NULL, jabber_conn.log);
jabber_conn.conn = xmpp_conn_new(jabber_conn.ctx); jabber_conn.conn = xmpp_conn_new(jabber_conn.ctx);
xmpp_conn_set_jid(jabber_conn.conn, user); xmpp_conn_set_jid(jabber_conn.conn, saved_user);
xmpp_conn_set_pass(jabber_conn.conn, passwd); xmpp_conn_set_pass(jabber_conn.conn, saved_password);
if (jabber_conn.tls_disabled) if (jabber_conn.tls_disabled)
xmpp_conn_disable_tls(jabber_conn.conn); xmpp_conn_disable_tls(jabber_conn.conn);
@ -141,10 +153,21 @@ jabber_disconnect(void)
void void
jabber_process_events(void) jabber_process_events(void)
{ {
// run xmpp event loop if connected, connecting or disconnecting
if (jabber_conn.conn_status == JABBER_CONNECTED if (jabber_conn.conn_status == JABBER_CONNECTED
|| jabber_conn.conn_status == JABBER_CONNECTING || jabber_conn.conn_status == JABBER_CONNECTING
|| jabber_conn.conn_status == JABBER_DISCONNECTING) || jabber_conn.conn_status == JABBER_DISCONNECTING) {
xmpp_run_once(jabber_conn.ctx, 10); xmpp_run_once(jabber_conn.ctx, 10);
// check timer and reconnect if disconnected and timer set
} else if ((jabber_conn.conn_status == JABBER_DISCONNECTED) &&
(reconnect_timer != NULL)) {
if (g_timer_elapsed(reconnect_timer, NULL) > (prefs_get_reconnect() * 1.0)) {
log_debug("Attempting reconncet as %s", saved_user);
jabber_connect(saved_user, saved_password);
}
}
} }
void void
@ -400,6 +423,8 @@ jabber_get_status(void)
void void
jabber_free_resources(void) jabber_free_resources(void)
{ {
saved_user = NULL;
saved_password = NULL;
chat_sessions_clear(); chat_sessions_clear();
xmpp_conn_release(jabber_conn.conn); xmpp_conn_release(jabber_conn.conn);
xmpp_ctx_free(jabber_conn.ctx); xmpp_ctx_free(jabber_conn.ctx);
@ -624,6 +649,7 @@ _connection_handler(xmpp_conn_t * const conn,
{ {
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata; xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
// login success
if (status == XMPP_CONN_CONNECT) { if (status == XMPP_CONN_CONNECT) {
const char *jid = xmpp_conn_get_jid(conn); const char *jid = xmpp_conn_get_jid(conn);
prof_handle_login_success(jid); prof_handle_login_success(jid);
@ -637,26 +663,56 @@ _connection_handler(xmpp_conn_t * const conn,
_jabber_roster_request(); _jabber_roster_request();
jabber_conn.conn_status = JABBER_CONNECTED; jabber_conn.conn_status = JABBER_CONNECTED;
jabber_conn.presence = PRESENCE_ONLINE; jabber_conn.presence = PRESENCE_ONLINE;
if (reconnect_timer != NULL) {
g_timer_destroy(reconnect_timer);
reconnect_timer = NULL;
}
} else { } else {
// received close stream response from server after disconnect // received close stream response from server after disconnect
if (jabber_conn.conn_status == JABBER_DISCONNECTING) { if (jabber_conn.conn_status == JABBER_DISCONNECTING) {
jabber_conn.conn_status = JABBER_DISCONNECTED; jabber_conn.conn_status = JABBER_DISCONNECTED;
jabber_conn.presence = PRESENCE_OFFLINE; jabber_conn.presence = PRESENCE_OFFLINE;
if (saved_user != NULL) {
free(saved_user);
saved_user = NULL;
}
if (saved_password != NULL) {
free(saved_password);
saved_password = NULL;
}
// lost connection for unkown reason // lost connection for unkown reason
} else if (jabber_conn.conn_status == JABBER_CONNECTED) { } else if (jabber_conn.conn_status == JABBER_CONNECTED) {
prof_handle_lost_connection(); prof_handle_lost_connection();
reconnect_timer = g_timer_new();
xmpp_stop(ctx); xmpp_stop(ctx);
jabber_conn.conn_status = JABBER_DISCONNECTED; jabber_conn.conn_status = JABBER_DISCONNECTED;
jabber_conn.presence = PRESENCE_OFFLINE; jabber_conn.presence = PRESENCE_OFFLINE;
// login attempt failed // login attempt failed
} else { } else {
prof_handle_failed_login(); if (reconnect_timer == NULL) {
xmpp_stop(ctx); prof_handle_failed_login();
jabber_conn.conn_status = JABBER_DISCONNECTED; if (saved_user != NULL) {
jabber_conn.presence = PRESENCE_OFFLINE; free(saved_user);
saved_user = NULL;
}
if (saved_password != NULL) {
free(saved_password);
saved_password = NULL;
}
xmpp_stop(ctx);
jabber_conn.conn_status = JABBER_DISCONNECTED;
jabber_conn.presence = PRESENCE_OFFLINE;
} else {
xmpp_stop(ctx);
g_timer_start(reconnect_timer);
jabber_conn.conn_status = JABBER_DISCONNECTED;
jabber_conn.presence = PRESENCE_OFFLINE;
}
} }
} }
} }

View File

@ -44,56 +44,6 @@ gint log_maxsize = 0;
static PAutocomplete login_ac; static PAutocomplete login_ac;
static PAutocomplete boolean_choice_ac; static PAutocomplete boolean_choice_ac;
struct colour_string_t {
char *str;
NCURSES_COLOR_T colour;
};
static int num_colours = 9;
static struct colour_string_t colours[] = {
{ "default", -1 },
{ "white", COLOR_WHITE },
{ "green", COLOR_GREEN },
{ "red", COLOR_RED },
{ "yellow", COLOR_YELLOW },
{ "blue", COLOR_BLUE },
{ "cyan", COLOR_CYAN },
{ "black", COLOR_BLACK },
{ "magenta", COLOR_MAGENTA },
};
// colour preferences
static struct colours_t {
NCURSES_COLOR_T bkgnd;
NCURSES_COLOR_T titlebar;
NCURSES_COLOR_T statusbar;
NCURSES_COLOR_T titlebartext;
NCURSES_COLOR_T titlebarbrackets;
NCURSES_COLOR_T statusbartext;
NCURSES_COLOR_T statusbarbrackets;
NCURSES_COLOR_T statusbaractive;
NCURSES_COLOR_T statusbarnew;
NCURSES_COLOR_T maintext;
NCURSES_COLOR_T splashtext;
NCURSES_COLOR_T online;
NCURSES_COLOR_T away;
NCURSES_COLOR_T xa;
NCURSES_COLOR_T dnd;
NCURSES_COLOR_T chat;
NCURSES_COLOR_T offline;
NCURSES_COLOR_T typing;
NCURSES_COLOR_T gone;
NCURSES_COLOR_T error;
NCURSES_COLOR_T incoming;
NCURSES_COLOR_T roominfo;
NCURSES_COLOR_T me;
NCURSES_COLOR_T them;
} colour_prefs;
static NCURSES_COLOR_T _lookup_colour(const char * const colour);
static void _set_colour(gchar *val, NCURSES_COLOR_T *pref,
NCURSES_COLOR_T def);
static void _load_colours(void);
static void _save_prefs(void); static void _save_prefs(void);
void void
@ -125,8 +75,6 @@ prefs_load(void)
} }
free(jids); free(jids);
_load_colours();
err = NULL; err = NULL;
log_maxsize = g_key_file_get_integer(prefs, "log", "maxsize", &err); log_maxsize = g_key_file_get_integer(prefs, "log", "maxsize", &err);
if (err != NULL) { if (err != NULL) {
@ -147,111 +95,6 @@ prefs_close(void)
g_key_file_free(prefs); g_key_file_free(prefs);
} }
static NCURSES_COLOR_T
_lookup_colour(const char * const colour)
{
int i;
for (i = 0; i < num_colours; i++) {
if (strcmp(colours[i].str, colour) == 0) {
return colours[i].colour;
}
}
return -99;
}
static void
_set_colour(gchar *val, NCURSES_COLOR_T *pref,
NCURSES_COLOR_T def)
{
if(!val) {
*pref = def;
} else {
NCURSES_COLOR_T col = _lookup_colour(val);
if (col == -99) {
*pref = def;
} else {
*pref = col;
}
}
}
static void
_load_colours(void)
{
gchar *bkgnd_val = g_key_file_get_string(prefs, "colours", "bkgnd", NULL);
_set_colour(bkgnd_val, &colour_prefs.bkgnd, -1);
gchar *titlebar_val = g_key_file_get_string(prefs, "colours", "titlebar", NULL);
_set_colour(titlebar_val, &colour_prefs.titlebar, COLOR_BLUE);
gchar *statusbar_val = g_key_file_get_string(prefs, "colours", "statusbar", NULL);
_set_colour(statusbar_val, &colour_prefs.statusbar, COLOR_BLUE);
gchar *titlebartext_val = g_key_file_get_string(prefs, "colours", "titlebartext", NULL);
_set_colour(titlebartext_val, &colour_prefs.titlebartext, COLOR_WHITE);
gchar *titlebarbrackets_val = g_key_file_get_string(prefs, "colours", "titlebarbrackets", NULL);
_set_colour(titlebarbrackets_val, &colour_prefs.titlebarbrackets, COLOR_CYAN);
gchar *statusbartext_val = g_key_file_get_string(prefs, "colours", "statusbartext", NULL);
_set_colour(statusbartext_val, &colour_prefs.statusbartext, COLOR_WHITE);
gchar *statusbarbrackets_val = g_key_file_get_string(prefs, "colours", "statusbarbrackets", NULL);
_set_colour(statusbarbrackets_val, &colour_prefs.statusbarbrackets, COLOR_CYAN);
gchar *statusbaractive_val = g_key_file_get_string(prefs, "colours", "statusbaractive", NULL);
_set_colour(statusbaractive_val, &colour_prefs.statusbaractive, COLOR_CYAN);
gchar *statusbarnew_val = g_key_file_get_string(prefs, "colours", "statusbarnew", NULL);
_set_colour(statusbarnew_val, &colour_prefs.statusbarnew, COLOR_WHITE);
gchar *maintext_val = g_key_file_get_string(prefs, "colours", "maintext", NULL);
_set_colour(maintext_val, &colour_prefs.maintext, COLOR_WHITE);
gchar *splashtext_val = g_key_file_get_string(prefs, "colours", "splashtext", NULL);
_set_colour(splashtext_val, &colour_prefs.splashtext, COLOR_CYAN);
gchar *online_val = g_key_file_get_string(prefs, "colours", "online", NULL);
_set_colour(online_val, &colour_prefs.online, COLOR_GREEN);
gchar *away_val = g_key_file_get_string(prefs, "colours", "away", NULL);
_set_colour(away_val, &colour_prefs.away, COLOR_CYAN);
gchar *chat_val = g_key_file_get_string(prefs, "colours", "chat", NULL);
_set_colour(chat_val, &colour_prefs.chat, COLOR_GREEN);
gchar *dnd_val = g_key_file_get_string(prefs, "colours", "dnd", NULL);
_set_colour(dnd_val, &colour_prefs.dnd, COLOR_RED);
gchar *xa_val = g_key_file_get_string(prefs, "colours", "xa", NULL);
_set_colour(xa_val, &colour_prefs.xa, COLOR_CYAN);
gchar *offline_val = g_key_file_get_string(prefs, "colours", "offline", NULL);
_set_colour(offline_val, &colour_prefs.offline, COLOR_RED);
gchar *typing_val = g_key_file_get_string(prefs, "colours", "typing", NULL);
_set_colour(typing_val, &colour_prefs.typing, COLOR_YELLOW);
gchar *gone_val = g_key_file_get_string(prefs, "colours", "gone", NULL);
_set_colour(gone_val, &colour_prefs.gone, COLOR_RED);
gchar *error_val = g_key_file_get_string(prefs, "colours", "error", NULL);
_set_colour(error_val, &colour_prefs.error, COLOR_RED);
gchar *incoming_val = g_key_file_get_string(prefs, "colours", "incoming", NULL);
_set_colour(incoming_val, &colour_prefs.incoming, COLOR_YELLOW);
gchar *roominfo_val = g_key_file_get_string(prefs, "colours", "roominfo", NULL);
_set_colour(roominfo_val, &colour_prefs.roominfo, COLOR_YELLOW);
gchar *me_val = g_key_file_get_string(prefs, "colours", "me", NULL);
_set_colour(me_val, &colour_prefs.me, COLOR_YELLOW);
gchar *them_val = g_key_file_get_string(prefs, "colours", "them", NULL);
_set_colour(them_val, &colour_prefs.them, COLOR_GREEN);
}
char * char *
prefs_find_login(char *prefix) prefs_find_login(char *prefix)
{ {
@ -289,6 +132,19 @@ prefs_set_beep(gboolean value)
_save_prefs(); _save_prefs();
} }
gchar *
prefs_get_theme(void)
{
return g_key_file_get_string(prefs, "ui", "theme", NULL);
}
void
prefs_set_theme(gchar *value)
{
g_key_file_set_string(prefs, "ui", "theme", value);
_save_prefs();
}
gboolean gboolean
prefs_get_states(void) prefs_get_states(void)
{ {
@ -384,6 +240,19 @@ prefs_set_priority(gint value)
_save_prefs(); _save_prefs();
} }
gint
prefs_get_reconnect(void)
{
return g_key_file_get_integer(prefs, "jabber", "reconnect", NULL);
}
void
prefs_set_reconnect(gint value)
{
g_key_file_set_integer(prefs, "jabber", "reconnect", value);
_save_prefs();
}
gboolean gboolean
prefs_get_vercheck(void) prefs_get_vercheck(void)
{ {
@ -511,147 +380,3 @@ _save_prefs(void)
char *g_prefs_data = g_key_file_to_data(prefs, &g_data_size, NULL); char *g_prefs_data = g_key_file_to_data(prefs, &g_data_size, NULL);
g_file_set_contents(prefs_loc->str, g_prefs_data, g_data_size, NULL); g_file_set_contents(prefs_loc->str, g_prefs_data, g_data_size, NULL);
} }
NCURSES_COLOR_T
prefs_get_bkgnd()
{
return colour_prefs.bkgnd;
}
NCURSES_COLOR_T
prefs_get_titlebar()
{
return colour_prefs.titlebar;
}
NCURSES_COLOR_T
prefs_get_statusbar()
{
return colour_prefs.statusbar;
}
NCURSES_COLOR_T
prefs_get_titlebartext()
{
return colour_prefs.titlebartext;
}
NCURSES_COLOR_T
prefs_get_titlebarbrackets()
{
return colour_prefs.titlebarbrackets;
}
NCURSES_COLOR_T
prefs_get_statusbartext()
{
return colour_prefs.statusbartext;
}
NCURSES_COLOR_T
prefs_get_statusbarbrackets()
{
return colour_prefs.statusbarbrackets;
}
NCURSES_COLOR_T
prefs_get_statusbaractive()
{
return colour_prefs.statusbaractive;
}
NCURSES_COLOR_T
prefs_get_statusbarnew()
{
return colour_prefs.statusbarnew;
}
NCURSES_COLOR_T
prefs_get_maintext()
{
return colour_prefs.maintext;
}
NCURSES_COLOR_T
prefs_get_splashtext()
{
return colour_prefs.splashtext;
}
NCURSES_COLOR_T
prefs_get_online()
{
return colour_prefs.online;
}
NCURSES_COLOR_T
prefs_get_away()
{
return colour_prefs.away;
}
NCURSES_COLOR_T
prefs_get_chat()
{
return colour_prefs.chat;
}
NCURSES_COLOR_T
prefs_get_dnd()
{
return colour_prefs.dnd;
}
NCURSES_COLOR_T
prefs_get_xa()
{
return colour_prefs.xa;
}
NCURSES_COLOR_T
prefs_get_offline()
{
return colour_prefs.offline;
}
NCURSES_COLOR_T
prefs_get_typing()
{
return colour_prefs.typing;
}
NCURSES_COLOR_T
prefs_get_gone()
{
return colour_prefs.gone;
}
NCURSES_COLOR_T
prefs_get_error()
{
return colour_prefs.error;
}
NCURSES_COLOR_T
prefs_get_incoming()
{
return colour_prefs.incoming;
}
NCURSES_COLOR_T
prefs_get_roominfo()
{
return colour_prefs.roominfo;
}
NCURSES_COLOR_T
prefs_get_me()
{
return colour_prefs.me;
}
NCURSES_COLOR_T
prefs_get_them()
{
return colour_prefs.them;
}

View File

@ -63,6 +63,8 @@ gboolean prefs_get_states(void);
void prefs_set_states(gboolean value); void prefs_set_states(gboolean value);
gboolean prefs_get_outtype(void); gboolean prefs_get_outtype(void);
void prefs_set_outtype(gboolean value); void prefs_set_outtype(gboolean value);
gchar * prefs_get_theme(void);
void prefs_set_theme(gchar *value);
void prefs_set_notify_message(gboolean value); void prefs_set_notify_message(gboolean value);
gboolean prefs_get_notify_message(void); gboolean prefs_get_notify_message(void);
@ -74,32 +76,9 @@ void prefs_set_max_log_size(gint value);
gint prefs_get_max_log_size(void); gint prefs_get_max_log_size(void);
void prefs_set_priority(gint value); void prefs_set_priority(gint value);
gint prefs_get_priority(void); gint prefs_get_priority(void);
void prefs_set_reconnect(gint value);
gint prefs_get_reconnect(void);
void prefs_add_login(const char *jid); void prefs_add_login(const char *jid);
NCURSES_COLOR_T prefs_get_bkgnd();
NCURSES_COLOR_T prefs_get_titlebar();
NCURSES_COLOR_T prefs_get_statusbar();
NCURSES_COLOR_T prefs_get_titlebartext();
NCURSES_COLOR_T prefs_get_titlebarbrackets();
NCURSES_COLOR_T prefs_get_statusbartext();
NCURSES_COLOR_T prefs_get_statusbarbrackets();
NCURSES_COLOR_T prefs_get_statusbaractive();
NCURSES_COLOR_T prefs_get_statusbarnew();
NCURSES_COLOR_T prefs_get_maintext();
NCURSES_COLOR_T prefs_get_splashtext();
NCURSES_COLOR_T prefs_get_online();
NCURSES_COLOR_T prefs_get_away();
NCURSES_COLOR_T prefs_get_chat();
NCURSES_COLOR_T prefs_get_dnd();
NCURSES_COLOR_T prefs_get_xa();
NCURSES_COLOR_T prefs_get_offline();
NCURSES_COLOR_T prefs_get_typing();
NCURSES_COLOR_T prefs_get_gone();
NCURSES_COLOR_T prefs_get_error();
NCURSES_COLOR_T prefs_get_incoming();
NCURSES_COLOR_T prefs_get_roominfo();
NCURSES_COLOR_T prefs_get_me();
NCURSES_COLOR_T prefs_get_them();
#endif #endif

View File

@ -39,6 +39,7 @@
#include "preferences.h" #include "preferences.h"
#include "profanity.h" #include "profanity.h"
#include "room_chat.h" #include "room_chat.h"
#include "theme.h"
#include "jabber.h" #include "jabber.h"
#include "ui.h" #include "ui.h"
@ -446,6 +447,7 @@ _init(const int disable_tls, char *log_level)
log_info("Starting Profanity (%s)...", PACKAGE_VERSION); log_info("Starting Profanity (%s)...", PACKAGE_VERSION);
chat_log_init(); chat_log_init();
prefs_load(); prefs_load();
theme_load(prefs_get_theme());
gui_init(); gui_init();
jabber_init(disable_tls); jabber_init(disable_tls);
cmd_init(); cmd_init();
@ -462,6 +464,7 @@ _shutdown(void)
gui_close(); gui_close();
chat_log_close(); chat_log_close();
prefs_close(); prefs_close();
theme_close();
cmd_close(); cmd_close();
log_close(); log_close();
} }

View File

@ -32,13 +32,14 @@
#include <ncurses/ncurses.h> #include <ncurses/ncurses.h>
#endif #endif
#include "theme.h"
#include "ui.h" #include "ui.h"
static WINDOW *status_bar; static WINDOW *status_bar;
static char *message = NULL; static char *message = NULL;
static char _active[29] = "[ ][ ][ ][ ][ ][ ][ ][ ][ ]"; static char _active[31] = "[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]";
static int is_active[9]; static int is_active[10];
static int is_new[9]; static int is_new[10];
static int dirty; static int dirty;
static GDateTime *last_time; static GDateTime *last_time;
@ -50,7 +51,9 @@ create_status_bar(void)
int rows, cols, i; int rows, cols, i;
getmaxyx(stdscr, rows, cols); getmaxyx(stdscr, rows, cols);
for (i = 0; i < 9; i++) { is_active[0] = TRUE;
is_new[0] = FALSE;
for (i = 1; i < 10; i++) {
is_active[i] = FALSE; is_active[i] = FALSE;
is_new[i] = FALSE; is_new[i] = FALSE;
} }
@ -58,7 +61,7 @@ create_status_bar(void)
status_bar = newwin(1, cols, rows-2, 0); status_bar = newwin(1, cols, rows-2, 0);
wbkgd(status_bar, COLOUR_STATUS_TEXT); wbkgd(status_bar, COLOUR_STATUS_TEXT);
wattron(status_bar, COLOUR_STATUS_BRACKET); wattron(status_bar, COLOUR_STATUS_BRACKET);
mvwprintw(status_bar, 0, cols - 29, _active); mvwprintw(status_bar, 0, cols - 31, _active);
wattroff(status_bar, COLOUR_STATUS_BRACKET); wattroff(status_bar, COLOUR_STATUS_BRACKET);
last_time = g_date_time_new_now_local(); last_time = g_date_time_new_now_local();
@ -98,18 +101,18 @@ status_bar_resize(void)
wbkgd(status_bar, COLOUR_STATUS_TEXT); wbkgd(status_bar, COLOUR_STATUS_TEXT);
wclear(status_bar); wclear(status_bar);
wattron(status_bar, COLOUR_STATUS_BRACKET); wattron(status_bar, COLOUR_STATUS_BRACKET);
mvwprintw(status_bar, 0, cols - 29, _active); mvwprintw(status_bar, 0, cols - 31, _active);
wattroff(status_bar, COLOUR_STATUS_BRACKET); wattroff(status_bar, COLOUR_STATUS_BRACKET);
for(i = 0; i < 9; i++) { for(i = 0; i < 10; i++) {
if (is_new[i]) if (is_new[i])
status_bar_new(i+1); status_bar_new(i);
else if (is_active[i]) else if (is_active[i])
status_bar_active(i+1); status_bar_active(i);
} }
if (message != NULL) if (message != NULL)
mvwprintw(status_bar, 0, 9, message); mvwprintw(status_bar, 0, 10, message);
last_time = g_date_time_new_now_local(); last_time = g_date_time_new_now_local();
dirty = TRUE; dirty = TRUE;
@ -118,16 +121,14 @@ status_bar_resize(void)
void void
status_bar_inactive(const int win) status_bar_inactive(const int win)
{ {
is_active[win-1] = FALSE; is_active[win] = FALSE;
is_new[win-1] = FALSE; is_new[win] = FALSE;
int active_pos = 1 + ((win -1) * 3); int active_pos = 1 + (win * 3);
int cols = getmaxx(stdscr); int cols = getmaxx(stdscr);
mvwaddch(status_bar, 0, cols - 29 + active_pos, ' '); mvwaddch(status_bar, 0, cols - 31 + active_pos, ' ');
if (win == 9)
mvwaddch(status_bar, 0, cols - 29 + active_pos + 1, ' ');
dirty = TRUE; dirty = TRUE;
} }
@ -135,18 +136,18 @@ status_bar_inactive(const int win)
void void
status_bar_active(const int win) status_bar_active(const int win)
{ {
is_active[win-1] = TRUE; is_active[win] = TRUE;
is_new[win-1] = FALSE; is_new[win] = FALSE;
int active_pos = 1 + ((win -1) * 3); int active_pos = 1 + (win * 3);
int cols = getmaxx(stdscr); int cols = getmaxx(stdscr);
wattron(status_bar, COLOUR_STATUS_ACTIVE); wattron(status_bar, COLOUR_STATUS_ACTIVE);
if (win < 9) if (win+1 < 10)
mvwprintw(status_bar, 0, cols - 29 + active_pos, "%d", win+1); mvwprintw(status_bar, 0, cols - 31 + active_pos, "%d", win+1);
else else
mvwprintw(status_bar, 0, cols - 29 + active_pos, "10"); mvwprintw(status_bar, 0, cols - 31 + active_pos, "0");
wattroff(status_bar, COLOUR_STATUS_ACTIVE); wattroff(status_bar, COLOUR_STATUS_ACTIVE);
dirty = TRUE; dirty = TRUE;
@ -155,19 +156,19 @@ status_bar_active(const int win)
void void
status_bar_new(const int win) status_bar_new(const int win)
{ {
is_active[win-1] = TRUE; is_active[win] = TRUE;
is_new[win-1] = TRUE; is_new[win] = TRUE;
int active_pos = 1 + ((win -1) * 3); int active_pos = 1 + (win * 3);
int cols = getmaxx(stdscr); int cols = getmaxx(stdscr);
wattron(status_bar, COLOUR_STATUS_NEW); wattron(status_bar, COLOUR_STATUS_NEW);
wattron(status_bar, A_BLINK); wattron(status_bar, A_BLINK);
if (win < 9) if (win+1 < 10)
mvwprintw(status_bar, 0, cols - 29 + active_pos, "%d", win+1); mvwprintw(status_bar, 0, cols - 31 + active_pos, "%d", win+1);
else else
mvwprintw(status_bar, 0, cols - 29 + active_pos, "10"); mvwprintw(status_bar, 0, cols - 31 + active_pos, "0");
wattroff(status_bar, COLOUR_STATUS_NEW); wattroff(status_bar, COLOUR_STATUS_NEW);
wattroff(status_bar, A_BLINK); wattroff(status_bar, A_BLINK);
@ -193,20 +194,20 @@ status_bar_print_message(const char * const msg)
message = (char *) malloc((strlen(msg) + 1) * sizeof(char)); message = (char *) malloc((strlen(msg) + 1) * sizeof(char));
strcpy(message, msg); strcpy(message, msg);
mvwprintw(status_bar, 0, 9, message); mvwprintw(status_bar, 0, 10, message);
int cols = getmaxx(stdscr); int cols = getmaxx(stdscr);
wattron(status_bar, COLOUR_STATUS_BRACKET); wattron(status_bar, COLOUR_STATUS_BRACKET);
mvwprintw(status_bar, 0, cols - 29, _active); mvwprintw(status_bar, 0, cols - 31, _active);
wattroff(status_bar, COLOUR_STATUS_BRACKET); wattroff(status_bar, COLOUR_STATUS_BRACKET);
int i; int i;
for(i = 0; i < 9; i++) { for(i = 0; i < 10; i++) {
if (is_new[i]) if (is_new[i])
status_bar_new(i+1); status_bar_new(i);
else if (is_active[i]) else if (is_active[i])
status_bar_active(i+1); status_bar_active(i);
} }
dirty = TRUE; dirty = TRUE;
@ -221,7 +222,9 @@ status_bar_clear(void)
} }
int i; int i;
for (i = 0; i < 9; i++) { is_active[0] = TRUE;
is_new[0] = FALSE;
for (i = 1; i < 10; i++) {
is_active[i] = FALSE; is_active[i] = FALSE;
is_new[i] = FALSE; is_new[i] = FALSE;
} }
@ -231,7 +234,7 @@ status_bar_clear(void)
int cols = getmaxx(stdscr); int cols = getmaxx(stdscr);
wattron(status_bar, COLOUR_STATUS_BRACKET); wattron(status_bar, COLOUR_STATUS_BRACKET);
mvwprintw(status_bar, 0, cols - 29, _active); mvwprintw(status_bar, 0, cols - 31, _active);
wattroff(status_bar, COLOUR_STATUS_BRACKET); wattroff(status_bar, COLOUR_STATUS_BRACKET);
dirty = TRUE; dirty = TRUE;
@ -250,15 +253,15 @@ status_bar_clear_message(void)
int cols = getmaxx(stdscr); int cols = getmaxx(stdscr);
wattron(status_bar, COLOUR_STATUS_BRACKET); wattron(status_bar, COLOUR_STATUS_BRACKET);
mvwprintw(status_bar, 0, cols - 29, _active); mvwprintw(status_bar, 0, cols - 31, _active);
wattroff(status_bar, COLOUR_STATUS_BRACKET); wattroff(status_bar, COLOUR_STATUS_BRACKET);
int i; int i;
for(i = 0; i < 9; i++) { for(i = 0; i < 10; i++) {
if (is_new[i]) if (is_new[i])
status_bar_new(i+1); status_bar_new(i);
else if (is_active[i]) else if (is_active[i])
status_bar_active(i+1); status_bar_active(i);
} }
dirty = TRUE; dirty = TRUE;

303
src/theme.c Normal file
View File

@ -0,0 +1,303 @@
/*
* theme.c
*
* Copyright (C) 2012 James Booth <boothj5@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#ifdef HAVE_NCURSES_H
#include <ncurses.h>
#endif
#ifdef HAVE_NCURSES_NCURSES_H
#include <ncurses/ncurses.h>
#endif
#include "log.h"
#include "theme.h"
static GString *theme_loc;
static GKeyFile *theme;
struct colour_string_t {
char *str;
NCURSES_COLOR_T colour;
};
static int num_colours = 9;
static struct colour_string_t colours[] = {
{ "default", -1 },
{ "white", COLOR_WHITE },
{ "green", COLOR_GREEN },
{ "red", COLOR_RED },
{ "yellow", COLOR_YELLOW },
{ "blue", COLOR_BLUE },
{ "cyan", COLOR_CYAN },
{ "black", COLOR_BLACK },
{ "magenta", COLOR_MAGENTA },
};
// colour preferences
static struct colours_t {
NCURSES_COLOR_T bkgnd;
NCURSES_COLOR_T titlebar;
NCURSES_COLOR_T statusbar;
NCURSES_COLOR_T titlebartext;
NCURSES_COLOR_T titlebarbrackets;
NCURSES_COLOR_T statusbartext;
NCURSES_COLOR_T statusbarbrackets;
NCURSES_COLOR_T statusbaractive;
NCURSES_COLOR_T statusbarnew;
NCURSES_COLOR_T maintext;
NCURSES_COLOR_T inputtext;
NCURSES_COLOR_T timetext;
NCURSES_COLOR_T splashtext;
NCURSES_COLOR_T online;
NCURSES_COLOR_T away;
NCURSES_COLOR_T xa;
NCURSES_COLOR_T dnd;
NCURSES_COLOR_T chat;
NCURSES_COLOR_T offline;
NCURSES_COLOR_T typing;
NCURSES_COLOR_T gone;
NCURSES_COLOR_T error;
NCURSES_COLOR_T incoming;
NCURSES_COLOR_T roominfo;
NCURSES_COLOR_T me;
NCURSES_COLOR_T them;
} colour_prefs;
static NCURSES_COLOR_T _lookup_colour(const char * const colour);
static void _set_colour(gchar *val, NCURSES_COLOR_T *pref,
NCURSES_COLOR_T def);
static void _load_colours(void);
void
theme_load(const char * const theme_name)
{
log_info("Loading theme");
theme = g_key_file_new();
if (theme_name != NULL) {
theme_loc = g_string_new(getenv("HOME"));
g_string_append(theme_loc, "/.profanity/themes/");
g_string_append(theme_loc, theme_name);
g_key_file_load_from_file(theme, theme_loc->str, G_KEY_FILE_KEEP_COMMENTS,
NULL);
}
_load_colours();
}
gboolean
theme_change(const char * const theme_name)
{
// use default theme
if (strcmp(theme_name, "default") == 0) {
g_key_file_free(theme);
theme = g_key_file_new();
_load_colours();
return TRUE;
} else {
GString *new_theme_file = g_string_new(getenv("HOME"));
g_string_append(new_theme_file, "/.profanity/themes/");
g_string_append(new_theme_file, theme_name);
// no theme file found
if (!g_file_test(new_theme_file->str, G_FILE_TEST_EXISTS)) {
log_info("Theme does not exist \"%s\"", theme_name);
g_string_free(new_theme_file, TRUE);
return FALSE;
// load from theme file
} else {
g_string_free(theme_loc, TRUE);
theme_loc = new_theme_file;
log_info("Changing theme to \"%s\"", theme_name);
g_key_file_free(theme);
theme = g_key_file_new();
g_key_file_load_from_file(theme, theme_loc->str, G_KEY_FILE_KEEP_COMMENTS,
NULL);
_load_colours();
return TRUE;
}
}
}
void
theme_close(void)
{
g_key_file_free(theme);
}
void
theme_init_colours(void)
{
// main text
init_pair(1, colour_prefs.maintext, colour_prefs.bkgnd);
init_pair(2, colour_prefs.splashtext, colour_prefs.bkgnd);
init_pair(3, colour_prefs.error, colour_prefs.bkgnd);
init_pair(4, colour_prefs.incoming, colour_prefs.bkgnd);
init_pair(5, colour_prefs.inputtext, colour_prefs.bkgnd);
init_pair(6, colour_prefs.timetext, colour_prefs.bkgnd);
// title bar
init_pair(10, colour_prefs.titlebartext, colour_prefs.titlebar);
init_pair(11, colour_prefs.titlebarbrackets, colour_prefs.titlebar);
// status bar
init_pair(20, colour_prefs.statusbartext, colour_prefs.statusbar);
init_pair(21, colour_prefs.statusbarbrackets, colour_prefs.statusbar);
init_pair(22, colour_prefs.statusbaractive, colour_prefs.statusbar);
init_pair(23, colour_prefs.statusbarnew, colour_prefs.statusbar);
// chat
init_pair(30, colour_prefs.me, colour_prefs.bkgnd);
init_pair(31, colour_prefs.them, colour_prefs.bkgnd);
// room chat
init_pair(40, colour_prefs.roominfo, colour_prefs.bkgnd);
// statuses
init_pair(50, colour_prefs.online, colour_prefs.bkgnd);
init_pair(51, colour_prefs.offline, colour_prefs.bkgnd);
init_pair(52, colour_prefs.away, colour_prefs.bkgnd);
init_pair(53, colour_prefs.chat, colour_prefs.bkgnd);
init_pair(54, colour_prefs.dnd, colour_prefs.bkgnd);
init_pair(55, colour_prefs.xa, colour_prefs.bkgnd);
// states
init_pair(60, colour_prefs.typing, colour_prefs.bkgnd);
init_pair(61, colour_prefs.gone, colour_prefs.bkgnd);
}
static NCURSES_COLOR_T
_lookup_colour(const char * const colour)
{
int i;
for (i = 0; i < num_colours; i++) {
if (strcmp(colours[i].str, colour) == 0) {
return colours[i].colour;
}
}
return -99;
}
static void
_set_colour(gchar *val, NCURSES_COLOR_T *pref,
NCURSES_COLOR_T def)
{
if(!val) {
*pref = def;
} else {
NCURSES_COLOR_T col = _lookup_colour(val);
if (col == -99) {
*pref = def;
} else {
*pref = col;
}
}
}
static void
_load_colours(void)
{
gchar *bkgnd_val = g_key_file_get_string(theme, "colours", "bkgnd", NULL);
_set_colour(bkgnd_val, &colour_prefs.bkgnd, -1);
gchar *titlebar_val = g_key_file_get_string(theme, "colours", "titlebar", NULL);
_set_colour(titlebar_val, &colour_prefs.titlebar, COLOR_BLUE);
gchar *statusbar_val = g_key_file_get_string(theme, "colours", "statusbar", NULL);
_set_colour(statusbar_val, &colour_prefs.statusbar, COLOR_BLUE);
gchar *titlebartext_val = g_key_file_get_string(theme, "colours", "titlebartext", NULL);
_set_colour(titlebartext_val, &colour_prefs.titlebartext, COLOR_WHITE);
gchar *titlebarbrackets_val = g_key_file_get_string(theme, "colours", "titlebarbrackets", NULL);
_set_colour(titlebarbrackets_val, &colour_prefs.titlebarbrackets, COLOR_CYAN);
gchar *statusbartext_val = g_key_file_get_string(theme, "colours", "statusbartext", NULL);
_set_colour(statusbartext_val, &colour_prefs.statusbartext, COLOR_WHITE);
gchar *statusbarbrackets_val = g_key_file_get_string(theme, "colours", "statusbarbrackets", NULL);
_set_colour(statusbarbrackets_val, &colour_prefs.statusbarbrackets, COLOR_CYAN);
gchar *statusbaractive_val = g_key_file_get_string(theme, "colours", "statusbaractive", NULL);
_set_colour(statusbaractive_val, &colour_prefs.statusbaractive, COLOR_CYAN);
gchar *statusbarnew_val = g_key_file_get_string(theme, "colours", "statusbarnew", NULL);
_set_colour(statusbarnew_val, &colour_prefs.statusbarnew, COLOR_WHITE);
gchar *maintext_val = g_key_file_get_string(theme, "colours", "maintext", NULL);
_set_colour(maintext_val, &colour_prefs.maintext, COLOR_WHITE);
gchar *splashtext_val = g_key_file_get_string(theme, "colours", "splashtext", NULL);
_set_colour(splashtext_val, &colour_prefs.splashtext, COLOR_CYAN);
gchar *inputtext_val = g_key_file_get_string(theme, "colours", "inputtext", NULL);
_set_colour(inputtext_val, &colour_prefs.inputtext, COLOR_WHITE);
gchar *timetext_val = g_key_file_get_string(theme, "colours", "timetext", NULL);
_set_colour(timetext_val, &colour_prefs.timetext, COLOR_WHITE);
gchar *online_val = g_key_file_get_string(theme, "colours", "online", NULL);
_set_colour(online_val, &colour_prefs.online, COLOR_GREEN);
gchar *away_val = g_key_file_get_string(theme, "colours", "away", NULL);
_set_colour(away_val, &colour_prefs.away, COLOR_CYAN);
gchar *chat_val = g_key_file_get_string(theme, "colours", "chat", NULL);
_set_colour(chat_val, &colour_prefs.chat, COLOR_GREEN);
gchar *dnd_val = g_key_file_get_string(theme, "colours", "dnd", NULL);
_set_colour(dnd_val, &colour_prefs.dnd, COLOR_RED);
gchar *xa_val = g_key_file_get_string(theme, "colours", "xa", NULL);
_set_colour(xa_val, &colour_prefs.xa, COLOR_CYAN);
gchar *offline_val = g_key_file_get_string(theme, "colours", "offline", NULL);
_set_colour(offline_val, &colour_prefs.offline, COLOR_RED);
gchar *typing_val = g_key_file_get_string(theme, "colours", "typing", NULL);
_set_colour(typing_val, &colour_prefs.typing, COLOR_YELLOW);
gchar *gone_val = g_key_file_get_string(theme, "colours", "gone", NULL);
_set_colour(gone_val, &colour_prefs.gone, COLOR_RED);
gchar *error_val = g_key_file_get_string(theme, "colours", "error", NULL);
_set_colour(error_val, &colour_prefs.error, COLOR_RED);
gchar *incoming_val = g_key_file_get_string(theme, "colours", "incoming", NULL);
_set_colour(incoming_val, &colour_prefs.incoming, COLOR_YELLOW);
gchar *roominfo_val = g_key_file_get_string(theme, "colours", "roominfo", NULL);
_set_colour(roominfo_val, &colour_prefs.roominfo, COLOR_YELLOW);
gchar *me_val = g_key_file_get_string(theme, "colours", "me", NULL);
_set_colour(me_val, &colour_prefs.me, COLOR_YELLOW);
gchar *them_val = g_key_file_get_string(theme, "colours", "them", NULL);
_set_colour(them_val, &colour_prefs.them, COLOR_GREEN);
}

66
src/theme.h Normal file
View File

@ -0,0 +1,66 @@
/*
* theme.h
*
* Copyright (C) 2012 James Booth <boothj5@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef THEME_H
#define THEME_H
#include "config.h"
#include <glib.h>
#ifdef HAVE_NCURSES_H
#include <ncurses.h>
#endif
#ifdef HAVE_NCURSES_NCURSES_H
#include <ncurses/ncurses.h>
#endif
#define COLOUR_TEXT COLOR_PAIR(1)
#define COLOUR_SPLASH COLOR_PAIR(2)
#define COLOUR_ERROR COLOR_PAIR(3)
#define COLOUR_INCOMING COLOR_PAIR(4)
#define COLOUR_INPUT_TEXT COLOR_PAIR(5)
#define COLOUR_TIME COLOR_PAIR(6)
#define COLOUR_TITLE_TEXT COLOR_PAIR(10)
#define COLOUR_TITLE_BRACKET COLOR_PAIR(11)
#define COLOUR_STATUS_TEXT COLOR_PAIR(20)
#define COLOUR_STATUS_BRACKET COLOR_PAIR(21)
#define COLOUR_STATUS_ACTIVE COLOR_PAIR(22)
#define COLOUR_STATUS_NEW COLOR_PAIR(23)
#define COLOUR_ME COLOR_PAIR(30)
#define COLOUR_THEM COLOR_PAIR(31)
#define COLOUR_ROOMINFO COLOR_PAIR(40)
#define COLOUR_ONLINE COLOR_PAIR(50)
#define COLOUR_OFFLINE COLOR_PAIR(51)
#define COLOUR_AWAY COLOR_PAIR(52)
#define COLOUR_CHAT COLOR_PAIR(53)
#define COLOUR_DND COLOR_PAIR(54)
#define COLOUR_XA COLOR_PAIR(55)
#define COLOUR_TYPING COLOR_PAIR(60)
#define COLOUR_GONE COLOR_PAIR(61)
void theme_load(const char * const theme_name);
void theme_init_colours(void);
gboolean theme_change(const char * const theme_name);
void theme_close(void);
#endif

View File

@ -24,6 +24,7 @@
#include <string.h> #include <string.h>
#include "common.h" #include "common.h"
#include "theme.h"
#include "ui.h" #include "ui.h"
static WINDOW *title_bar; static WINDOW *title_bar;

View File

@ -37,28 +37,7 @@
#include "jabber.h" #include "jabber.h"
#define INP_WIN_MAX 1000 #define INP_WIN_MAX 1000
#define PAD_SIZE 1000
#define COLOUR_TEXT COLOR_PAIR(1)
#define COLOUR_SPLASH COLOR_PAIR(2)
#define COLOUR_ERROR COLOR_PAIR(3)
#define COLOUR_INCOMING COLOR_PAIR(4)
#define COLOUR_TITLE_TEXT COLOR_PAIR(10)
#define COLOUR_TITLE_BRACKET COLOR_PAIR(11)
#define COLOUR_STATUS_TEXT COLOR_PAIR(20)
#define COLOUR_STATUS_BRACKET COLOR_PAIR(21)
#define COLOUR_STATUS_ACTIVE COLOR_PAIR(22)
#define COLOUR_STATUS_NEW COLOR_PAIR(23)
#define COLOUR_ME COLOR_PAIR(30)
#define COLOUR_THEM COLOR_PAIR(31)
#define COLOUR_ROOMINFO COLOR_PAIR(40)
#define COLOUR_ONLINE COLOR_PAIR(50)
#define COLOUR_OFFLINE COLOR_PAIR(51)
#define COLOUR_AWAY COLOR_PAIR(52)
#define COLOUR_CHAT COLOR_PAIR(53)
#define COLOUR_DND COLOR_PAIR(54)
#define COLOUR_XA COLOR_PAIR(55)
#define COLOUR_TYPING COLOR_PAIR(60)
#define COLOUR_GONE COLOR_PAIR(61)
typedef enum { typedef enum {
WIN_UNUSED, WIN_UNUSED,
@ -124,6 +103,7 @@ void win_bad_show(const char * const msg);
void win_remind(void); void win_remind(void);
void win_activity(void); void win_activity(void);
void win_no_activity(void); void win_no_activity(void);
void win_switch_if_active(const int i);
void win_join_chat(const char * const room, const char * const nick); void win_join_chat(const char * const room, const char * const nick);
void win_show_room_roster(const char * const room); void win_show_room_roster(const char * const room);
@ -147,6 +127,7 @@ void win_show_room_member_nick_change(const char * const room,
void win_show_room_nick_change(const char * const room, const char * const nick); void win_show_room_nick_change(const char * const room, const char * const nick);
void win_show_room_member_presence(const char * const room, void win_show_room_member_presence(const char * const room,
const char * const nick, const char * const show, const char * const status); const char * const nick, const char * const show, const char * const status);
void win_load_colours(void);
// console window actions // console window actions
void cons_about(void); void cons_about(void);
@ -186,5 +167,6 @@ void inp_non_block(void);
void inp_block(void); void inp_block(void);
void inp_get_password(char *passwd); void inp_get_password(char *passwd);
void inp_replace_input(char *input, const char * const new_input, int *size); void inp_replace_input(char *input, const char * const new_input, int *size);
int inp_get_next_char(void);
#endif #endif

67
src/window.c Normal file
View File

@ -0,0 +1,67 @@
/*
* window.c
*
* Copyright (C) 2012 James Booth <boothj5@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#ifdef HAVE_NCURSES_H
#include <ncurses.h>
#endif
#ifdef HAVE_NCURSES_NCURSES_H
#include <ncurses/ncurses.h>
#endif
#include "theme.h"
#include "window.h"
#define CONS_WIN_TITLE "_cons"
ProfWin*
window_create(const char * const title, int cols, win_type_t type)
{
ProfWin *new_win = malloc(sizeof(struct prof_win_t));
new_win->from = strdup(title);
new_win->win = newpad(PAD_SIZE, cols);
wbkgd(new_win->win, COLOUR_TEXT);
new_win->y_pos = 0;
new_win->paged = 0;
new_win->unread = 0;
new_win->history_shown = 0;
new_win->type = type;
scrollok(new_win->win, TRUE);
return new_win;
}
void
window_free(ProfWin* window)
{
delwin(window->win);
free(window->from);
window->from = NULL;
window->win = NULL;
free(window);
window = NULL;
}

37
src/window.h Normal file
View File

@ -0,0 +1,37 @@
/*
* window.h
*
* Copyright (C) 2012 James Booth <boothj5@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "ui.h"
typedef struct prof_win_t {
char *from;
WINDOW *win;
win_type_t type;
int y_pos;
int paged;
int unread;
int history_shown;
} ProfWin;
ProfWin* window_create(const char * const title, int cols, win_type_t type);
void window_free(ProfWin *window);

File diff suppressed because it is too large Load Diff

27
themes/aqua Normal file
View File

@ -0,0 +1,27 @@
[colours]
bkgnd=default
titlebar=blue
statusbar=blue
titlebartext=white
titlebarbrackets=white
statusbartext=white
statusbarbrackets=white
statusbaractive=cyan
statusbarnew=white
maintext=blue
inputtext=white
timetext=cyan
splashtext=white
online=white
away=cyan
chat=white
dnd=blue
xa=cyan
offline=blue
typing=white
gone=blue
error=white
incoming=white
roominfo=white
me=white
them=cyan

27
themes/hacker Normal file
View File

@ -0,0 +1,27 @@
[colours]
bkgnd=default
titlebar=green
statusbar=green
titlebartext=black
titlebarbrackets=black
statusbartext=black
statusbarbrackets=black
statusbaractive=black
statusbarnew=black
maintext=green
inputtext=green
timetext=green
splashtext=green
online=green
away=green
chat=green
dnd=green
xa=green
offline=green
typing=green
gone=green
error=red
incoming=green
roominfo=green
me=green
them=green

27
themes/headache Normal file
View File

@ -0,0 +1,27 @@
[colours]
bkgnd=default
titlebar=magenta
statusbar=default
titlebartext=white
titlebarbrackets=white
statusbartext=white
statusbarbrackets=red
statusbaractive=cyan
statusbarnew=white
maintext=blue
inputtext=yellow
timetext=green
splashtext=red
online=red
away=cyan
chat=green
dnd=megenta
xa=cyan
offline=green
typing=magenta
gone=yellow
error=red
incoming=yellow
roominfo=white
me=white
them=white

27
themes/original Normal file
View File

@ -0,0 +1,27 @@
[colours]
bkgnd=default
titlebar=blue
statusbar=blue
titlebartext=white
titlebarbrackets=cyan
statusbartext=white
statusbarbrackets=cyan
statusbaractive=cyan
statusbarnew=white
maintext=white
inputtext=white
timetext=white
splashtext=cyan
online=green
away=cyan
chat=green
dnd=red
xa=cyan
offline=red
typing=yellow
gone=red
error=red
incoming=yellow
roominfo=yellow
me=yellow
them=green

2
themes/redsplash Normal file
View File

@ -0,0 +1,2 @@
[colours]
splashtext=red

27
themes/whiteness Normal file
View File

@ -0,0 +1,27 @@
[colours]
bkgnd=white
titlebar=blue
statusbar=blue
titlebartext=white
titlebarbrackets=white
statusbartext=white
statusbarbrackets=white
statusbaractive=megenta
statusbarnew=red
maintext=black
inputtext=black
timetext=black
splashtext=black
online=green
away=cyan
chat=green
dnd=red
xa=cyan
offline=red
typing=yellow
gone=red
error=red
incoming=yellow
roominfo=yellow
me=yellow
them=green

2
themes/yellowsplash Normal file
View File

@ -0,0 +1,2 @@
[colours]
splashtext=yellow