From 5e979044ddae3f2e9d31f480dd103bfb0fa7103b Mon Sep 17 00:00:00 2001 From: Andy Spencer Date: Tue, 26 May 2009 02:02:35 +0000 Subject: [PATCH] destructors, still need to free data in plugins though --- TODO | 6 +++++ data/main.glade | 4 ++-- src/Makefile.am | 2 +- src/aweather-gui.c | 54 +++++++++++++++++++++++++++++++++----------- src/aweather-view.c | 22 ++++-------------- src/main.c | 6 ++--- src/plugin-example.c | 30 ++++++++++++++++++++---- src/plugin-radar.c | 30 ++++++++++++++++++++---- src/plugin-ridge.c | 30 ++++++++++++++++++++---- 9 files changed, 135 insertions(+), 49 deletions(-) diff --git a/TODO b/TODO index 613f2bc..bad23e9 100644 --- a/TODO +++ b/TODO @@ -4,6 +4,12 @@ Road plan * Fix all memory leaks * Pre-load textures and polys in OpenGL +0.x - Misc + * Resume downloads (back to CURL/Soup) + * Configuration file + * Default site + * Keybindings? + 0.x - Volume scans * Display iso surfaces of volume scans diff --git a/data/main.glade b/data/main.glade index bc8daa6..2fa73b4 100644 --- a/data/main.glade +++ b/data/main.glade @@ -1,6 +1,6 @@ - + @@ -60,7 +60,7 @@ gtk-quit True True - + diff --git a/src/Makefile.am b/src/Makefile.am index 1721d9f..10c83f0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,7 +42,7 @@ memcheck: G_DEBUG=gc-friendly,resident-modules \ valgrind --leak-check=full \ --leak-resolution=high \ - --num-callers=50 \ + --num-callers=100 \ --suppressions=gtk.suppression \ ./aweather \ 2> valgrind.out diff --git a/src/aweather-gui.c b/src/aweather-gui.c index c21471f..2e44b91 100644 --- a/src/aweather-gui.c +++ b/src/aweather-gui.c @@ -48,14 +48,33 @@ static void aweather_gui_dispose(GObject *gobject) { g_debug("AWeatherGui: dispose"); AWeatherGui *gui = AWEATHER_GUI(gobject); - g_object_unref(gui->view ); - g_object_unref(gui->builder); + if (gui->view) { + g_object_unref(gui->view); + gui->view = NULL; + } + if (gui->builder) { + /* Reparent to avoid double unrefs */ + GtkWidget *body = aweather_gui_get_widget(gui, "body"); + GtkWidget *window = aweather_gui_get_widget(gui, "window"); + gtk_widget_reparent(body, window); + g_object_unref(gui->builder); + gui->builder = NULL; + } + if (gui->plugins) { + g_list_foreach(gui->plugins, (GFunc)g_object_unref, NULL); + g_list_free(gui->plugins); + gui->plugins = NULL; + } + //for (GList *cur = gui->plugins; cur; cur = cur->next) + // g_object_unref(cur->data); G_OBJECT_CLASS(aweather_gui_parent_class)->dispose(gobject); } static void aweather_gui_finalize(GObject *gobject) { g_debug("AWeatherGui: finalize"); G_OBJECT_CLASS(aweather_gui_parent_class)->finalize(gobject); + gtk_main_quit(); + } static void aweather_gui_class_init(AWeatherGuiClass *klass) { @@ -69,6 +88,10 @@ static void aweather_gui_class_init(AWeatherGuiClass *klass) /************* * Callbacks * *************/ +void on_quit(GtkMenuItem *menu, AWeatherGui *gui) +{ + gtk_widget_destroy(GTK_WIDGET(gui)); +} gboolean on_drawing_button_press(GtkWidget *widget, GdkEventButton *event, AWeatherGui *gui) { g_debug("AWeatherGui: on_drawing_button_press - Grabbing focus"); @@ -78,25 +101,28 @@ gboolean on_drawing_button_press(GtkWidget *widget, GdkEventButton *event, AWeat } gboolean on_drawing_key_press(GtkWidget *widget, GdkEventKey *event, AWeatherGui *gui) { - g_debug("AWeatherGui: on_drawing_key_press - key=%x, state=%x", event->keyval, event->state); + g_debug("AWeatherGui: on_drawing_key_press - key=%x, state=%x", + event->keyval, event->state); AWeatherView *view = aweather_gui_get_view(gui); double x,y,z; aweather_view_get_location(view, &x, &y, &z); - if (event->keyval == GDK_Right) aweather_view_pan(view, z/10, 0, 0); - else if (event->keyval == GDK_Left) aweather_view_pan(view, -z/10, 0, 0); - else if (event->keyval == GDK_Up) aweather_view_pan(view, 0, z/10, 0); - else if (event->keyval == GDK_Down) aweather_view_pan(view, 0, -z/10, 0); - else if (event->keyval == GDK_minus) aweather_view_zoom(view, 10./9); - else if (event->keyval == GDK_plus) aweather_view_zoom(view, 9./10); + guint kv = event->keyval; + if (kv == GDK_Right || kv == GDK_l) aweather_view_pan(view, z/10, 0, 0); + else if (kv == GDK_Left || kv == GDK_h) aweather_view_pan(view, -z/10, 0, 0); + else if (kv == GDK_Up || kv == GDK_k) aweather_view_pan(view, 0, z/10, 0); + else if (kv == GDK_Down || kv == GDK_j) aweather_view_pan(view, 0, -z/10, 0); + else if (kv == GDK_minus || kv == GDK_o) aweather_view_zoom(view, 10./9); + else if (kv == GDK_plus || kv == GDK_i) aweather_view_zoom(view, 9./10); return TRUE; } gboolean on_gui_key_press(GtkWidget *widget, GdkEventKey *event, AWeatherGui *gui) { - g_debug("AWeatherGui: on_gui_key_press - key=%x, state=%x", event->keyval, event->state); + g_debug("AWeatherGui: on_gui_key_press - key=%x, state=%x", + event->keyval, event->state); AWeatherView *view = aweather_gui_get_view(gui); if (event->keyval == GDK_q) - gtk_main_quit(); + gtk_widget_destroy(GTK_WIDGET(gui)); else if (event->keyval == GDK_r && event->state & GDK_CONTROL_MASK) aweather_view_refresh(view); else if (event->keyval == GDK_Tab || event->keyval == GDK_ISO_Left_Tab) { @@ -236,6 +262,7 @@ gboolean on_expose(GtkWidget *da, GdkEventExpose *event, AWeatherGui *gui) void on_about(GtkMenuItem *item, AWeatherGui *gui) { + // TODO: use gtk_widget_hide_on_delete() GError *error = NULL; GtkBuilder *builder = gtk_builder_new(); if (!gtk_builder_add_from_file(builder, DATADIR "/aweather/about.xml", &error)) @@ -400,8 +427,7 @@ AWeatherGui *aweather_gui_new() if (!gtk_builder_add_from_file(self->builder, DATADIR "/aweather/main.xml", &error)) g_error("Failed to create gtk builder: %s", error->message); gtk_builder_connect_signals(self->builder, self); - g_signal_connect(self, "delete-event", G_CALLBACK(gtk_main_quit), self); - g_signal_connect(self, "key-press-event", G_CALLBACK(on_gui_key_press), self); + g_signal_connect(self, "key-press-event", G_CALLBACK(on_gui_key_press), self); gtk_widget_reparent(aweather_gui_get_widget(self, "body"), GTK_WIDGET(self)); /* Load components */ @@ -419,11 +445,13 @@ AWeatherView *aweather_gui_get_view(AWeatherGui *gui) } GtkBuilder *aweather_gui_get_builder(AWeatherGui *gui) { + g_debug("AWeatherGui: get_builder"); g_assert(AWEATHER_IS_GUI(gui)); return gui->builder; } GtkWidget *aweather_gui_get_widget(AWeatherGui *gui, const gchar *name) { + g_debug("AWeatherGui: get_widget - name=%s", name); g_assert(AWEATHER_IS_GUI(gui)); GObject *widget = gtk_builder_get_object(gui->builder, name); if (!GTK_IS_WIDGET(widget)) diff --git a/src/aweather-view.c b/src/aweather-view.c index 627824f..96f9fed 100644 --- a/src/aweather-view.c +++ b/src/aweather-view.c @@ -23,14 +23,12 @@ /**************** * GObject code * ****************/ -G_DEFINE_TYPE(AWeatherView, aweather_view, G_TYPE_OBJECT); - +/* Constants */ enum { PROP_0, PROP_TIME, PROP_SITE, }; - enum { SIG_TIME_CHANGED, SIG_SITE_CHANGED, @@ -38,9 +36,10 @@ enum { SIG_REFRESH, NUM_SIGNALS, }; - static guint signals[NUM_SIGNALS]; +/* Class/Object init */ +G_DEFINE_TYPE(AWeatherView, aweather_view, G_TYPE_OBJECT); static void aweather_view_init(AWeatherView *self) { g_debug("AWeatherView: init"); @@ -48,30 +47,20 @@ static void aweather_view_init(AWeatherView *self) self->time = g_strdup(""); self->site = g_strdup(""); } - -static GObject *aweather_view_constructor(GType gtype, guint n_properties, - GObjectConstructParam *properties) -{ - g_debug("AWeatherView: constructor"); - GObjectClass *parent_class = G_OBJECT_CLASS(aweather_view_parent_class); - return parent_class->constructor(gtype, n_properties, properties); -} - static void aweather_view_dispose(GObject *gobject) { g_debug("AWeatherView: dispose"); /* Drop references to other GObjects */ G_OBJECT_CLASS(aweather_view_parent_class)->dispose(gobject); } - static void aweather_view_finalize(GObject *gobject) { g_debug("AWeatherView: finalize"); AWeatherView *self = AWEATHER_VIEW(gobject); + g_free(self->time); g_free(self->site); G_OBJECT_CLASS(aweather_view_parent_class)->finalize(gobject); } - static void aweather_view_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { @@ -83,7 +72,6 @@ static void aweather_view_set_property(GObject *object, guint property_id, default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); } } - static void aweather_view_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { @@ -95,12 +83,10 @@ static void aweather_view_get_property(GObject *object, guint property_id, default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); } } - static void aweather_view_class_init(AWeatherViewClass *klass) { g_debug("AWeatherView: class_init"); GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - gobject_class->constructor = aweather_view_constructor; gobject_class->dispose = aweather_view_dispose; gobject_class->finalize = aweather_view_finalize; gobject_class->get_property = aweather_view_get_property; diff --git a/src/main.c b/src/main.c index d1b13b3..cdd97e6 100644 --- a/src/main.c +++ b/src/main.c @@ -79,9 +79,9 @@ int main(int argc, char *argv[]) g_signal_connect(gui, "map-event", G_CALLBACK(on_map), opt_site); /* Load plugins */ - aweather_gui_register_plugin(gui, AWEATHER_PLUGIN(aweather_example_new(gui))); - aweather_gui_register_plugin(gui, AWEATHER_PLUGIN(aweather_ridge_new(gui))); - aweather_gui_register_plugin(gui, AWEATHER_PLUGIN(aweather_radar_new(gui))); + //aweather_gui_register_plugin(gui, AWEATHER_PLUGIN(aweather_example_new(gui))); + //aweather_gui_register_plugin(gui, AWEATHER_PLUGIN(aweather_ridge_new(gui))); + //aweather_gui_register_plugin(gui, AWEATHER_PLUGIN(aweather_radar_new(gui))); gtk_widget_show_all(GTK_WIDGET(gui)); gtk_main(); diff --git a/src/plugin-example.c b/src/plugin-example.c index 4060642..f2ae95e 100644 --- a/src/plugin-example.c +++ b/src/plugin-example.c @@ -26,27 +26,49 @@ /**************** * GObject code * ****************/ +/* Plugin init */ static void aweather_example_plugin_init(AWeatherPluginInterface *iface); static void aweather_example_expose(AWeatherPlugin *_example); G_DEFINE_TYPE_WITH_CODE(AWeatherExample, aweather_example, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(AWEATHER_TYPE_PLUGIN, aweather_example_plugin_init)); -static void aweather_example_class_init(AWeatherExampleClass *klass) -{ - GObjectClass *object_class = (GObjectClass*)klass; -} static void aweather_example_plugin_init(AWeatherPluginInterface *iface) { + g_debug("AWeatherExample: plugin_init"); /* Add methods to the interface */ iface->expose = aweather_example_expose; } +/* Class/Object init */ static void aweather_example_init(AWeatherExample *example) { + g_debug("AWeatherExample: init"); /* Set defaults */ example->gui = NULL; example->button = NULL; example->rotation = 30.0; } +static void aweather_example_dispose(GObject *gobject) +{ + g_debug("AWeatherExample: dispose"); + AWeatherExample *self = AWEATHER_EXAMPLE(gobject); + /* Drop references */ + G_OBJECT_CLASS(aweather_example_parent_class)->dispose(gobject); +} +static void aweather_example_finalize(GObject *gobject) +{ + g_debug("AWeatherExample: finalize"); + AWeatherExample *self = AWEATHER_EXAMPLE(gobject); + /* Free data */ + G_OBJECT_CLASS(aweather_example_parent_class)->finalize(gobject); + +} +static void aweather_example_class_init(AWeatherExampleClass *klass) +{ + g_debug("AWeatherExample: class_init"); + GObjectClass *gobject_class = (GObjectClass*)klass; + gobject_class->dispose = aweather_example_dispose; + gobject_class->finalize = aweather_example_finalize; +} /*********** * Helpers * diff --git a/src/plugin-radar.c b/src/plugin-radar.c index e17d5a2..1d4706e 100644 --- a/src/plugin-radar.c +++ b/src/plugin-radar.c @@ -29,25 +29,47 @@ /**************** * GObject code * ****************/ +/* Plugin init */ static void aweather_radar_plugin_init(AWeatherPluginInterface *iface); static void _aweather_radar_expose(AWeatherPlugin *_radar); G_DEFINE_TYPE_WITH_CODE(AWeatherRadar, aweather_radar, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(AWEATHER_TYPE_PLUGIN, aweather_radar_plugin_init)); -static void aweather_radar_class_init(AWeatherRadarClass *klass) -{ - GObjectClass *object_class = (GObjectClass*)klass; -} static void aweather_radar_plugin_init(AWeatherPluginInterface *iface) { + g_debug("AWeatherRadar: plugin_init"); /* Add methods to the interface */ iface->expose = _aweather_radar_expose; } +/* Class/Object init */ static void aweather_radar_init(AWeatherRadar *radar) { + g_debug("AWeatherRadar: class_init"); /* Set defaults */ radar->gui = NULL; } +static void aweather_radar_dispose(GObject *gobject) +{ + g_debug("AWeatherRadar: dispose"); + AWeatherRadar *self = AWEATHER_RADAR(gobject); + /* Drop references */ + G_OBJECT_CLASS(aweather_radar_parent_class)->dispose(gobject); +} +static void aweather_radar_finalize(GObject *gobject) +{ + g_debug("AWeatherRadar: finalize"); + AWeatherRadar *self = AWEATHER_RADAR(gobject); + /* Free data */ + G_OBJECT_CLASS(aweather_radar_parent_class)->finalize(gobject); + +} +static void aweather_radar_class_init(AWeatherRadarClass *klass) +{ + g_debug("AWeatherRadar: class_init"); + GObjectClass *gobject_class = (GObjectClass*)klass; + gobject_class->dispose = aweather_radar_dispose; + gobject_class->finalize = aweather_radar_finalize; +} /************************** * Data loading functions * diff --git a/src/plugin-ridge.c b/src/plugin-ridge.c index 646878c..90ad4d1 100644 --- a/src/plugin-ridge.c +++ b/src/plugin-ridge.c @@ -29,25 +29,47 @@ /**************** * GObject code * ****************/ +/* Plugin init */ static void aweather_ridge_plugin_init(AWeatherPluginInterface *iface); static void aweather_ridge_expose(AWeatherPlugin *_ridge); G_DEFINE_TYPE_WITH_CODE(AWeatherRidge, aweather_ridge, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(AWEATHER_TYPE_PLUGIN, aweather_ridge_plugin_init)); -static void aweather_ridge_class_init(AWeatherRidgeClass *klass) -{ - GObjectClass *object_class = (GObjectClass*)klass; -} static void aweather_ridge_plugin_init(AWeatherPluginInterface *iface) { + g_debug("AWeatherRidge: plugin_init"); /* Add methods to the interface */ iface->expose = aweather_ridge_expose; } +/* Class/Object init */ static void aweather_ridge_init(AWeatherRidge *ridge) { + g_debug("AWeatherRidge: init"); /* Set defaults */ ridge->gui = NULL; } +static void aweather_ridge_dispose(GObject *gobject) +{ + g_debug("AWeatherRidge: dispose"); + AWeatherRidge *self = AWEATHER_RIDGE(gobject); + /* Drop references */ + G_OBJECT_CLASS(aweather_ridge_parent_class)->dispose(gobject); +} +static void aweather_ridge_finalize(GObject *gobject) +{ + g_debug("AWeatherRidge: finalize"); + AWeatherRidge *self = AWEATHER_RIDGE(gobject); + /* Free data */ + G_OBJECT_CLASS(aweather_ridge_parent_class)->finalize(gobject); + +} +static void aweather_ridge_class_init(AWeatherRidgeClass *klass) +{ + g_debug("AWeatherRidge: class_init"); + GObjectClass *gobject_class = (GObjectClass*)klass; + gobject_class->dispose = aweather_ridge_dispose; + gobject_class->finalize = aweather_ridge_finalize; +} /********************* * Overlay constants * -- 2.43.2