Added C plugin code from plugins branch

This commit is contained in:
James Booth
2016-02-14 22:28:55 +00:00
parent f887a35c0c
commit 41fe8c22b1
70 changed files with 2668 additions and 287 deletions

233
src/plugins/api.c Normal file
View File

@@ -0,0 +1,233 @@
/*
* api.c
*
* Copyright (C) 2012 - 2015 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/>.
*
* 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 <stdlib.h>
#include <assert.h>
#include <glib.h>
#include "log.h"
#include "plugins/callbacks.h"
#include "plugins/autocompleters.h"
#include "profanity.h"
#include "ui/ui.h"
#include "config/theme.h"
#include "command/command.h"
#include "window_list.h"
#include "common.h"
void
api_cons_alert(void)
{
cons_alert();
}
void
api_cons_show(const char * const message)
{
if (message) {
char *parsed = str_replace(message, "\r\n", "\n");
cons_show("%s", parsed);
free(parsed);
}
}
void
api_register_command(const char *command_name, int min_args, int max_args,
const char *usage, const char *short_help, const char *long_help, void *callback,
void(*callback_func)(PluginCommand *command, gchar **args))
{
PluginCommand *command = malloc(sizeof(PluginCommand));
command->command_name = command_name;
command->min_args = min_args;
command->max_args = max_args;
command->usage = usage;
command->short_help = short_help;
command->long_help = long_help;
command->callback = callback;
command->callback_func = callback_func;
callbacks_add_command(command);
}
void
api_register_timed(void *callback, int interval_seconds,
void (*callback_func)(PluginTimedFunction *timed_function))
{
PluginTimedFunction *timed_function = malloc(sizeof(PluginTimedFunction));
timed_function->callback = callback;
timed_function->callback_func = callback_func;
timed_function->interval_seconds = interval_seconds;
timed_function->timer = g_timer_new();
callbacks_add_timed(timed_function);
}
void
api_register_ac(const char *key, char **items)
{
autocompleters_add(key, items);
}
void
api_notify(const char *message, const char *category, int timeout_ms)
{
notify(message, timeout_ms, category);
}
void
api_send_line(char *line)
{
ProfWin *current = wins_get_current();
cmd_process_input(current, line);
}
char *
api_get_current_recipient(void)
{
ProfWin *current = wins_get_current();
if (current->type == WIN_CHAT) {
ProfChatWin *chatwin = (ProfChatWin*)current;
assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK);
return chatwin->barejid;
} else {
return NULL;
}
}
char *
api_get_current_muc(void)
{
ProfWin *current = wins_get_current();
if (current->type == WIN_MUC) {
ProfMucWin *mucwin = (ProfMucWin*)current;
assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK);
return mucwin->roomjid;
} else {
return NULL;
}
}
void
api_log_debug(const char *message)
{
log_debug("%s", message);
}
void
api_log_info(const char *message)
{
log_info("%s", message);
}
void
api_log_warning(const char *message)
{
log_warning("%s", message);
}
void
api_log_error(const char *message)
{
log_error("%s", message);
}
int
api_win_exists(const char *tag)
{
return (wins_get_plugin(tag) != NULL);
}
void
api_win_create(const char *tag, void *callback,
void(*callback_func)(PluginWindowCallback *window_callback, const char *tag, const char * const line))
{
PluginWindowCallback *window = malloc(sizeof(PluginWindowCallback));
window->callback = callback;
window->callback_func = callback_func;
callbacks_add_window_handler(tag, window);
wins_new_plugin(tag);
// set status bar active
ProfPluginWin *pluginwin = wins_get_plugin(tag);
int num = wins_get_num((ProfWin*)pluginwin);
status_bar_active(num);
}
void
api_win_focus(const char *tag)
{
ProfPluginWin *pluginwin = wins_get_plugin(tag);
ui_focus_win((ProfWin*)pluginwin);
}
void
api_win_show(const char *tag, const char *line)
{
ProfPluginWin *pluginwin = wins_get_plugin(tag);
ProfWin *window = (ProfWin*)pluginwin;
win_print(window, '!', 0, NULL, 0, 0, "", line);
}
void
api_win_show_green(const char *tag, const char *line)
{
ProfPluginWin *pluginwin = wins_get_plugin(tag);
ProfWin *window = (ProfWin*)pluginwin;
win_print(window, '!', 0, NULL, 0, THEME_GREEN, "", line);
}
void
api_win_show_red(const char *tag, const char *line)
{
ProfPluginWin *pluginwin = wins_get_plugin(tag);
ProfWin *window = (ProfWin*)pluginwin;
win_print(window, '!', 0, NULL, 0, THEME_RED, "", line);
}
void
api_win_show_cyan(const char *tag, const char *line)
{
ProfPluginWin *pluginwin = wins_get_plugin(tag);
ProfWin *window = (ProfWin*)pluginwin;
win_print(window, '!', 0, NULL, 0, THEME_CYAN, "", line);
}
void
api_win_show_yellow(const char *tag, const char *line)
{
ProfPluginWin *pluginwin = wins_get_plugin(tag);
ProfWin *window = (ProfWin*)pluginwin;
win_print(window, '!', 0, NULL, 0, THEME_YELLOW, "", line);
}

69
src/plugins/api.h Normal file
View File

@@ -0,0 +1,69 @@
/*
* api.h
*
* Copyright (C) 2012 - 2015 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/>.
*
* 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.
*
*/
#ifndef API_H
#define API_H
#include "plugins/callbacks.h"
void api_cons_alert(void);
void api_cons_show(const char * const message);
void api_notify(const char *message, const char *category, int timeout_ms);
void api_send_line(char *line);
char * api_get_current_recipient(void);
char * api_get_current_muc(void);
void api_register_command(const char *command_name, int min_args, int max_args,
const char *usage, const char *short_help, const char *long_help,
void *callback, void(*callback_func)(PluginCommand *command, gchar **args));
void api_register_timed(void *callback, int interval_seconds,
void (*callback_func)(PluginTimedFunction *timed_function));
void api_register_ac(const char *key, char **items);
void api_log_debug(const char *message);
void api_log_info(const char *message);
void api_log_warning(const char *message);
void api_log_error(const char *message);
int api_win_exists(const char *tag);
void api_win_create(const char *tag, void *callback,
void(*callback_func)(PluginWindowCallback *window_callback, char *tag, char *line));
void api_win_focus(const char *tag);
void api_win_show(const char *tag, const char *line);
void api_win_show_green(const char *tag, const char *line);
void api_win_show_red(const char *tag, const char *line);
void api_win_show_cyan(const char *tag, const char *line);
void api_win_show_yellow(const char *tag, const char *line);
#endif

View File

@@ -0,0 +1,92 @@
/*
* autocompleters.c
*
* Copyright (C) 2012 - 2015 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/>.
*
* 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 <string.h>
#include <glib.h>
#include "tools/autocomplete.h"
static GHashTable *autocompleters;
void
autocompleters_init(void)
{
autocompleters = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)autocomplete_free);
}
void
autocompleters_add(const char *key, char **items)
{
Autocomplete new_ac = autocomplete_new();
int i = 0;
for (i = 0; i < g_strv_length(items); i++) {
autocomplete_add(new_ac, items[i]);
}
g_hash_table_insert(autocompleters, strdup(key), new_ac);
}
char *
autocompleters_complete(const char * const input)
{
char *result = NULL;
GList *keys = g_hash_table_get_keys(autocompleters);
GList *curr = keys;
while (curr) {
result = autocomplete_param_with_ac(input, curr->data, g_hash_table_lookup(autocompleters, curr->data), TRUE);
if (result) {
return result;
}
curr = g_list_next(curr);
}
return NULL;
}
void
autocompleters_reset(void)
{
GList *acs = g_hash_table_get_values(autocompleters);
GList *curr = acs;
while (curr) {
autocomplete_reset(curr->data);
curr = g_list_next(curr);
}
}
void autocompleters_destroy(void)
{
g_hash_table_destroy(autocompleters);
}

View File

@@ -0,0 +1,46 @@
/*
* autocompleters.h
*
* Copyright (C) 2012 - 2015 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/>.
*
* 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.
*
*/
#ifndef AUTOCOMPLETERS_H
#define AUTOCOMPLETERS_H
#include <glib.h>
void autocompleters_init(void);
void autocompleters_add(const char *key, char **items);
char* autocompleters_complete(const char * const input);
void autocompleters_reset(void);
void autocompleters_destroy(void);
#endif

240
src/plugins/c_api.c Normal file
View File

@@ -0,0 +1,240 @@
/*
* c_api.c
*
* Copyright (C) 2012 - 2015 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/>.
*
* 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 <stdlib.h>
#include <glib.h>
#include "log.h"
#include "plugins/api.h"
#include "plugins/c_api.h"
#include "plugins/callbacks.h"
#include "plugins/profapi.h"
typedef struct command_wrapper_t {
void(*func)(char **args);
} CommandWrapper;
typedef struct timed_wrapper_t {
void(*func)(void);
} TimedWrapper;
typedef struct window_wrapper_t {
void(*func)(char *tag, char *line);
} WindowWrapper;
static void
c_api_cons_alert(void)
{
api_cons_alert();
}
static void
c_api_cons_show(const char * const message)
{
if (message) {
api_cons_show(message);
}
}
static void
c_api_register_command(const char *command_name, int min_args, int max_args,
const char *usage, const char *short_help, const char *long_help, void(*callback)(char **args))
{
CommandWrapper *wrapper = malloc(sizeof(CommandWrapper));
wrapper->func = callback;
api_register_command(command_name, min_args, max_args, usage,
short_help, long_help, wrapper, c_command_callback);
}
static void
c_api_register_timed(void(*callback)(void), int interval_seconds)
{
TimedWrapper *wrapper = malloc(sizeof(TimedWrapper));
wrapper->func = callback;
api_register_timed(wrapper, interval_seconds, c_timed_callback);
}
static void
c_api_register_ac(const char *key, char **items)
{
api_register_ac(key, items);
}
static void
c_api_notify(const char *message, int timeout_ms, const char *category)
{
api_notify(message, category, timeout_ms);
}
static void
c_api_send_line(char *line)
{
api_send_line(line);
}
static char *
c_api_get_current_recipient(void)
{
return api_get_current_recipient();
}
static char *
c_api_get_current_muc(void)
{
return api_get_current_muc();
}
static void
c_api_log_debug(const char *message)
{
api_log_debug(message);
}
static void
c_api_log_info(const char *message)
{
api_log_info(message);
}
static void
c_api_log_warning(const char *message)
{
api_log_warning(message);
}
static void
c_api_log_error(const char *message)
{
api_log_error(message);
}
int
c_api_win_exists(char *tag)
{
return api_win_exists(tag);
}
void
c_api_win_create(char *tag, void(*callback)(char *tag, char *line))
{
WindowWrapper *wrapper = malloc(sizeof(WindowWrapper));
wrapper->func = callback;
api_win_create(tag, wrapper, c_window_callback);
}
void
c_api_win_focus(char *tag)
{
api_win_focus(tag);
}
void
c_api_win_show(char *tag, char *line)
{
api_win_show(tag, line);
}
void
c_api_win_show_green(char *tag, char *line)
{
api_win_show_green(tag, line);
}
void
c_api_win_show_red(char *tag, char *line)
{
api_win_show_red(tag, line);
}
void
c_api_win_show_cyan(char *tag, char *line)
{
api_win_show_cyan(tag, line);
}
void
c_api_win_show_yellow(char *tag, char *line)
{
api_win_show_yellow(tag, line);
}
void
c_command_callback(PluginCommand *command, gchar **args)
{
CommandWrapper *wrapper = command->callback;
void(*f)(gchar **args) = wrapper->func;
f(args);
}
void
c_timed_callback(PluginTimedFunction *timed_function)
{
TimedWrapper *wrapper = timed_function->callback;
void(*f)(void) = wrapper->func;
f();
}
void
c_window_callback(PluginWindowCallback *window_callback, char *tag, char *line)
{
WindowWrapper *wrapper = window_callback->callback;
void(*f)(char *tag, char *line) = wrapper->func;
f(tag, line);
}
void
c_api_init(void)
{
prof_cons_alert = c_api_cons_alert;
prof_cons_show = c_api_cons_show;
prof_register_command = c_api_register_command;
prof_register_timed = c_api_register_timed;
prof_register_ac = c_api_register_ac;
prof_notify = c_api_notify;
prof_send_line = c_api_send_line;
prof_get_current_recipient = c_api_get_current_recipient;
prof_get_current_muc = c_api_get_current_muc;
prof_log_debug = c_api_log_debug;
prof_log_info = c_api_log_info;
prof_log_warning = c_api_log_warning;
prof_log_error = c_api_log_error;
prof_win_exists = c_api_win_exists;
prof_win_create = c_api_win_create;
prof_win_focus = c_api_win_focus;
prof_win_show = c_api_win_show;
prof_win_show_green = c_api_win_show_green;
prof_win_show_red = c_api_win_show_red;
prof_win_show_cyan = c_api_win_show_cyan;
prof_win_show_yellow = c_api_win_show_yellow;
}

41
src/plugins/c_api.h Normal file
View File

@@ -0,0 +1,41 @@
/*
* c_api.h
*
* Copyright (C) 2012 - 2015 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/>.
*
* 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 <glib.h>
void c_api_init(void);
void c_command_callback(PluginCommand *command, gchar **args);
void c_timed_callback(PluginTimedFunction *timed_function);
void c_window_callback(PluginWindowCallback *window_callback, char *tag, char *line);

367
src/plugins/c_plugins.c Normal file
View File

@@ -0,0 +1,367 @@
/*
* c_plugins.c
*
* Copyright (C) 2012 - 2015 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/>.
*
* 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 <dlfcn.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <glib.h>
#include "config/preferences.h"
#include "log.h"
#include "plugins/api.h"
#include "plugins/callbacks.h"
#include "plugins/plugins.h"
#include "plugins/c_plugins.h"
#include "plugins/c_api.h"
#include "ui/ui.h"
void
c_env_init(void)
{
c_api_init();
}
ProfPlugin *
c_plugin_create(const char * const filename)
{
ProfPlugin *plugin;
void *handle = NULL;
gchar *plugins_dir = plugins_get_dir();
GString *path = g_string_new(plugins_dir);
g_free(plugins_dir);
g_string_append(path, "/");
g_string_append(path, filename);
handle = dlopen (path->str, RTLD_NOW | RTLD_GLOBAL);
if (!handle) {
log_warning ("dlopen failed to open `%s', %s", filename, dlerror ());
g_string_free(path, TRUE);
return NULL;
}
gchar *module_name = g_strndup(filename, strlen(filename) - 3);
plugin = malloc(sizeof(ProfPlugin));
plugin->name = strdup(module_name);
plugin->lang = LANG_C;
plugin->module = handle;
plugin->init_func = c_init_hook;
plugin->on_start_func = c_on_start_hook;
plugin->on_shutdown_func = c_on_shutdown_hook;
plugin->on_connect_func = c_on_connect_hook;
plugin->on_disconnect_func = c_on_disconnect_hook;
plugin->pre_chat_message_display = c_pre_chat_message_display_hook;
plugin->post_chat_message_display = c_post_chat_message_display_hook;
plugin->pre_chat_message_send = c_pre_chat_message_send_hook;
plugin->post_chat_message_send = c_post_chat_message_send_hook;
plugin->pre_room_message_display = c_pre_room_message_display_hook;
plugin->post_room_message_display = c_post_room_message_display_hook;
plugin->pre_room_message_send = c_pre_room_message_send_hook;
plugin->post_room_message_send = c_post_room_message_send_hook;
plugin->pre_priv_message_display = c_pre_priv_message_display_hook;
plugin->post_priv_message_display = c_post_priv_message_display_hook;
plugin->pre_priv_message_send = c_pre_priv_message_send_hook;
plugin->post_priv_message_send = c_post_priv_message_send_hook;
g_string_free(path, TRUE);
g_free(module_name);
return plugin;
}
void
c_init_hook(ProfPlugin *plugin, const char * const version, const char * const status)
{
void * f = NULL;
void (*func)(const char * const __version, const char * const __status);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_init"))) {
log_warning ("warning: %s does not have init function", plugin->name);
return ;
}
func = (void (*)(const char * const, const char * const))f;
// FIXME maybe we want to make it boolean to see if it succeeded or not?
func (version, status);
}
void
c_on_start_hook(ProfPlugin *plugin)
{
void * f = NULL;
void (*func)(void);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_on_start")))
return ;
func = (void (*)(void)) f;
func ();
}
void
c_on_shutdown_hook(ProfPlugin *plugin)
{
void * f = NULL;
void (*func)(void);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_on_shutdown")))
return ;
func = (void (*)(void)) f;
func ();
}
void
c_on_connect_hook(ProfPlugin *plugin, const char * const account_name, const char * const fulljid)
{
void * f = NULL;
void (*func)(const char * const __account_name, const char * const __fulljid);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_on_connect")))
return ;
func = (void (*)(const char * const, const char * const)) f;
func (account_name, fulljid);
}
void
c_on_disconnect_hook(ProfPlugin *plugin, const char * const account_name, const char * const fulljid)
{
void * f = NULL;
void (*func)(const char * const __account_name, const char * const __fulljid);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_on_disconnect")))
return ;
func = (void (*)(const char * const, const char * const)) f;
func (account_name, fulljid);
}
char *
c_pre_chat_message_display_hook(ProfPlugin *plugin, const char * const jid, const char *message)
{
void * f = NULL;
char* (*func)(const char * const __jid, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_pre_chat_message_display")))
return NULL;
func = (char* (*)(const char * const, const char *)) f;
return func (jid, message);
}
void
c_post_chat_message_display_hook(ProfPlugin *plugin, const char * const jid, const char *message)
{
void * f = NULL;
void (*func)(const char * const __jid, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_post_chat_message_display")))
return;
func = (void (*)(const char * const, const char *)) f;
func (jid, message);
}
char *
c_pre_chat_message_send_hook(ProfPlugin *plugin, const char * const jid, const char *message)
{
void * f = NULL;
char* (*func)(const char * const __jid, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_pre_chat_message_send")))
return NULL;
func = (char* (*)(const char * const, const char *)) f;
return func (jid, message);
}
void
c_post_chat_message_send_hook(ProfPlugin *plugin, const char * const jid, const char *message)
{
void * f = NULL;
void (*func)(const char * const __jid, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_post_chat_message_send")))
return;
func = (void (*)(const char * const, const char *)) f;
func (jid, message);
}
char *
c_pre_room_message_display_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char *message)
{
void * f = NULL;
char* (*func)(const char * const __room, const char * const __nick, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_pre_room_message_display")))
return NULL;
func = (char* (*)(const char * const, const char * const, const char *)) f;
return func (room, nick, message);
}
void
c_post_room_message_display_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char *message)
{
void * f = NULL;
void (*func)(const char * const __room, const char * const __nick, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_post_room_message_display")))
return;
func = (void (*)(const char * const, const char * const, const char *)) f;
func (room, nick, message);
}
char *
c_pre_room_message_send_hook(ProfPlugin *plugin, const char * const room, const char *message)
{
void * f = NULL;
char* (*func)(const char * const __room, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_pre_room_message_send")))
return NULL;
func = (char* (*)(const char * const, const char *)) f;
return func (room, message);
}
void
c_post_room_message_send_hook(ProfPlugin *plugin, const char * const room, const char *message)
{
void * f = NULL;
void (*func)(const char * const __room, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_post_room_message_send")))
return;
func = (void (*)(const char * const, const char *)) f;
func (room, message);
}
char *
c_pre_priv_message_display_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char *message)
{
void * f = NULL;
char* (*func)(const char * const __room, const char * const __nick, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_pre_priv_message_display")))
return NULL;
func = (char* (*)(const char * const, const char * const, const char *)) f;
return func (room, nick, message);
}
void
c_post_priv_message_display_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char *message)
{
void * f = NULL;
void (*func)(const char * const __room, const char * const __nick, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_post_priv_message_display")))
return;
func = (void (*)(const char * const, const char * const, const char *)) f;
func (room, nick, message);
}
char *
c_pre_priv_message_send_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char *message)
{
void * f = NULL;
char* (*func)(const char * const __room, const char * const __nick, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_pre_priv_message_send")))
return NULL;
func = (char* (*)(const char * const, const char * const, const char *)) f;
return func (room, nick, message);
}
void
c_post_priv_message_send_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char *message)
{
void * f = NULL;
void (*func)(const char * const __room, const char * const __nick, const char * __message);
assert (plugin && plugin->module);
if (NULL == (f = dlsym (plugin->module, "prof_post_priv_message_send")))
return;
func = (void (*)(const char * const, const char * const, const char *)) f;
func (room, nick, message);
}
void
c_plugin_destroy(ProfPlugin *plugin)
{
assert (plugin && plugin->module);
if (dlclose (plugin->module)) {
log_warning ("dlclose failed to close `%s' with `%s'", plugin->name, dlerror ());
}
free(plugin->name);
free(plugin);
}
void
c_shutdown(void)
{
}

67
src/plugins/c_plugins.h Normal file
View File

@@ -0,0 +1,67 @@
/*
* c_plugins.h
*
* Copyright (C) 2012 - 2015 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/>.
*
* 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.
*
*/
#ifndef C_PLUGINS_H
#define C_PLUGINS_H
#include "plugins/plugins.h"
void c_env_init(void);
ProfPlugin* c_plugin_create(const char * const filename);
void c_plugin_destroy(ProfPlugin * plugin);
void c_shutdown(void);
void c_init_hook(ProfPlugin *plugin, const char * const version, const char * const status);
void c_on_start_hook(ProfPlugin *plugin);
void c_on_shutdown_hook(ProfPlugin *plugin);
void c_on_connect_hook(ProfPlugin *plugin, const char * const account_name, const char * const fulljid);
void c_on_disconnect_hook(ProfPlugin *plugin, const char * const account_name, const char * const fulljid);
char* c_pre_chat_message_display_hook(ProfPlugin *plugin, const char * const jid, const char *message);
void c_post_chat_message_display_hook(ProfPlugin *plugin, const char * const jid, const char *message);
char* c_pre_chat_message_send_hook(ProfPlugin *plugin, const char * const jid, const char *message);
void c_post_chat_message_send_hook(ProfPlugin *plugin, const char * const jid, const char *message);
char* c_pre_room_message_display_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char *message);
void c_post_room_message_display_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char *message);
char* c_pre_room_message_send_hook(ProfPlugin *plugin, const char * const room, const char *message);
void c_post_room_message_send_hook(ProfPlugin *plugin, const char * const room, const char *message);
char* c_pre_priv_message_display_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char *message);
void c_post_priv_message_display_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char *message);
char* c_pre_priv_message_send_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char * const message);
void c_post_priv_message_send_hook(ProfPlugin *plugin, const char * const room, const char * const nick, const char * const message);
#endif

126
src/plugins/callbacks.c Normal file
View File

@@ -0,0 +1,126 @@
/*
* callbacks.c
*
* Copyright (C) 2012 - 2015 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/>.
*
* 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 <string.h>
#include "command/command.h"
#include "plugins/callbacks.h"
#include "plugins/plugins.h"
#include "tools/autocomplete.h"
#include "tools/parser.h"
#include "ui/ui.h"
static GSList *p_commands = NULL;
static GSList *p_timed_functions = NULL;
static GHashTable *p_window_callbacks = NULL;
void
callbacks_add_command(PluginCommand *command)
{
p_commands = g_slist_append(p_commands, command);
cmd_autocomplete_add(command->command_name);
}
void
callbacks_add_timed(PluginTimedFunction *timed_function)
{
p_timed_functions = g_slist_append(p_timed_functions, timed_function);
}
void
callbacks_add_window_handler(const char *tag, PluginWindowCallback *window_callback)
{
if (p_window_callbacks == NULL) {
p_window_callbacks = g_hash_table_new(g_str_hash, g_str_equal);
}
g_hash_table_insert(p_window_callbacks, strdup(tag), window_callback);
}
void *
callbacks_get_window_handler(const char *tag)
{
if (p_window_callbacks) {
return g_hash_table_lookup(p_window_callbacks, tag);
} else {
return NULL;
}
}
gboolean
plugins_run_command(const char * const input)
{
gchar **split = g_strsplit(input, " ", -1);
GSList *p_command = p_commands;
while (p_command) {
PluginCommand *command = p_command->data;
if (g_strcmp0(split[0], command->command_name) == 0) {
gboolean result;
gchar **args = parse_args(input, command->min_args, command->max_args, &result);
if (result == FALSE) {
ui_invalid_command_usage(command->usage, NULL);
return TRUE;
} else {
command->callback_func(command, args);
g_strfreev(split);
return TRUE;
}
g_strfreev(args);
}
p_command = g_slist_next(p_command);
}
g_strfreev(split);
return FALSE;
}
void
plugins_run_timed(void)
{
GSList *p_timed_function = p_timed_functions;
while (p_timed_function) {
PluginTimedFunction *timed_function = p_timed_function->data;
gdouble elapsed = g_timer_elapsed(timed_function->timer, NULL);
if (timed_function->interval_seconds > 0 && elapsed >= timed_function->interval_seconds) {
timed_function->callback_func(timed_function);
g_timer_start(timed_function->timer);
}
p_timed_function = g_slist_next(p_timed_function);
}
return;
}

68
src/plugins/callbacks.h Normal file
View File

@@ -0,0 +1,68 @@
/*
* callbacks.h
*
* Copyright (C) 2012 - 2015 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/>.
*
* 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.
*
*/
#ifndef CALLBACKS_H
#define CALLBACKS_H
#include <glib.h>
typedef struct p_command {
const char *command_name;
int min_args;
int max_args;
const char *usage;
const char *short_help;
const char *long_help;
void *callback;
void (*callback_func)(struct p_command *command, gchar **args);
} PluginCommand;
typedef struct p_timed_function {
void *callback;
void (*callback_func)(struct p_timed_function *timed_function);
int interval_seconds;
GTimer *timer;
} PluginTimedFunction;
typedef struct p_window_input_callback {
void *callback;
void (*callback_func)(struct p_window_input_callback *window_callback, const char *tag, const char * const line);
} PluginWindowCallback;
void callbacks_add_command(PluginCommand *command);
void callbacks_add_timed(PluginTimedFunction *timed_function);
void callbacks_add_window_handler(const char *tag, PluginWindowCallback *window_callback);
void * callbacks_get_window_handler(const char *tag);
#endif

497
src/plugins/plugins.c Normal file
View File

@@ -0,0 +1,497 @@
/*
* plugins.c
*
* Copyright (C) 2012 - 2015 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/>.
*
* 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 <string.h>
#include <stdlib.h>
#include "common.h"
#include "config/preferences.h"
#include "log.h"
#include "plugins/callbacks.h"
#include "plugins/autocompleters.h"
#include "plugins/api.h"
#include "plugins/plugins.h"
#ifdef PROF_HAVE_PYTHON
#include "plugins/python_plugins.h"
#include "plugins/python_api.h"
#endif
#ifdef PROF_HAVE_RUBY
#include "plugins/ruby_plugins.h"
#include "plugins/ruby_api.h"
#endif
#ifdef PROF_HAVE_LUA
#include "plugins/lua_plugins.h"
#include "plugins/lua_api.h"
#endif
#ifdef PROF_HAVE_C
#include "plugins/c_plugins.h"
#include "plugins/c_api.h"
#endif
#include "ui/ui.h"
static GSList* plugins;
void
plugins_init(void)
{
plugins = NULL;
autocompleters_init();
#ifdef PROF_HAVE_PYTHON
python_env_init();
#endif
#ifdef PROF_HAVE_RUBY
ruby_env_init();
#endif
#ifdef PROF_HAVE_LUA
lua_env_init();
#endif
#ifdef PROF_HAVE_C
c_env_init();
#endif
// load plugins
gchar **plugins_load = prefs_get_plugins();
if (plugins_load) {
int i;
for (i = 0; i < g_strv_length(plugins_load); i++)
{
gboolean loaded = FALSE;
gchar *filename = plugins_load[i];
#ifdef PROF_HAVE_PYTHON
if (g_str_has_suffix(filename, ".py")) {
ProfPlugin *plugin = python_plugin_create(filename);
if (plugin) {
plugins = g_slist_append(plugins, plugin);
loaded = TRUE;
}
}
#endif
#ifdef PROF_HAVE_RUBY
if (g_str_has_suffix(filename, ".rb")) {
ProfPlugin *plugin = ruby_plugin_create(filename);
if (plugin) {
plugins = g_slist_append(plugins, plugin);
loaded = TRUE;
}
}
#endif
#ifdef PROF_HAVE_LUA
if (g_str_has_suffix(filename, ".lua")) {
ProfPlugin *plugin = lua_plugin_create(filename);
if (plugin) {
plugins = g_slist_append(plugins, plugin);
loaded = TRUE;
}
}
#endif
#ifdef PROF_HAVE_C
if (g_str_has_suffix(filename, ".so")) {
ProfPlugin *plugin = c_plugin_create(filename);
if (plugin) {
plugins = g_slist_append(plugins, plugin);
loaded = TRUE;
}
}
#endif
if (loaded == TRUE) {
log_info("Loaded plugin: %s", filename);
}
}
// initialise plugins
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->init_func(plugin, PROF_PACKAGE_VERSION, PROF_PACKAGE_STATUS);
curr = g_slist_next(curr);
}
}
return;
}
GSList *
plugins_get_list(void)
{
return plugins;
}
char *
plugins_get_lang_string(ProfPlugin *plugin)
{
switch (plugin->lang)
{
case LANG_PYTHON:
return "Python";
case LANG_RUBY:
return "Ruby";
case LANG_LUA:
return "Lua";
case LANG_C:
return "C";
default:
return "Unknown";
}
}
char *
plugins_autocomplete(const char * const input)
{
return autocompleters_complete(input);
}
void
plugins_reset_autocomplete(void)
{
autocompleters_reset();
}
void
plugins_win_process_line(char *win, const char * const line)
{
PluginWindowCallback *window = callbacks_get_window_handler(win);
window->callback_func(window, win, line);
}
void
plugins_on_start(void)
{
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->on_start_func(plugin);
curr = g_slist_next(curr);
}
}
void
plugins_on_shutdown(void)
{
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->on_shutdown_func(plugin);
curr = g_slist_next(curr);
}
}
void
plugins_on_connect(const char * const account_name, const char * const fulljid)
{
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->on_connect_func(plugin, account_name, fulljid);
curr = g_slist_next(curr);
}
}
void
plugins_on_disconnect(const char * const account_name, const char * const fulljid)
{
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->on_disconnect_func(plugin, account_name, fulljid);
curr = g_slist_next(curr);
}
}
char*
plugins_pre_chat_message_display(const char * const jid, const char *message)
{
char *new_message = NULL;
char *curr_message = strdup(message);
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
new_message = plugin->pre_chat_message_display(plugin, jid, curr_message);
if (new_message) {
free(curr_message);
curr_message = strdup(new_message);
free(new_message);
}
curr = g_slist_next(curr);
}
return curr_message;
}
void
plugins_post_chat_message_display(const char * const jid, const char *message)
{
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->post_chat_message_display(plugin, jid, message);
curr = g_slist_next(curr);
}
}
char*
plugins_pre_chat_message_send(const char * const jid, const char *message)
{
char *new_message = NULL;
char *curr_message = strdup(message);
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
new_message = plugin->pre_chat_message_send(plugin, jid, curr_message);
if (new_message) {
free(curr_message);
curr_message = strdup(new_message);
free(new_message);
}
curr = g_slist_next(curr);
}
return curr_message;
}
void
plugins_post_chat_message_send(const char * const jid, const char *message)
{
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->post_chat_message_send(plugin, jid, message);
curr = g_slist_next(curr);
}
}
char*
plugins_pre_room_message_display(const char * const room, const char * const nick, const char *message)
{
char *new_message = NULL;
char *curr_message = strdup(message);
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
new_message = plugin->pre_room_message_display(plugin, room, nick, curr_message);
if (new_message) {
free(curr_message);
curr_message = strdup(new_message);
free(new_message);
}
curr = g_slist_next(curr);
}
return curr_message;
}
void
plugins_post_room_message_display(const char * const room, const char * const nick, const char *message)
{
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->post_room_message_display(plugin, room, nick, message);
curr = g_slist_next(curr);
}
}
char*
plugins_pre_room_message_send(const char * const room, const char *message)
{
char *new_message = NULL;
char *curr_message = strdup(message);
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
new_message = plugin->pre_room_message_send(plugin, room, curr_message);
if (new_message) {
free(curr_message);
curr_message = strdup(new_message);
free(new_message);
}
curr = g_slist_next(curr);
}
return curr_message;
}
void
plugins_post_room_message_send(const char * const room, const char *message)
{
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->post_room_message_send(plugin, room, message);
curr = g_slist_next(curr);
}
}
char*
plugins_pre_priv_message_display(const char * const jid, const char *message)
{
Jid *jidp = jid_create(jid);
char *new_message = NULL;
char *curr_message = strdup(message);
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
new_message = plugin->pre_priv_message_display(plugin, jidp->barejid, jidp->resourcepart, curr_message);
if (new_message) {
free(curr_message);
curr_message = strdup(new_message);
free(new_message);
}
curr = g_slist_next(curr);
}
jid_destroy(jidp);
return curr_message;
}
void
plugins_post_priv_message_display(const char * const jid, const char *message)
{
Jid *jidp = jid_create(jid);
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->post_priv_message_display(plugin, jidp->barejid, jidp->resourcepart, message);
curr = g_slist_next(curr);
}
jid_destroy(jidp);
}
char*
plugins_pre_priv_message_send(const char * const jid, const char * const message)
{
Jid *jidp = jid_create(jid);
char *new_message = NULL;
char *curr_message = strdup(message);
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
new_message = plugin->pre_priv_message_send(plugin, jidp->barejid, jidp->resourcepart, curr_message);
if (new_message) {
free(curr_message);
curr_message = strdup(new_message);
free(new_message);
}
curr = g_slist_next(curr);
}
jid_destroy(jidp);
return curr_message;
}
void
plugins_post_priv_message_send(const char * const jid, const char * const message)
{
Jid *jidp = jid_create(jid);
GSList *curr = plugins;
while (curr) {
ProfPlugin *plugin = curr->data;
plugin->post_priv_message_send(plugin, jidp->barejid, jidp->resourcepart, message);
curr = g_slist_next(curr);
}
jid_destroy(jidp);
}
void
plugins_shutdown(void)
{
GSList *curr = plugins;
while (curr) {
#ifdef PROF_HAVE_PYTHON
if (((ProfPlugin *)curr->data)->lang == LANG_PYTHON) {
python_plugin_destroy(curr->data);
}
#endif
#ifdef PROF_HAVE_RUBY
if (((ProfPlugin *)curr->data)->lang == LANG_RUBY) {
ruby_plugin_destroy(curr->data);
}
#endif
#ifdef PROF_HAVE_LUA
if (((ProfPlugin *)curr->data)->lang == LANG_LUA) {
lua_plugin_destroy(curr->data);
}
#endif
#ifdef PROF_HAVE_C
if (((ProfPlugin *)curr->data)->lang == LANG_C) {
c_plugin_destroy(curr->data);
}
#endif
curr = g_slist_next(curr);
}
#ifdef PROF_HAVE_PYTHON
python_shutdown();
#endif
#ifdef PROF_HAVE_RUBY
ruby_shutdown();
#endif
#ifdef PROF_HAVE_LUA
lua_shutdown();
#endif
#ifdef PROF_HAVE_C
c_shutdown();
#endif
autocompleters_destroy();
}
gchar *
plugins_get_dir(void)
{
gchar *xdg_data = xdg_get_data_home();
GString *plugins_dir = g_string_new(xdg_data);
g_string_append(plugins_dir, "/profanity/plugins");
gchar *result = strdup(plugins_dir->str);
g_free(xdg_data);
g_string_free(plugins_dir, TRUE);
return result;
}

108
src/plugins/plugins.h Normal file
View File

@@ -0,0 +1,108 @@
/*
* plugins.h
*
* Copyright (C) 2012 - 2015 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/>.
*
* 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.
*
*/
#ifndef PLUGINS_H
#define PLUGINS_H
typedef enum {
LANG_PYTHON,
LANG_RUBY,
LANG_LUA,
LANG_C
} lang_t;
typedef struct prof_plugin_t {
char *name;
lang_t lang;
void *module;
void (*init_func)(struct prof_plugin_t* plugin, const char * const version,
const char * const status);
void (*on_start_func)(struct prof_plugin_t* plugin);
void (*on_shutdown_func)(struct prof_plugin_t* plugin);
void (*on_connect_func)(struct prof_plugin_t* plugin, const char * const account_name, const char * const fulljid);
void (*on_disconnect_func)(struct prof_plugin_t* plugin, const char * const account_name, const char * const fulljid);
char* (*pre_chat_message_display)(struct prof_plugin_t* plugin, const char * const jid, const char *message);
void (*post_chat_message_display)(struct prof_plugin_t* plugin, const char * const jid, const char *message);
char* (*pre_chat_message_send)(struct prof_plugin_t* plugin, const char * const jid, const char *message);
void (*post_chat_message_send)(struct prof_plugin_t* plugin, const char * const jid, const char *message);
char* (*pre_room_message_display)(struct prof_plugin_t* plugin, const char * const room, const char * const nick, const char *message);
void (*post_room_message_display)(struct prof_plugin_t* plugin, const char * const room, const char * const nick, const char *message);
char* (*pre_room_message_send)(struct prof_plugin_t* plugin, const char * const room, const char *message);
void (*post_room_message_send)(struct prof_plugin_t* plugin, const char * const room, const char *message);
char* (*pre_priv_message_display)(struct prof_plugin_t* plugin, const char * const room, const char * const nick, const char *message);
void (*post_priv_message_display)(struct prof_plugin_t* plugin, const char * const room, const char * const nick, const char *message);
char* (*pre_priv_message_send)(struct prof_plugin_t* plugin, const char * const room, const char * const nick, const char * const message);
void (*post_priv_message_send)(struct prof_plugin_t* plugin, const char * const room, const char * const nick, const char * const message);
} ProfPlugin;
void plugins_init(void);
GSList* plugins_get_list(void);
char* plugins_get_lang_string(ProfPlugin *plugin);
char* plugins_autocomplete(const char * const input);
void plugins_reset_autocomplete(void);
void plugins_shutdown(void);
void plugins_on_start(void);
void plugins_on_shutdown(void);
void plugins_on_connect(const char * const account_name, const char * const fulljid);
void plugins_on_disconnect(const char * const account_name, const char * const fulljid);
char* plugins_pre_chat_message_display(const char * const jid, const char *message);
void plugins_post_chat_message_display(const char * const jid, const char *message);
char* plugins_pre_chat_message_send(const char * const jid, const char *message);
void plugins_post_chat_message_send(const char * const jid, const char *message);
char* plugins_pre_room_message_display(const char * const room, const char * const nick, const char *message);
void plugins_post_room_message_display(const char * const room, const char * const nick, const char *message);
char* plugins_pre_room_message_send(const char * const room, const char *message);
void plugins_post_room_message_send(const char * const room, const char *message);
char* plugins_pre_priv_message_display(const char * const jid, const char *message);
void plugins_post_priv_message_display(const char * const jid, const char *message);
char* plugins_pre_priv_message_send(const char * const jid, const char * const message);
void plugins_post_priv_message_send(const char * const jid, const char * const message);
gboolean plugins_run_command(const char * const cmd);
void plugins_run_timed(void);
gchar * plugins_get_dir(void);
void plugins_win_process_line(char *win, const char * const line);
#endif

70
src/plugins/profapi.c Normal file
View File

@@ -0,0 +1,70 @@
/*
* prof_api.c
*
* Copyright (C) 2012 - 2015 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/>.
*
* 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 <stdlib.h>
#include "plugins/profapi.h"
#include "plugins/callbacks.h"
void (*prof_cons_alert)(void) = NULL;
void (*prof_cons_show)(const char * const message) = NULL;
void (*prof_register_command)(const char *command_name, int min_args, int max_args,
const char *usage, const char *short_help, const char *long_help, void(*callback)(char **args)) = NULL;
void (*prof_register_timed)(void(*callback)(void), int interval_seconds) = NULL;
void (*prof_register_ac)(const char *key, char **items) = NULL;
void (*prof_notify)(const char *message, int timeout_ms, const char *category) = NULL;
void (*prof_send_line)(char *line) = NULL;
char* (*prof_get_current_recipient)(void) = NULL;
char* (*prof_get_current_muc)(void) = NULL;
void (*prof_log_debug)(const char *message) = NULL;
void (*prof_log_info)(const char *message) = NULL;
void (*prof_log_warning)(const char *message) = NULL;
void (*prof_log_error)(const char *message) = NULL;
int (*prof_win_exists)(PROF_WIN_TAG win) = NULL;
void (*prof_win_create)(PROF_WIN_TAG win, void(*input_handler)(PROF_WIN_TAG win, char *line)) = NULL;
void (*prof_win_focus)(PROF_WIN_TAG win) = NULL;
void (*prof_win_show)(PROF_WIN_TAG win, char *line) = NULL;
void (*prof_win_show_green)(PROF_WIN_TAG win, char *line) = NULL;
void (*prof_win_show_red)(PROF_WIN_TAG win, char *line) = NULL;
void (*prof_win_show_cyan)(PROF_WIN_TAG win, char *line) = NULL;
void (*prof_win_show_yellow)(PROF_WIN_TAG win, char *line) = NULL;

72
src/plugins/profapi.h Normal file
View File

@@ -0,0 +1,72 @@
/*
* prof_api.h
*
* Copyright (C) 2012 - 2015 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/>.
*
* 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.
*
*/
#ifndef PROF_API_H
#define PROF_API_H
typedef char* PROF_WIN_TAG;
void (*prof_cons_alert)(void);
void (*prof_cons_show)(const char * const message);
void (*prof_register_command)(const char *command_name, int min_args, int max_args,
const char *usage, const char *short_help, const char *long_help, void(*callback)(char **args));
void (*prof_register_timed)(void(*callback)(void), int interval_seconds);
void (*prof_register_ac)(const char *key, char **items);
void (*prof_notify)(const char *message, int timeout_ms, const char *category);
void (*prof_send_line)(char *line);
char* (*prof_get_current_recipient)(void);
char* (*prof_get_current_muc)(void);
void (*prof_log_debug)(const char *message);
void (*prof_log_info)(const char *message);
void (*prof_log_warning)(const char *message);
void (*prof_log_error)(const char *message);
int (*prof_win_exists)(PROF_WIN_TAG win);
void (*prof_win_create)(PROF_WIN_TAG win, void(*input_handler)(PROF_WIN_TAG win, char *line));
void (*prof_win_focus)(PROF_WIN_TAG win);
void (*prof_win_show)(PROF_WIN_TAG win, char *line);
void (*prof_win_show_green)(PROF_WIN_TAG win, char *line);
void (*prof_win_show_red)(PROF_WIN_TAG win, char *line);
void (*prof_win_show_cyan)(PROF_WIN_TAG win, char *line);
void (*prof_win_show_yellow)(PROF_WIN_TAG win, char *line);
#endif