// This Source Code Form is subject to the terms of the Mozilla Public // License, version 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include #include #include #include #include #include #include #include "plugin.hh" #include "config.hh" #include "account.hh" #include "connection.hh" #include "command.hh" #include "input.hh" #include "buffer.hh" #include "completion.hh" #define WEECHAT_TIMER_INTERVAL_SEC 0.01 #define WEECHAT_TIMER_SECONDS(IVL) (WEECHAT_TIMER_INTERVAL_SEC * IVL) #pragma GCC visibility push(default) extern "C" { WEECHAT_PLUGIN_NAME(WEECHAT_XMPP_PLUGIN_NAME); WEECHAT_PLUGIN_DESCRIPTION(N_("XMPP client protocol")); WEECHAT_PLUGIN_AUTHOR("bqv "); WEECHAT_PLUGIN_VERSION(WEECHAT_XMPP_PLUGIN_VERSION); WEECHAT_PLUGIN_LICENSE("MPL2"); WEECHAT_PLUGIN_PRIORITY(5500); } void (* weechat_signal_handler)(int); extern "C" void wrapped_signal_handler(int arg) { // wrap weechat's handler weechat_signal_handler(arg); __asm__("int3"); } extern "C" int weechat_plugin_init(struct t_weechat_plugin *plugin, int argc, char *argv[]) { try { weechat::plugin::instance = std::make_unique(plugin); weechat::plugin::instance->init(argc, argv); } catch (std::exception const& ex) { return WEECHAT_RC_ERROR; } return WEECHAT_RC_OK; } extern "C" int weechat_plugin_end(struct t_weechat_plugin *plugin) { try { if (plugin != *weechat::plugin::instance) throw std::runtime_error("wrong plugin?"); weechat::plugin::instance->end(); weechat::plugin::instance.reset(); } catch (std::exception const& ex) { return WEECHAT_RC_ERROR; } return WEECHAT_RC_OK; } std::unique_ptr weechat::plugin::instance; weechat::plugin::plugin(struct t_weechat_plugin *plugin) : m_plugin_ptr(plugin) { } void weechat::plugin::init(int argc, char *argv[]) { m_args = std::vector(argv, argv+argc); if (std::find(m_args.begin(), m_args.end(), "debug") != m_args.end()) weechat_signal_handler = std::signal(SIGSEGV, wrapped_signal_handler); if (!weechat::config::init()) // TODO: bool -> exceptions throw std::runtime_error("Config init failed"); weechat::config::read(); weechat::connection::init(); command__init(); // TODO: port completion__init(); // TODO: port m_process_timer = weechat_hook_timer(WEECHAT_TIMER_SECONDS(1000), 0, 0, &weechat::account::timer_cb, nullptr, nullptr); if (!weechat_bar_search(typing_bar_name.data())) { weechat_bar_new(typing_bar_name.data(), "off", "400", "window", "${typing}", "bottom", "horizontal", "vertical", "1", "1", "default", "default", "default", "default", "off", typing_bar_item_name.data()); } m_typing_bar_item = weechat_bar_item_new(typing_bar_item_name.data(), &buffer__typing_bar_cb, // TODO: port nullptr, nullptr); weechat_hook_signal("input_text_changed", &input__text_changed_cb, // TODO: port nullptr, nullptr); } void weechat::plugin::end() { if (m_typing_bar_item) // raii? weechat_bar_item_remove(m_typing_bar_item); if (m_process_timer) // raii? weechat_unhook(m_process_timer); weechat::config::write(); weechat::config::instance.reset(); weechat::account::disconnect_all(); weechat::accounts.clear(); libstrophe::shutdown(); } weechat::plugin::~plugin() { }