1
0
Fork 0

Merge branch 'master' into type_out

This commit is contained in:
James Booth 2012-10-22 22:21:55 +01:00
commit a5e4e52567
39 changed files with 722 additions and 623 deletions

40
cygwin
View File

@ -1,40 +0,0 @@
Install cygwin:
http://www.cygwin.com/
http://cygwin.com/setup.exe
Choose git and wget
wget http://apt-cyg.googlecode.com/svn/trunk/apt-cyg
chmod +x apt-cyg
mv apt-cyg /usr/local/bin/
apt-cyg install make gcc automake autoconf pkg-config openssl-devel expat zlib-devel libncurses-devel libncurses-devel libxml2-devel libglib2.0-devel libcurl-devel libidn-devel libssh2-devel libkrb5-devel openldap-devel
ln -s /usr/bin/gcc-3.exe /usr/bin/gcc.exe
ln -s /usr/bin/g++-3.exe /usr/bin/g++.exe
mkdir projects-git
git clone git://github.com/boothj5/profanity.git
cd profanity
git clone git://github.com/boothj5/head-unit.git
cd head-unit
make
make install
cd ..
git clone git://github.com/metajack/libstrophe.git
cd libstrophe
./bootstrap.sh
./bootstrap.sh
./configure
make
make install
cd ..
./bootstrap.sh
./configure
make
make install

View File

@ -155,3 +155,5 @@ with contributions from:
Dolan O'Toole
.br
Colin Bradley
.br
Dmitry Podgorny <pasis.ua@gmail.com>

View File

@ -1,5 +0,0 @@
#!/bin/sh
rm -f tags
rm -f cscope.out
ctags -R .
cscope -R -b

View File

@ -1,4 +0,0 @@
#!/bin/sh
rm -f valgrind.out
#valgrind --log-file=valgrind.out --leak-check=full --track-origins=yes --show-reachable=yes ./profanity
valgrind --log-file=valgrind.out --leak-check=full --track-origins=yes ./profanity -l DEBUG

View File

@ -1,8 +1,8 @@
/*
/*
* chat_log.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
@ -44,25 +44,25 @@ static gboolean _log_roll_needed(struct dated_chat_log *dated_log);
static struct dated_chat_log *_create_log(char *other, const char * const login);
static void _free_chat_log(struct dated_chat_log *dated_log);
static gboolean _key_equals(void *key1, void *key2);
static char * _get_log_filename(const char * const other, const char * const login,
static char * _get_log_filename(const char * const other, const char * const login,
GDateTime *dt, gboolean create);
void
chat_log_init(void)
{
{
session_started = g_date_time_new_now_local();
log_info("Initialising chat logs");
logs = g_hash_table_new_full(g_str_hash, (GEqualFunc) _key_equals, g_free,
logs = g_hash_table_new_full(g_str_hash, (GEqualFunc) _key_equals, g_free,
(GDestroyNotify)_free_chat_log);
}
void
chat_log_chat(const gchar * const login, gchar *other,
chat_log_chat(const gchar * const login, gchar *other,
const gchar * const msg, chat_log_direction_t direction)
{
gchar *other_copy = strdup(other);
struct dated_chat_log *dated_log = g_hash_table_lookup(logs, other_copy);
// no log for user
if (dated_log == NULL) {
dated_log = _create_log(other_copy, login);
@ -94,29 +94,29 @@ chat_log_chat(const gchar * const login, gchar *other,
}
GSList *
chat_log_get_previous(const gchar * const login, const gchar * const recipient,
chat_log_get_previous(const gchar * const login, const gchar * const recipient,
GSList *history)
{
GTimeZone *tz = g_time_zone_new_local();
GDateTime *now = g_date_time_new_now_local();
GDateTime *log_date = g_date_time_new(tz,
GDateTime *log_date = g_date_time_new(tz,
g_date_time_get_year(session_started),
g_date_time_get_month(session_started),
g_date_time_get_month(session_started),
g_date_time_get_day_of_month(session_started),
g_date_time_get_hour(session_started),
g_date_time_get_minute(session_started),
g_date_time_get_second(session_started));
// get data from all logs from the day the session was started to today
while (g_date_time_get_day_of_year(log_date) <= g_date_time_get_day_of_year(now)) {
char *filename = _get_log_filename(recipient, login, log_date, FALSE);
FILE *logp = fopen(filename, "r");
char *line = NULL;
size_t read = 0;
if (logp != NULL) {
GString *gs_header = g_string_new("Log ");
GString *gs_header = g_string_new("");
g_string_append_printf(gs_header, "%d/%d/%d:",
g_date_time_get_day_of_month(log_date),
g_date_time_get_month(log_date),
@ -136,10 +136,10 @@ chat_log_get_previous(const gchar * const login, const gchar * const recipient,
read = 0;
length = getline(&line, &read, logp);
}
fclose(logp);
}
free(filename);
GDateTime *next = g_date_time_add_days(log_date, 1);
g_date_time_unref(log_date);
@ -208,12 +208,12 @@ gboolean _key_equals(void *key1, void *key2)
{
gchar *str1 = (gchar *) key1;
gchar *str2 = (gchar *) key2;
return (g_strcmp0(str1, str2) == 0);
}
static char *
_get_log_filename(const char * const other, const char * const login,
_get_log_filename(const char * const other, const char * const login,
GDateTime *dt, gboolean create)
{
GString *log_file = g_string_new(getenv("HOME"));

View File

@ -1,8 +1,8 @@
/*
/*
* chat_log.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
@ -31,10 +31,10 @@ typedef enum {
} chat_log_direction_t;
void chat_log_init(void);
void chat_log_chat(const gchar * const login, gchar *other,
void chat_log_chat(const gchar * const login, gchar *other,
const gchar * const msg, chat_log_direction_t direction);
void chat_log_close(void);
GSList * chat_log_get_previous(const gchar * const login,
GSList * chat_log_get_previous(const gchar * const login,
const gchar * const recipient, GSList *history);
#endif

View File

@ -1,8 +1,8 @@
/*
/*
* command.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
@ -38,7 +38,7 @@
#include "tinyurl.h"
#include "ui.h"
/*
/*
* Command structure
*
* cmd - The command string including leading '/'
@ -52,11 +52,10 @@ struct cmd_t {
};
static struct cmd_t * _cmd_get_command(const char * const command);
static void _update_presence(const jabber_presence_t presence,
static void _update_presence(const jabber_presence_t presence,
const char * const show, const char * const inp);
static gboolean
_cmd_set_boolean_preference(const char * const inp, struct cmd_help_t help,
const char * const cmd_str, const char * const display,
static gboolean _cmd_set_boolean_preference(const char * const inp,
struct cmd_help_t help, const char * const cmd_str, const char * const display,
void (*set_func)(gboolean));
// command prototypes
@ -88,10 +87,10 @@ static gboolean _cmd_xa(const char * const inp, struct cmd_help_t help);
* Commands to change preferences
* Commands to change users status
*/
static struct cmd_t main_commands[] =
static struct cmd_t main_commands[] =
{
{ "/help",
_cmd_help,
{ "/help",
_cmd_help,
{ "/help [command]", "Show help summary, or help on a specific command",
{ "/help [command]",
"---------------",
@ -101,8 +100,8 @@ static struct cmd_t main_commands[] =
"Example : /help connect",
NULL } } },
{ "/connect",
_cmd_connect,
{ "/connect",
_cmd_connect,
{ "/connect user@host", "Login to jabber.",
{ "/connect user@host",
"------------------",
@ -110,11 +109,11 @@ static struct cmd_t main_commands[] =
"Profanity should work with any XMPP (Jabber) compliant chat host.",
"You can use tab completion to autocomplete any logins you have used before.",
"",
"Example: /connect myuser@gmail.com",
"Example: /connect myuser@gmail.com",
NULL } } },
{ "/prefs",
_cmd_prefs,
{ "/prefs",
_cmd_prefs,
{ "/prefs", "Show current preferences.",
{ "/prefs",
"------",
@ -127,8 +126,8 @@ static struct cmd_t main_commands[] =
"you will need to restart Profanity for config file edits to take effect.",
NULL } } },
{ "/msg",
_cmd_msg,
{ "/msg",
_cmd_msg,
{ "/msg user@host mesg", "Send mesg to user.",
{ "/msg user@host mesg",
"-------------------",
@ -142,8 +141,8 @@ static struct cmd_t main_commands[] =
"Example : /msg boothj5@gmail.com Hey, here's a message!",
NULL } } },
{ "/tiny",
_cmd_tiny,
{ "/tiny",
_cmd_tiny,
{ "/tiny url", "Send url as tinyurl in current chat.",
{ "/tiny url",
"---------",
@ -154,7 +153,7 @@ static struct cmd_t main_commands[] =
"Example : /tiny http://www.google.com",
NULL } } },
{ "/who",
{ "/who",
_cmd_who,
{ "/who [status]", "Show contacts with chosen status.",
{ "/who [status]",
@ -164,8 +163,8 @@ static struct cmd_t main_commands[] =
"online includes: chat, dnd, away, xa.",
NULL } } },
{ "/close",
_cmd_close,
{ "/close",
_cmd_close,
{ "/close", "Close current chat window.",
{ "/close",
"------",
@ -173,8 +172,8 @@ static struct cmd_t main_commands[] =
"The chat window will become available for new chats.",
NULL } } },
{ "/quit",
_cmd_quit,
{ "/quit",
_cmd_quit,
{ "/quit", "Quit Profanity.",
{ "/quit",
"-----",
@ -182,7 +181,7 @@ static struct cmd_t main_commands[] =
NULL } } }
};
static struct cmd_t setting_commands[] =
static struct cmd_t setting_commands[] =
{
{ "/beep",
_cmd_set_beep,
@ -237,7 +236,7 @@ static struct cmd_t setting_commands[] =
"Config file value : remind=seconds",
NULL } } },
{ "/flash",
{ "/flash",
_cmd_set_flash,
{ "/flash on|off", "Enable/disable screen flash notifications.",
{ "/flash on|off",
@ -251,8 +250,8 @@ static struct cmd_t setting_commands[] =
"Config file value : flash=true|false",
NULL } } },
{ "/showsplash",
_cmd_set_showsplash,
{ "/showsplash",
_cmd_set_showsplash,
{ "/showsplash on|off", "Enable/disable splash logo on startup.",
{ "/showsplash on|off",
"------------------",
@ -262,7 +261,7 @@ static struct cmd_t setting_commands[] =
"Config file value : showsplash=true|false",
NULL } } },
{ "/chlog",
{ "/chlog",
_cmd_set_chlog,
{ "/chlog on|off", "Enable/disable chat logging.",
{ "/chlog on|off",
@ -278,7 +277,7 @@ static struct cmd_t setting_commands[] =
" ~/.profanity/log/someuser_at_chatserv.com/myfriend_at_chatserv.com",
NULL } } },
{ "/history",
{ "/history",
_cmd_set_history,
{ "/history on|off", "Enable/disable chat history.",
{ "/history on|off",
@ -291,7 +290,7 @@ static struct cmd_t setting_commands[] =
NULL } } }
};
static struct cmd_t status_commands[] =
static struct cmd_t status_commands[] =
{
{ "/away",
_cmd_away,
@ -328,7 +327,7 @@ static struct cmd_t status_commands[] =
"Example : /dnd I'm in the zone",
NULL } } },
{ "/online",
{ "/online",
_cmd_online,
{ "/online [msg]", "Set status to online.",
{ "/online [msg]",
@ -351,8 +350,9 @@ static struct cmd_t status_commands[] =
"Example : /xa This meeting is going to be a long one",
NULL } } },
};
static PAutocomplete commands_ac;
static PAutocomplete help_ac;
/*
* Initialise command autocompleter and history
@ -362,26 +362,37 @@ cmd_init(void)
{
log_info("Initialising commands");
commands_ac = p_autocomplete_new();
help_ac = p_autocomplete_new();
unsigned int i;
for (i = 0; i < ARRAY_SIZE(main_commands); i++) {
struct cmd_t *pcmd = main_commands+i;
p_autocomplete_add(commands_ac, (gchar *)pcmd->cmd);
p_autocomplete_add(commands_ac, (gchar *)strdup(pcmd->cmd));
p_autocomplete_add(help_ac, (gchar *)strdup(pcmd->cmd+1));
}
for (i = 0; i < ARRAY_SIZE(setting_commands); i++) {
struct cmd_t *pcmd = setting_commands+i;
p_autocomplete_add(commands_ac, (gchar *)pcmd->cmd);
p_autocomplete_add(commands_ac, (gchar *)strdup(pcmd->cmd));
p_autocomplete_add(help_ac, (gchar *)strdup(pcmd->cmd+1));
}
for (i = 0; i < ARRAY_SIZE(status_commands); i++) {
struct cmd_t *pcmd = status_commands+i;
p_autocomplete_add(commands_ac, (gchar *)pcmd->cmd);
p_autocomplete_add(commands_ac, (gchar *)strdup(pcmd->cmd));
p_autocomplete_add(help_ac, (gchar *)strdup(pcmd->cmd+1));
}
history_init();
}
void
cmd_close(void)
{
p_autocomplete_clear(commands_ac);
p_autocomplete_clear(help_ac);
}
// Command autocompletion functions
char *
@ -397,6 +408,17 @@ cmd_reset_completer(void)
}
// Command help
char *
cmd_help_complete(char *inp)
{
return p_autocomplete_complete(help_ac, inp);
}
void
cmd_help_reset_completer(void)
{
p_autocomplete_reset(help_ac);
}
GSList *
cmd_get_basic_help(void)
@ -443,7 +465,7 @@ gboolean
cmd_execute(const char * const command, const char * const inp)
{
struct cmd_t *cmd = _cmd_get_command(command);
if (cmd != NULL) {
return (cmd->func(inp, cmd->help));
} else {
@ -457,7 +479,7 @@ cmd_execute_default(const char * const inp)
if (win_in_chat()) {
char *recipient = win_get_recipient();
jabber_send(inp, recipient);
if (prefs_get_chlog()) {
const char *jid = jabber_get_jid();
chat_log_chat(jid, recipient, inp, OUT);
@ -499,7 +521,7 @@ _cmd_connect(const char * const inp, struct cmd_help_t help)
inp_non_block();
log_debug("Connecting as %s", lower);
conn_status = jabber_connect(lower, passwd);
if (conn_status == JABBER_CONNECTING) {
cons_show("Connecting...");
@ -512,7 +534,7 @@ _cmd_connect(const char * const inp, struct cmd_help_t help)
result = TRUE;
}
return result;
}
@ -540,7 +562,7 @@ _cmd_help(const char * const inp, struct cmd_help_t help)
if (command != NULL) {
help_text = command->help.long_help;
}
cons_show("");
if (help_text != NULL) {
@ -574,7 +596,7 @@ _cmd_who(const char * const inp, struct cmd_help_t help)
if (conn_status != JABBER_CONNECTED) {
cons_show("You are not currently connected.");
} else {
// copy input
// copy input
char inp_cpy[strlen(inp) + 1];
strcpy(inp_cpy, inp);
@ -595,7 +617,7 @@ _cmd_who(const char * const inp, struct cmd_help_t help)
// valid arg
} else {
GSList *list = get_contact_list();
// no arg, show all contacts
if (show == NULL) {
cons_show("All contacts:");
@ -653,7 +675,7 @@ _cmd_msg(const char * const inp, struct cmd_help_t help)
if (conn_status != JABBER_CONNECTED) {
cons_show("You are not currently connected.");
} else {
// copy input
// copy input
char inp_cpy[strlen(inp) + 1];
strcpy(inp_cpy, inp);
@ -719,7 +741,7 @@ _cmd_tiny(const char * const inp, struct cmd_help_t help)
}
} else {
cons_show("Usage: %s", help.usage);
if (win_in_chat()) {
char usage[strlen(help.usage + 8)];
sprintf(usage, "Usage: %s", help.usage);
@ -735,7 +757,7 @@ _cmd_close(const char * const inp, struct cmd_help_t help)
{
if (!win_close_win())
cons_bad_command(inp);
return TRUE;
}
@ -749,42 +771,42 @@ _cmd_set_beep(const char * const inp, struct cmd_help_t help)
static gboolean
_cmd_set_notify(const char * const inp, struct cmd_help_t help)
{
return _cmd_set_boolean_preference(inp, help, "/notify",
return _cmd_set_boolean_preference(inp, help, "/notify",
"Desktop notifications", prefs_set_notify);
}
static gboolean
_cmd_set_typing(const char * const inp, struct cmd_help_t help)
{
return _cmd_set_boolean_preference(inp, help, "/typing",
return _cmd_set_boolean_preference(inp, help, "/typing",
"Incoming typing notifications", prefs_set_typing);
}
static gboolean
_cmd_set_flash(const char * const inp, struct cmd_help_t help)
{
return _cmd_set_boolean_preference(inp, help, "/flash",
return _cmd_set_boolean_preference(inp, help, "/flash",
"Screen flash", prefs_set_flash);
}
static gboolean
_cmd_set_showsplash(const char * const inp, struct cmd_help_t help)
{
return _cmd_set_boolean_preference(inp, help, "/showsplash",
return _cmd_set_boolean_preference(inp, help, "/showsplash",
"Splash screen", prefs_set_showsplash);
}
static gboolean
_cmd_set_chlog(const char * const inp, struct cmd_help_t help)
{
return _cmd_set_boolean_preference(inp, help, "/chlog",
return _cmd_set_boolean_preference(inp, help, "/chlog",
"Chat logging", prefs_set_chlog);
}
static gboolean
_cmd_set_history(const char * const inp, struct cmd_help_t help)
{
return _cmd_set_boolean_preference(inp, help, "/history",
return _cmd_set_boolean_preference(inp, help, "/history",
"Chat history", prefs_set_history);
}
@ -794,7 +816,7 @@ _cmd_set_remind(const char * const inp, struct cmd_help_t help)
if ((strncmp(inp, "/remind ", 8) != 0) || (strlen(inp) < 9)) {
cons_show("Usage: %s", help.usage);
} else {
// copy input
// copy input
char inp_cpy[strlen(inp) + 1];
strcpy(inp_cpy, inp);
@ -813,7 +835,7 @@ _cmd_set_remind(const char * const inp, struct cmd_help_t help)
}
}
return TRUE;
return TRUE;
}
static gboolean
@ -854,7 +876,7 @@ _cmd_xa(const char * const inp, struct cmd_help_t help)
// helper function for status change commands
static void
_update_presence(const jabber_presence_t presence,
_update_presence(const jabber_presence_t presence,
const char * const show, const char * const inp)
{
char *msg;
@ -865,7 +887,7 @@ _update_presence(const jabber_presence_t presence,
}
jabber_conn_status_t conn_status = jabber_get_connection_status();
if (conn_status != JABBER_CONNECTED) {
cons_show("You are not currently connected.");
} else {
@ -879,18 +901,18 @@ _update_presence(const jabber_presence_t presence,
}
}
}
}
// helper function for boolean preference commands
static gboolean
_cmd_set_boolean_preference(const char * const inp, struct cmd_help_t help,
const char * const cmd_str, const char * const display,
const char * const cmd_str, const char * const display,
void (*set_func)(gboolean))
{
GString *on = g_string_new(cmd_str);
g_string_append(on, " on");
GString *off = g_string_new(cmd_str);
g_string_append(off, " off");
@ -910,7 +932,7 @@ _cmd_set_boolean_preference(const char * const inp, struct cmd_help_t help,
char usage[strlen(help.usage + 8)];
sprintf(usage, "Usage: %s", help.usage);
cons_show(usage);
}
}
g_string_free(on, TRUE);
g_string_free(off, TRUE);

View File

@ -1,8 +1,8 @@
/*
/*
* command.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
@ -33,12 +33,15 @@ struct cmd_help_t {
};
void cmd_init(void);
void cmd_close(void);
char * cmd_complete(char *inp);
void cmd_reset_completer(void);
gboolean cmd_execute(const char * const command, const char * const inp);
gboolean cmd_execute_default(const char * const inp);
// command help
char * cmd_help_complete(char *inp);
void cmd_help_reset_completer(void);
GSList * cmd_get_basic_help(void);
GSList * cmd_get_settings_help(void);
GSList * cmd_get_status_help(void);

View File

@ -1,8 +1,8 @@
/*
/*
* common.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
@ -50,20 +50,20 @@ create_dir(char *name)
}
char *
str_replace(const char *string, const char *substr,
const char *replacement)
str_replace(const char *string, const char *substr,
const char *replacement)
{
char *tok = NULL;
char *newstr = NULL;
char *oldstr = NULL;
char *head = NULL;
if (string == NULL)
return NULL;
if ( substr == NULL ||
replacement == NULL ||
(strcmp(substr, "") == 0))
if ( substr == NULL ||
replacement == NULL ||
(strcmp(substr, "") == 0))
return strdup (string);
newstr = strdup (string);
@ -71,26 +71,26 @@ str_replace(const char *string, const char *substr,
while ( (tok = strstr ( head, substr ))) {
oldstr = newstr;
newstr = malloc ( strlen ( oldstr ) - strlen ( substr ) +
newstr = malloc ( strlen ( oldstr ) - strlen ( substr ) +
strlen ( replacement ) + 1 );
if ( newstr == NULL ) {
if ( newstr == NULL ) {
free (oldstr);
return NULL;
}
memcpy ( newstr, oldstr, tok - oldstr );
memcpy ( newstr + (tok - oldstr), replacement, strlen ( replacement ) );
memcpy ( newstr + (tok - oldstr) + strlen( replacement ),
tok + strlen ( substr ),
memcpy ( newstr + (tok - oldstr) + strlen( replacement ),
tok + strlen ( substr ),
strlen ( oldstr ) - strlen ( substr ) - ( tok - oldstr ) );
memset ( newstr + strlen ( oldstr ) - strlen ( substr ) +
memset ( newstr + strlen ( oldstr ) - strlen ( substr ) +
strlen ( replacement ) , 0, 1 );
head = newstr + (tok - oldstr) + strlen( replacement );
free (oldstr);
}
return newstr;
}

View File

@ -1,8 +1,8 @@
/*
/*
* common.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
@ -37,7 +37,7 @@
void p_slist_free_full(GSList *items, GDestroyNotify free_func);
void create_dir(char *name);
char * str_replace(const char *string, const char *substr,
char * str_replace(const char *string, const char *substr,
const char *replacement);
int str_contains(char str[], int size, char ch);

View File

@ -1,8 +1,8 @@
/*
/*
* contact.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
@ -34,7 +34,7 @@ struct p_contact_t {
};
PContact
p_contact_new(const char * const name, const char * const show,
p_contact_new(const char * const name, const char * const show,
const char * const status)
{
PContact contact = malloc(sizeof(struct p_contact_t));
@ -59,12 +59,12 @@ p_contact_copy(PContact contact)
PContact copy = malloc(sizeof(struct p_contact_t));
copy->name = strdup(contact->name);
copy->show = strdup(contact->show);
if (contact->status != NULL)
copy->status = strdup(contact->status);
else
copy->status = NULL;
return copy;
}

View File

@ -1,8 +1,8 @@
/*
/*
* contact.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
@ -25,7 +25,7 @@
typedef struct p_contact_t *PContact;
PContact p_contact_new(const char * const name, const char * const show,
PContact p_contact_new(const char * const name, const char * const show,
const char * const status);
PContact p_contact_copy(PContact contact);
void p_contact_free(PContact contact);

View File

@ -1,8 +1,8 @@
/*
/*
* contact_list.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
@ -30,7 +30,7 @@ static PAutocomplete ac;
void
contact_list_init(void)
{
ac = p_obj_autocomplete_new((PStrFunc)p_contact_name,
ac = p_obj_autocomplete_new((PStrFunc)p_contact_name,
(PCopyFunc)p_contact_copy,
(PEqualDeepFunc)p_contacts_equal_deep,
(GDestroyNotify)p_contact_free);
@ -43,7 +43,7 @@ contact_list_clear(void)
}
void
reset_search_attempts(void)
contact_list_reset_search_attempts(void)
{
p_autocomplete_reset(ac);
}
@ -55,7 +55,7 @@ contact_list_remove(const char * const name)
}
gboolean
contact_list_add(const char * const name, const char * const show,
contact_list_add(const char * const name, const char * const show,
const char * const status)
{
return p_autocomplete_add(ac, p_contact_new(name, show, status));
@ -68,7 +68,7 @@ get_contact_list(void)
}
char *
find_contact(char *search_str)
contact_list_find_contact(char *search_str)
{
return p_autocomplete_complete(ac, search_str);
}
@ -77,7 +77,7 @@ PContact
contact_list_get_contact(const char const *jid)
{
GSList *contacts = get_contact_list();
while (contacts != NULL) {
PContact contact = contacts->data;
if (strcmp(p_contact_name(contact), jid) == 0) {

View File

@ -1,8 +1,8 @@
/*
/*
* contact_list.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
@ -29,12 +29,12 @@
void contact_list_init(void);
void contact_list_clear(void);
void reset_search_attempts(void);
void contact_list_reset_search_attempts(void);
gboolean contact_list_add(const char * const name, const char * const show,
const char * const status);
gboolean contact_list_remove(const char * const name);
GSList * get_contact_list(void);
char * find_contact(char *search_str);
char * contact_list_find_contact(char *search_str);
PContact contact_list_get_contact(const char const *jid);
#endif

View File

@ -1,8 +1,8 @@
/*
/*
* history.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
@ -45,7 +45,7 @@ history_previous(char *inp, int *size)
{
char inp_str[*size + 1];
_stringify_input(inp, *size, inp_str);
return p_history_previous(history, inp_str);
}

View File

@ -1,8 +1,8 @@
/*
/*
* history.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

View File

@ -1,8 +1,8 @@
/*
* input_win.c
/*
* input_win.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
@ -26,11 +26,11 @@
* *size - holds the current size of input
* *input - holds the current input string, NOT null terminated at this point
* *ch - getch will put a charater here if there was any input
*
*
* The example below shows the values of size, input, a call to wgetyx to
* find the current cursor location, and the index of the input string.
*
* view : |mple|
* view : |mple|
* input : "example te"
* index : "0123456789"
* inp_x : "0123456789"
@ -58,12 +58,16 @@
#include "preferences.h"
#include "ui.h"
typedef char*(*autocomplete_func)(char *);
static WINDOW *inp_win;
static int pad_start = 0;
static int _handle_edit(const int ch, char *input, int *size);
static int _printable(const int ch);
static void _replace_input(char *input, const char * const new_input, int *size);
static void _parameter_autocomplete(char *input, int *size, char *command,
autocomplete_func func);
void
create_input_window(void)
@ -84,7 +88,7 @@ inp_win_resize(const char * const input, const int size)
int rows, cols, inp_x;
getmaxyx(stdscr, rows, cols);
inp_x = getcurx(inp_win);
// if lost cursor off screen, move contents to show it
if (inp_x >= pad_start + cols) {
pad_start = inp_x - (cols / 2);
@ -125,7 +129,7 @@ inp_get_char(int *ch, char *input, int *size)
int inp_y = 0;
int inp_x = 0;
int i;
// echo off, and get some more input
noecho();
*ch = wgetch(inp_win);
@ -134,7 +138,7 @@ inp_get_char(int *ch, char *input, int *size)
if (!_handle_edit(*ch, input, size)) {
if (_printable(*ch)) {
getyx(inp_win, inp_y, inp_x);
// handle insert if not at end of input
if (inp_x < *size) {
winsch(inp_win, *ch);
@ -150,7 +154,7 @@ inp_get_char(int *ch, char *input, int *size)
} else {
waddch(inp_win, *ch);
input[(*size)++] = *ch;
// if gone over screen size follow input
int rows, cols;
getmaxyx(stdscr, rows, cols);
@ -160,8 +164,10 @@ inp_get_char(int *ch, char *input, int *size)
}
}
reset_search_attempts();
reset_login_search();
contact_list_reset_search_attempts();
prefs_reset_login_search();
prefs_reset_boolean_choice();
cmd_help_reset_completer();
cmd_reset_completer();
}
}
@ -174,7 +180,7 @@ inp_get_password(char *passwd)
{
int rows, cols;
getmaxyx(stdscr, rows, cols);
wclear(inp_win);
prefresh(inp_win, 0, pad_start, rows-1, 0, rows-1, cols-1);
noecho();
@ -208,15 +214,15 @@ _handle_edit(const int ch, char *input, int *size)
int inp_y = 0;
int inp_x = 0;
char inp_cpy[*size];
getmaxyx(stdscr, rows, cols);
getyx(inp_win, inp_y, inp_x);
switch(ch) {
case 127:
case KEY_BACKSPACE:
reset_search_attempts();
contact_list_reset_search_attempts();
if (*size > 0) {
// if at end, delete last char
@ -252,12 +258,12 @@ _handle_edit(const int ch, char *input, int *size)
case KEY_DC: // DEL
if (inp_x < *size) {
wdelch(inp_win);
// if not last char, shift chars left
if (inp_x < *size - 1)
for (i = inp_x; i < *size; i++)
input[i] = input[i+1];
(*size)--;
}
return 1;
@ -265,7 +271,7 @@ _handle_edit(const int ch, char *input, int *size)
case KEY_LEFT:
if (inp_x > 0)
wmove(inp_win, inp_y, inp_x-1);
// current position off screen to left
if (inp_x - 1 < pad_start) {
pad_start--;
@ -276,7 +282,7 @@ _handle_edit(const int ch, char *input, int *size)
case KEY_RIGHT:
if (inp_x < *size) {
wmove(inp_win, inp_y, inp_x+1);
// current position off screen to right
if ((inp_x + 1 - pad_start) >= cols) {
pad_start++;
@ -319,7 +325,7 @@ _handle_edit(const int ch, char *input, int *size)
case 9: // tab
// autocomplete commands
// autocomplete command
if ((strncmp(input, "/", 1) == 0) && (!str_contains(input, *size, ' '))) {
for(i = 0; i < *size; i++) {
inp_cpy[i] = input[i];
@ -333,41 +339,31 @@ _handle_edit(const int ch, char *input, int *size)
free(auto_msg);
free(found);
}
// autcomplete /msg recipient
} else if ((strncmp(input, "/msg ", 5) == 0) && (*size > 5)) {
for(i = 5; i < *size; i++) {
inp_cpy[i-5] = input[i];
}
inp_cpy[(*size) - 5] = '\0';
found = find_contact(inp_cpy);
if (found != NULL) {
auto_msg = (char *) malloc((5 + (strlen(found) + 1)) * sizeof(char));
strcpy(auto_msg, "/msg ");
strcat(auto_msg, found);
_replace_input(input, auto_msg, size);
free(auto_msg);
free(found);
}
// autocomplete /connect username
} else if ((strncmp(input, "/connect ", 9) == 0) && (*size > 9)) {
for(i = 9; i < *size; i++) {
inp_cpy[i-9] = input[i];
}
inp_cpy[(*size) - 9] = '\0';
found = find_login(inp_cpy);
if (found != NULL) {
auto_msg = (char *) malloc((9 + (strlen(found) + 1)) * sizeof(char));
strcpy(auto_msg, "/connect ");
strcat(auto_msg, found);
_replace_input(input, auto_msg, size);
free(auto_msg);
free(found);
}
}
_parameter_autocomplete(input, size, "/msg",
contact_list_find_contact);
_parameter_autocomplete(input, size, "/connect",
prefs_find_login);
_parameter_autocomplete(input, size, "/help",
cmd_help_complete);
_parameter_autocomplete(input, size, "/beep",
prefs_autocomplete_boolean_choice);
_parameter_autocomplete(input, size, "/notify",
prefs_autocomplete_boolean_choice);
_parameter_autocomplete(input, size, "/typing",
prefs_autocomplete_boolean_choice);
_parameter_autocomplete(input, size, "/flash",
prefs_autocomplete_boolean_choice);
_parameter_autocomplete(input, size, "/showsplash",
prefs_autocomplete_boolean_choice);
_parameter_autocomplete(input, size, "/chlog",
prefs_autocomplete_boolean_choice);
_parameter_autocomplete(input, size, "/history",
prefs_autocomplete_boolean_choice);
return 1;
default:
return 0;
}
@ -376,9 +372,9 @@ _handle_edit(const int ch, char *input, int *size)
static int
_printable(const int ch)
{
return (ch != ERR && ch != '\n' &&
return (ch != ERR && ch != '\n' &&
ch != KEY_PPAGE && ch != KEY_NPAGE &&
ch != KEY_F(1) && ch != KEY_F(2) && ch != KEY_F(3) &&
ch != KEY_F(1) && ch != KEY_F(2) && ch != KEY_F(3) &&
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(10) && ch!= KEY_F(11) && ch != KEY_F(12) &&
@ -396,3 +392,32 @@ _replace_input(char *input, const char * const new_input, int *size)
for (i = 0; i < *size; i++)
waddch(inp_win, input[i]);
}
static void
_parameter_autocomplete(char *input, int *size, char *command,
autocomplete_func func)
{
char *found = NULL;
char *auto_msg = NULL;
char inp_cpy[*size];
int i;
char *command_cpy = malloc(strlen(command) + 2);
sprintf(command_cpy, "%s ", command);
int len = strlen(command_cpy);
if ((strncmp(input, command_cpy, len) == 0) && (*size > len)) {
for(i = len; i < *size; i++) {
inp_cpy[i-len] = input[i];
}
inp_cpy[(*size) - len] = '\0';
found = func(inp_cpy);
if (found != NULL) {
auto_msg = (char *) malloc((len + (strlen(found) + 1)) * sizeof(char));
strcpy(auto_msg, command_cpy);
strcat(auto_msg, found);
_replace_input(input, auto_msg, size);
free(auto_msg);
free(found);
}
}
free(command_cpy);
}

View File

@ -1,8 +1,8 @@
/*
/*
* jabber.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
@ -44,20 +44,20 @@ static struct _jabber_conn_t {
static log_level_t _get_log_level(xmpp_log_level_t xmpp_level);
static xmpp_log_level_t _get_xmpp_log_level();
static void _xmpp_file_logger(void * const userdata,
const xmpp_log_level_t level, const char * const area,
static void _xmpp_file_logger(void * const userdata,
const xmpp_log_level_t level, const char * const area,
const char * const msg);
static xmpp_log_t * _xmpp_get_file_logger();
// XMPP event handlers
static void _connection_handler(xmpp_conn_t * const conn,
const xmpp_conn_event_t status, const int error,
static void _connection_handler(xmpp_conn_t * const conn,
const xmpp_conn_event_t status, const int error,
xmpp_stream_error_t * const stream_error, void * const userdata);
static int _message_handler(xmpp_conn_t * const conn,
static int _message_handler(xmpp_conn_t * const conn,
xmpp_stanza_t * const stanza, void * const userdata);
static int _roster_handler(xmpp_conn_t * const conn,
static int _roster_handler(xmpp_conn_t * const conn,
xmpp_stanza_t * const stanza, void * const userdata);
static int _presence_handler(xmpp_conn_t * const conn,
static int _presence_handler(xmpp_conn_t * const conn,
xmpp_stanza_t * const stanza, void * const userdata);
static int _ping_timed_handler(xmpp_conn_t * const conn, void