diff --git a/markdown/src/plugin.c b/markdown/src/plugin.c index 4dd001a6dd..ea5d5d7198 100644 --- a/markdown/src/plugin.c +++ b/markdown/src/plugin.c @@ -24,16 +24,7 @@ #include "viewer.h" #include "conf.h" -GeanyData *geany_data; -GeanyPlugin *geany_plugin; - -PLUGIN_VERSION_CHECK(224) - -PLUGIN_SET_TRANSLATABLE_INFO(LOCALEDIR, GETTEXT_PACKAGE, - "Markdown", - _("Real-time Markdown preview"), - "0.01", - "Matthew Brush ") +static GeanyPlugin *geany_plugin = NULL; /* Should be defined by build system, this is just a fallback */ #ifndef MARKDOWN_DOC_DIR @@ -58,8 +49,8 @@ static void on_document_filetype_set(GObject *obj, GeanyDocument *doc, GeanyFile static void on_view_pos_notify(GObject *obj, GParamSpec *pspec, MarkdownViewer *viewer); static void on_export_as_html_activate(GtkMenuItem *item, MarkdownViewer *viewer); -/* Main plugin entry point on plugin load. */ -void plugin_init(GeanyData *data) +/* Plugin entry point on activation. */ +static gboolean md_plugin_init(GeanyPlugin *plugin, gpointer data) { gint page_num; gchar *conf_fn; @@ -68,9 +59,11 @@ void plugin_init(GeanyData *data) GtkWidget *viewer; GtkNotebook *nb; + geany_plugin = plugin; + /* Setup the config object which is needed by the view. */ - conf_fn = g_build_filename(geany->app->configdir, "plugins", "markdown", - "markdown.conf", NULL); + conf_fn = g_build_filename(geany_plugin->geany_data->app->configdir, + "plugins", "markdown", "markdown.conf", NULL); conf = markdown_config_new(conf_fn); g_free(conf_fn); @@ -85,11 +78,11 @@ void plugin_init(GeanyData *data) GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); if (view_pos == MARKDOWN_CONFIG_VIEW_POS_MSGWIN) { - nb = GTK_NOTEBOOK(geany->main_widgets->message_window_notebook); + nb = GTK_NOTEBOOK(geany_plugin->geany_data->main_widgets->message_window_notebook); page_num = gtk_notebook_append_page(nb, g_scrolled_win, gtk_label_new(MARKDOWN_PREVIEW_LABEL)); } else { - nb = GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook); + nb = GTK_NOTEBOOK(geany_plugin->geany_data->main_widgets->sidebar_notebook); page_num = gtk_notebook_append_page(nb, g_scrolled_win, gtk_label_new(MARKDOWN_PREVIEW_LABEL)); } @@ -100,7 +93,7 @@ void plugin_init(GeanyData *data) g_signal_connect(conf, "notify::view-pos", G_CALLBACK(on_view_pos_notify), viewer); g_export_html = gtk_menu_item_new_with_label(_("Export Markdown as HTML...")); - gtk_menu_shell_append(GTK_MENU_SHELL(data->main_widgets->tools_menu), g_export_html); + gtk_menu_shell_append(GTK_MENU_SHELL(geany_plugin->geany_data->main_widgets->tools_menu), g_export_html); g_signal_connect(g_export_html, "activate", G_CALLBACK(on_export_as_html_activate), viewer); gtk_widget_show(g_export_html); @@ -116,22 +109,22 @@ void plugin_init(GeanyData *data) MD_PSC("document-reload", on_document_signal); #undef MD_PSC - /* Prevent segfault in plugin when it registers GTypes and gets unloaded - * and when reloaded tries to re-register the GTypes. */ - plugin_module_make_resident(geany_plugin); - update_markdown_viewer(MARKDOWN_VIEWER(viewer)); + + return TRUE; } /* Cleanup resources on plugin unload. */ -void plugin_cleanup(void) +static void md_plugin_cleanup(GeanyPlugin *plugin, gpointer data) { gtk_widget_destroy(g_export_html); gtk_widget_destroy(g_scrolled_win); + + geany_plugin = NULL; } /* Called to show the preferences GUI. */ -GtkWidget *plugin_configure(GtkDialog *dialog) +static GtkWidget *md_plugin_configure(GeanyPlugin *plugin, GtkDialog *dialog, gpointer data) { MarkdownConfig *conf = NULL; g_object_get(g_viewer, "config", &conf, NULL); @@ -139,7 +132,7 @@ GtkWidget *plugin_configure(GtkDialog *dialog) } /* Called to show the plugin's help */ -void plugin_help(void) +static void md_plugin_help(GeanyPlugin *plugin, gpointer data) { #ifdef G_OS_WIN32 gchar *prefix = g_win32_get_package_installation_directory_of_module(NULL); @@ -218,8 +211,8 @@ on_view_pos_notify(GObject *obj, GParamSpec *pspec, MarkdownViewer *viewer) { gint page_num; GtkNotebook *newnb; - GtkNotebook *snb = GTK_NOTEBOOK(geany->main_widgets->sidebar_notebook); - GtkNotebook *mnb = GTK_NOTEBOOK(geany->main_widgets->message_window_notebook); + GtkNotebook *snb = GTK_NOTEBOOK(geany_plugin->geany_data->main_widgets->sidebar_notebook); + GtkNotebook *mnb = GTK_NOTEBOOK(geany_plugin->geany_data->main_widgets->message_window_notebook); MarkdownConfigViewPos view_pos; g_object_ref(g_scrolled_win); /* Prevent it from being destroyed */ @@ -276,7 +269,7 @@ static void on_export_as_html_activate(GtkMenuItem *item, MarkdownViewer *viewer g_return_if_fail(DOC_VALID(doc)); dialog = gtk_file_chooser_dialog_new(_("Save HTML File As"), - GTK_WINDOW(geany_data->main_widgets->window), GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_WINDOW(geany_plugin->geany_data->main_widgets->window), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); @@ -331,3 +324,34 @@ static void on_export_as_html_activate(GtkMenuItem *item, MarkdownViewer *viewer gtk_widget_destroy(dialog); } + +/* Main plugin entry point on plugin load */ +G_MODULE_EXPORT +void geany_load_module(GeanyPlugin *plugin) +{ + /* setup translation */ + main_locale_init(LOCALEDIR, GETTEXT_PACKAGE); + + /* metadata */ + plugin->info->name = "Markdown"; + plugin->info->description = _("Real-time Markdown preview"); + plugin->info->version = "0.01"; + plugin->info->author = "Matthew Brush "; + + /* entry points */ + plugin->funcs->init = md_plugin_init; + plugin->funcs->cleanup = md_plugin_cleanup; + plugin->funcs->configure = md_plugin_configure; + plugin->funcs->help = md_plugin_help; + + /* Prevent segfault in plugin when it registers GTypes and gets unloaded + * and when reloaded tries to re-register the GTypes. + * It used to be only needed in init() (e.g. when the plugin actually called + * some WebKit stuff), but we now see crashes with recent WebKit versions + * even if the module has merely been loaded (e.g. for listing in the plugin + * manager). */ + plugin_module_make_resident(plugin); + + /* register */ + GEANY_PLUGIN_REGISTER(plugin, 224); +} diff --git a/webhelper/src/gwh-browser.c b/webhelper/src/gwh-browser.c index 1cb3bf3691..9fe1139080 100644 --- a/webhelper/src/gwh-browser.c +++ b/webhelper/src/gwh-browser.c @@ -920,7 +920,7 @@ gwh_browser_init (GwhBrowser *self) gtk_box_pack_start (GTK_BOX (self), scrolled, TRUE, TRUE, 0); gtk_widget_show_all (scrolled); - self->priv->statusbar = ui_lookup_widget (geany->main_widgets->window, "statusbar"); + self->priv->statusbar = ui_lookup_widget (geany_plugin->geany_data->main_widgets->window, "statusbar"); if (self->priv->statusbar) { g_object_ref (self->priv->statusbar); } else { diff --git a/webhelper/src/gwh-plugin.c b/webhelper/src/gwh-plugin.c index 6480858b33..20299eda2e 100644 --- a/webhelper/src/gwh-plugin.c +++ b/webhelper/src/gwh-plugin.c @@ -38,21 +38,9 @@ #include "gwh-enum-types.h" -GeanyPlugin *geany_plugin; -GeanyData *geany_data; - - -PLUGIN_VERSION_CHECK(224) - -PLUGIN_SET_TRANSLATABLE_INFO ( - LOCALEDIR, GETTEXT_PACKAGE, - _("Web helper"), - _("Display a preview web page that gets updated upon document saving and " - "provide web analysis and debugging tools (aka Web Inspector), all using " - "WebKit."), - GWH_PLUGIN_VERSION, - "Colomban Wendling " -) +/* we still use this in other files, although it's set by us in init(), not by + * Geany */ +GeanyPlugin *geany_plugin = NULL; enum { @@ -115,7 +103,7 @@ on_idle_widget_show (gpointer data) /* present back the Geany's window because it is very unlikely the user * expects the focus on our newly created window at this point, since we * either just loaded the plugin or activated a element from Geany's UI */ - gtk_window_present (GTK_WINDOW (geany_data->main_widgets->window)); + gtk_window_present (GTK_WINDOW (geany_plugin->geany_data->main_widgets->window)); return FALSE; } @@ -147,11 +135,11 @@ create_separate_window (void) gtk_container_add (GTK_CONTAINER (window), G_browser); if (is_transient) { gtk_window_set_transient_for (GTK_WINDOW (window), - GTK_WINDOW (geany_data->main_widgets->window)); + GTK_WINDOW (geany_plugin->geany_data->main_widgets->window)); } else { GList *icons; - icons = gtk_window_get_icon_list (GTK_WINDOW (geany_data->main_widgets->window)); + icons = gtk_window_get_icon_list (GTK_WINDOW (geany_plugin->geany_data->main_widgets->window)); gtk_window_set_icon_list (GTK_WINDOW (window), icons); g_list_free (icons); } @@ -174,9 +162,9 @@ attach_browser (void) } else { G_container.type = CONTAINER_NOTEBOOK; if (position == GWH_BROWSER_POSITION_SIDEBAR) { - G_container.widget = geany_data->main_widgets->sidebar_notebook; + G_container.widget = geany_plugin->geany_data->main_widgets->sidebar_notebook; } else { - G_container.widget = geany_data->main_widgets->message_window_notebook; + G_container.widget = geany_plugin->geany_data->main_widgets->message_window_notebook; } gtk_notebook_append_page (GTK_NOTEBOOK (G_container.widget), G_browser, gtk_label_new (_("Web preview"))); @@ -311,7 +299,7 @@ on_kb_load_current_file (guint key_id) static gchar * get_config_filename (void) { - return g_build_filename (geany_data->app->configdir, "plugins", + return g_build_filename (geany_plugin->geany_data->app->configdir, "plugins", GWH_PLUGIN_TARNAME, GWH_PLUGIN_TARNAME".conf", NULL); } @@ -415,15 +403,12 @@ save_config (void) G_settings = NULL; } -void -plugin_init (GeanyData *data) +static gboolean +gwh_plugin_init (GeanyPlugin *plugin, + gpointer data) { - /* even though it's not really a good idea to keep all the library we load - * into memory, this is needed for webkit. first, without this we creash after - * module unloading, and webkitgtk inserts static data into the GLib - * (g_quark_from_static_string() for example) so it's not safe to remove it */ - plugin_module_make_resident (geany_plugin); - + geany_plugin = plugin; + load_config (); gwh_keybindings_init (); @@ -465,15 +450,20 @@ plugin_init (GeanyData *data) keybindings_set_item (gwh_keybindings_get_group (), GWH_KB_LOAD_CURRENT_FILE, on_kb_load_current_file, 0, 0, "load_current_file", _("Load the current file in the web view"), NULL); + + return TRUE; } -void -plugin_cleanup (void) +static void +gwh_plugin_cleanup (GeanyPlugin *plugin, + gpointer data) { detach_browser (); gwh_keybindings_cleanup (); save_config (); + + geany_plugin = NULL; } @@ -516,8 +506,10 @@ on_configure_dialog_response (GtkDialog *dialog, } } -GtkWidget * -plugin_configure (GtkDialog *dialog) +static GtkWidget * +gwh_plugin_configure (GeanyPlugin *plugin, + GtkDialog *dialog, + gpointer data) { GtkWidget *box1; GtkWidget *box; @@ -563,3 +555,38 @@ plugin_configure (GtkDialog *dialog) return box1; } + +/* Load module */ +G_MODULE_EXPORT void +geany_load_module (GeanyPlugin *plugin) +{ + /* setup translation */ + main_locale_init (LOCALEDIR, GETTEXT_PACKAGE); + + /* metadata */ + plugin->info->name = _("Web helper"); + plugin->info->description = _("Display a preview web page that gets updated " + "upon document saving and provide web " + "analysis and debugging tools (aka Web " + "Inspector), all using WebKit."); + plugin->info->version = GWH_PLUGIN_VERSION; + plugin->info->author = "Colomban Wendling "; + + /* entry points */ + plugin->funcs->init = gwh_plugin_init; + plugin->funcs->cleanup = gwh_plugin_cleanup; + plugin->funcs->configure = gwh_plugin_configure; + + /* even though it's not really a good idea to keep all the libraries we load + * into memory, this is needed for webkit. first, without this we crash after + * module unloading, and webkitgtk inserts static data into GLib + * (g_quark_from_static_string() for example) so it's not safe to remove it. + * It used to be only needed in init() (e.g. when the plugin actually called + * some WebKit stuff), but we now see crashes with recent WebKit versions + * even if the module has merely been loaded (e.g. for listing in the plugin + * manager). */ + plugin_module_make_resident (plugin); + + /* register */ + GEANY_PLUGIN_REGISTER (plugin, 224); +} diff --git a/webhelper/src/gwh-plugin.h b/webhelper/src/gwh-plugin.h index f3a2b9d08e..91e8905831 100644 --- a/webhelper/src/gwh-plugin.h +++ b/webhelper/src/gwh-plugin.h @@ -33,8 +33,7 @@ G_BEGIN_DECLS #define GWH_PLUGIN_VERSION "0.2" -extern GeanyPlugin *geany_plugin; -extern GeanyData *geany_data; +extern GeanyPlugin *geany_plugin; G_END_DECLS