--- configure.ac | 1 data/gnome-settings-daemon.schemas.in | 23 ++ plugins/Makefile.am | 1 plugins/apport/Makefile.am | 32 +++ plugins/apport/apport.gnome-settings-plugin.in | 8 plugins/apport/gsd-apport-manager.c | 219 +++++++++++++++++++++++++ plugins/apport/gsd-apport-manager.h | 58 ++++++ plugins/apport/gsd-apport-plugin.c | 104 +++++++++++ plugins/apport/gsd-apport-plugin.h | 57 ++++++ 9 files changed, 503 insertions(+) Index: configure.ac =================================================================== --- configure.ac.orig +++ configure.ac @@ -425,6 +425,7 @@ Makefile gnome-settings-daemon/Makefile plugins/Makefile plugins/a11y-keyboard/Makefile +plugins/apport/Makefile plugins/background/Makefile plugins/clipboard/Makefile plugins/common/Makefile Index: data/gnome-settings-daemon.schemas.in =================================================================== --- data/gnome-settings-daemon.schemas.in.orig +++ data/gnome-settings-daemon.schemas.in @@ -26,6 +26,29 @@ + /schemas/apps/gnome_settings_daemon/plugins/apport/active + /apps/gnome_settings_daemon/plugins/apport/active + gnome-settings-daemon + bool + TRUE + + Enable Apport monitoring plugin + Set to True to enable the plugin to manage Apport crash reports. + + + + /schemas/apps/gnome_settings_daemon/plugins/apport/priority + /apps/gnome_settings_daemon/plugins/apport/priority + gnome-settings-daemon + int + 400 + + + + + + + /schemas/apps/gnome_settings_daemon/plugins/background/active /apps/gnome_settings_daemon/plugins/background/active gnome-settings-daemon Index: plugins/Makefile.am =================================================================== --- plugins/Makefile.am.orig +++ plugins/Makefile.am @@ -2,6 +2,7 @@ NULL = enabled_plugins = \ a11y-keyboard \ + apport \ background \ clipboard \ datetime \ Index: plugins/apport/Makefile.am =================================================================== --- /dev/null +++ plugins/apport/Makefile.am @@ -0,0 +1,32 @@ +plugin_LTLIBRARIES = libapport.la + +libapport_la_SOURCES = \ + gsd-apport-manager.c \ + gsd-apport-manager.h \ + gsd-apport-plugin.c \ + gsd-apport-plugin.h + +libapport_la_CPPFLAGS = \ + -I$(top_srcdir)/gnome-settings-daemon \ + -DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libapport_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libapport_la_LDFLAGS = $(GSD_PLUGIN_LDFLAGS) + +libapport_la_LIBADD = $(SETTINGS_PLUGIN_LIBS) + +plugin_in_files = apport.gnome-settings-plugin.in + +plugin_DATA = $(plugin_in_files:.gnome-settings-plugin.in=.gnome-settings-plugin) + +EXTRA_DIST = $(plugin_in_files) + +CLEANFILES = $(plugin_DATA) + +DISTCLEANFILES = (plugin_DATA) + +@GSD_INTLTOOL_PLUGIN_RULE@ Index: plugins/apport/apport.gnome-settings-plugin.in =================================================================== --- /dev/null +++ plugins/apport/apport.gnome-settings-plugin.in @@ -0,0 +1,8 @@ +[GNOME Settings Plugin] +Module=apport +IAge=0 +_Name=Apport +_Description=Checks for new Apport crash reports and launches a handling application +Authors=Nikolay Derkach +Copyright=Copyright © 2008 Nikolay Derkach +Website= Index: plugins/apport/gsd-apport-manager.c =================================================================== --- /dev/null +++ plugins/apport/gsd-apport-manager.c @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2008 Nikolay Derkach + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +/* Some code was taken from update-notifier */ + +#include +#include +#include +#include +#include + +#include "gnome-settings-profile.h" +#include "gsd-apport-manager.h" + +#define GSD_APPORT_MANAGER_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_APPORT_MANAGER, \ + GsdApportManagerPrivate)) + +#define CRASHREPORT_REPORT_APP "apport-gtk" +#define CRASHREPORT_HELPER "apport-checkreports" + +struct GsdApportManagerPrivate { + GFileMonitor *monitor; + guint monitor_id; + GtkStatusIcon *ti; +}; + +static void gsd_apport_manager_class_init(GsdApportManagerClass *klass); +static void gsd_apport_manager_init(GsdApportManager *apport_manager); + +G_DEFINE_TYPE (GsdApportManager, gsd_apport_manager, G_TYPE_OBJECT) + +static gpointer manager_object = NULL; + + +static gboolean +run_apport (void) +{ + char *error_msg; + + gnome_settings_profile_msg ("fire up the crashreport tool"); + return g_spawn_command_line_async (CRASHREPORT_REPORT_APP, NULL); +} + +static void +hide_crash_applet (GtkStatusIcon *ti) +{ + gtk_status_icon_set_visible (ti, FALSE); +} + +static gboolean +crashreport_check (GtkStatusIcon *ti) +{ + gboolean crashreports_found; + static gboolean first_run = TRUE; + gboolean visible; + int exitcode; + + gnome_settings_profile_msg ("crashreport_check"); + + /* don't do anything if no apport-gtk is installed */ +// if (!g_file_test (CRASHREPORT_REPORT_APP, G_FILE_TEST_IS_EXECUTABLE)) +// return FALSE; + + /* check for (new) reports by calling CRASHREPORT_HELPER + and checking the return code */ + + if (!g_spawn_command_line_sync (CRASHREPORT_HELPER, NULL, NULL, + &exitcode, NULL)) { + g_warning ("Can not run %s\n", CRASHREPORT_HELPER); + return FALSE; + } + /* exitcode == 0: reports found, else no reports */ + crashreports_found = !exitcode ? TRUE : FALSE; + visible = gtk_status_icon_get_visible (ti); + + if (crashreports_found && first_run) { + gtk_status_icon_set_tooltip (ti, _("Crash report detected")); + gtk_status_icon_set_blinking (ti, TRUE); + gtk_status_icon_set_visible (ti, TRUE); + } + + /* crashreport found and already visible */ + if (crashreports_found && !first_run) { + run_apport (); + /* we don't care anymore and hide the icon */ + crashreports_found = FALSE; + } + + /* no crashreports, but visible */ + if (!crashreports_found && visible) { + hide_crash_applet (ti); + } + + first_run = FALSE; + return TRUE; +} + +static void +apport_watchdir_changed (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + gpointer user_data) +{ + GtkStatusIcon *ti = (GtkStatusIcon *)user_data; + if (event_type == G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED) { + gnome_settings_profile_msg ("G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED"); + crashreport_check (ti); + } +} + +static gboolean +button_release_cb (GtkStatusIcon *ti) +{ + run_apport (); + hide_crash_applet (ti); + return TRUE; +} + +static gboolean +trayapplet_create (GtkStatusIcon *ti, const char *name) +{ + /* setup widgets */ + ti = gtk_status_icon_new_from_icon_name (name); + gtk_status_icon_set_visible (ti, FALSE); + + g_signal_connect (ti, + "activate", + G_CALLBACK (button_release_cb), + ti); + + /* Check for crashes for the first time */ + crashreport_check (ti); + return TRUE; +} + +gboolean +gsd_apport_manager_start (GsdApportManager *manager, + GError **error) +{ + GFile *file; + GFileMonitor *m; + + gnome_settings_profile_start ("Starting apport manager"); + + /* crashreport detected icon */ + trayapplet_create (manager->priv->ti, "apport"); + + file = g_file_new_for_path (CRASHREPORT_DIR); + m = g_file_monitor_directory (file, 0, NULL, NULL); + g_object_unref (file); + + if (m) { + manager->priv->monitor_id = g_signal_connect (m, "changed", G_CALLBACK (apport_watchdir_changed), manager->priv->ti); + manager->priv->monitor = m; + } else + return FALSE; + + gnome_settings_profile_end (NULL); + return TRUE; +} + + +void +gsd_apport_manager_stop (GsdApportManager *manager) +{ + gnome_settings_profile_start ("Stopping apport manager"); + + g_signal_handler_disconnect (manager->priv->monitor, manager->priv->monitor_id); + g_file_monitor_cancel (manager->priv->monitor); + g_object_unref (manager->priv->monitor); + + gtk_widget_destroy ((GtkWidget *)manager->priv->ti); + gnome_settings_profile_end (NULL); +} + +static void +gsd_apport_manager_class_init (GsdApportManagerClass *klass) +{ + g_type_class_add_private (klass, sizeof (GsdApportManagerPrivate)); +} + + +static void +gsd_apport_manager_init (GsdApportManager *manager) +{ + manager->priv = GSD_APPORT_MANAGER_GET_PRIVATE (manager); +} + + +GsdApportManager * +gsd_apport_manager_new (void) +{ + if (manager_object != NULL) { + g_object_ref (manager_object); + } else { + manager_object = g_object_new (GSD_TYPE_APPORT_MANAGER, NULL); + g_object_add_weak_pointer (manager_object, + (gpointer *) &manager_object); + } + + return GSD_APPORT_MANAGER (manager_object); +} Index: plugins/apport/gsd-apport-manager.h =================================================================== --- /dev/null +++ plugins/apport/gsd-apport-manager.h @@ -0,0 +1,58 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Nikolay Derkach + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef __GSD_APPORT_MANAGER_H +#define __GSD_APPORT_MANAGER_H + +#include +#include + +G_BEGIN_DECLS + +#define GSD_TYPE_APPORT_MANAGER (gsd_apport_manager_get_type ()) +#define GSD_APPORT_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_APPORT_MANAGER, GsdApportManager)) +#define GSD_APPORT_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_APPORT_MANAGER, GsdApportManagerClass)) +#define GSD_IS_APPORT_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_APPORT_MANAGER)) +#define GSD_IS_APPORT_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_APPORT_MANAGER)) +#define GSD_APPORT_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_APPORT_MANAGER, GsdApportManagerClass)) + +#define CRASHREPORT_DIR "/var/crash/" + +typedef struct GsdApportManagerPrivate GsdApportManagerPrivate; + +typedef struct { + GObject parent; + GsdApportManagerPrivate *priv; +} GsdApportManager; + +typedef struct { + GObjectClass parent_class; +} GsdApportManagerClass; + +GType gsd_apport_manager_get_type (void); + +GsdApportManager* gsd_apport_manager_new (void); +gboolean gsd_apport_manager_start (GsdApportManager *manager, + GError **error); +void gsd_apport_manager_stop (GsdApportManager *manager); + +G_END_DECLS + +#endif /* __GSD_APPORT_MANAGER_H */ Index: plugins/apport/gsd-apport-plugin.c =================================================================== --- /dev/null +++ plugins/apport/gsd-apport-plugin.c @@ -0,0 +1,104 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Nikolay Derkach + * + * This program 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 2, or (at your option) + * any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include "config.h" + +#include +#include + +#include "gnome-settings-plugin.h" +#include "gsd-apport-plugin.h" +#include "gsd-apport-manager.h" + +struct GsdApportPluginPrivate { + GsdApportManager *manager; +}; + +#define GSD_APPORT_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSD_TYPE_APPORT_PLUGIN, GsdApportPluginPrivate)) + +GNOME_SETTINGS_PLUGIN_REGISTER (GsdApportPlugin, gsd_apport_plugin) + +static void +gsd_apport_plugin_init (GsdApportPlugin *plugin) +{ + plugin->priv = GSD_APPORT_PLUGIN_GET_PRIVATE (plugin); + + g_debug ("GsdApportPlugin initializing"); + + plugin->priv->manager = gsd_apport_manager_new (); +} + +static void +gsd_apport_plugin_finalize (GObject *object) +{ + GsdApportPlugin *plugin; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_APPORT_PLUGIN (object)); + + g_debug ("GsdApportPlugin finalizing"); + + plugin = GSD_APPORT_PLUGIN (object); + + g_return_if_fail (plugin->priv != NULL); + + if (plugin->priv->manager != NULL) { + g_object_unref (plugin->priv->manager); + } + + G_OBJECT_CLASS (gsd_apport_plugin_parent_class)->finalize (object); +} + +static void +impl_activate (GnomeSettingsPlugin *plugin) +{ + gboolean res; + GError *error; + + g_debug ("Activating apport plugin"); + + error = NULL; + res = gsd_apport_manager_start (GSD_APPORT_PLUGIN (plugin)->priv->manager, &error); + if (! res) { + g_warning ("Unable to start apport manager: %s", error->message); + g_error_free (error); + } +} + +static void +impl_deactivate (GnomeSettingsPlugin *plugin) +{ + g_debug ("Deactivating apport plugin"); + gsd_apport_manager_stop (GSD_APPORT_PLUGIN (plugin)->priv->manager); +} + +static void +gsd_apport_plugin_class_init (GsdApportPluginClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GnomeSettingsPluginClass *plugin_class = GNOME_SETTINGS_PLUGIN_CLASS (klass); + + object_class->finalize = gsd_apport_plugin_finalize; + + plugin_class->activate = impl_activate; + plugin_class->deactivate = impl_deactivate; + + g_type_class_add_private (klass, sizeof (GsdApportPluginPrivate)); +} Index: plugins/apport/gsd-apport-plugin.h =================================================================== --- /dev/null +++ plugins/apport/gsd-apport-plugin.h @@ -0,0 +1,57 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Nikolay Derkach + * + * This program 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 2, or (at your option) + * any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef __GSD_APPORT_PLUGIN_H__ +#define __GSD_APPORT_PLUGIN_H__ + +#include +#include +#include + +#include "gnome-settings-plugin.h" + +G_BEGIN_DECLS + +#define GSD_TYPE_APPORT_PLUGIN (gsd_apport_plugin_get_type ()) +#define GSD_APPORT_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_APPORT_PLUGIN, GsdApportPlugin)) +#define GSD_APPORT_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_APPORT_PLUGIN, GsdApportPluginClass)) +#define GSD_IS_APPORT_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_APPORT_PLUGIN)) +#define GSD_IS_APPORT_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_APPORT_PLUGIN)) +#define GSD_APPORT_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_APPORT_PLUGIN, GsdApportPluginClass)) + +typedef struct GsdApportPluginPrivate GsdApportPluginPrivate; + +typedef struct { + GnomeSettingsPlugin parent; + GsdApportPluginPrivate *priv; +} GsdApportPlugin; + +typedef struct { + GnomeSettingsPluginClass parent_class; +} GsdApportPluginClass; + +GType gsd_apport_plugin_get_type (void) G_GNUC_CONST; + +/* All the plugins must implement this function */ +G_MODULE_EXPORT GType register_gnome_settings_plugin (GTypeModule *module); + +G_END_DECLS + +#endif /* __GSD_APPORT_PLUGIN_H__ */