]> Pileus Git - aweather/commitdiff
Miscellaneous bug fixes
authorAndy Spencer <andy753421@gmail.com>
Sat, 1 May 2010 08:00:31 +0000 (08:00 +0000)
committerAndy Spencer <andy753421@gmail.com>
Sat, 1 May 2010 08:00:31 +0000 (08:00 +0000)
- Lots of plugged memory leaks
- Lots of small improvements

data/main.ui.in
src/aweather-gui.c
src/aweather-location.c
src/main.c
src/plugins/level2.c
src/plugins/radar.c
src/plugins/radar.h

index eb543bd7ebdd530241da891fad1288b5e800fa47..4588d3a959a9ff751712d9c4d693d40e38b5e625 100644 (file)
       <column type="gint"/>
     </columns>
   </object>
+  <object class="GtkTreeStore" id="sites">
+    <columns>
+      <!-- column-name code -->
+      <column type="gchararray"/>
+      <!-- column-name name -->
+      <column type="gchararray"/>
+    </columns>
+  </object>
   <object class="GtkWindow" id="main_window">
     <property name="title" translatable="yes">AWeather</property>
     <child>
                                 <child>
                                   <object class="GtkComboBox" id="prefs_general_site">
                                     <property name="visible">True</property>
+                                    <property name="model">sites</property>
                                     <signal name="changed" handler="on_initial_site_changed"/>
                                     <child>
                                       <object class="GtkCellRendererText" id="prefs_general_site_rend"/>
                                       <attributes>
-                                        <attribute name="text">0</attribute>
+                                        <attribute name="text">1</attribute>
                                       </attributes>
                                     </child>
                                   </object>
@@ -893,9 +902,9 @@ The hypothetical commands `show w' and `show c' should show the appropriate part
   </object>
   <object class="GtkSizeGroup" id="prefs_general_size">
     <widgets>
-      <widget name="prefs_general_site_label"/>
-      <widget name="prefs_general_url_label"/>
       <widget name="prefs_general_log_label"/>
+      <widget name="prefs_general_url_label"/>
+      <widget name="prefs_general_site_label"/>
     </widgets>
   </object>
   <object class="GtkAdjustment" id="prefs_general_log_adj">
index 50f4f60013baa29eecbde4a43acba789c69e39f4..90b1d76e7b79661d430a8f44d6a5d5e63ca66a5a 100644 (file)
@@ -153,6 +153,18 @@ void on_offline(GtkToggleAction *action, AWeatherGui *self)
        gis_viewer_set_offline(self->viewer, value);
 }
 
+void on_initial_site_changed(GtkComboBox *combo, AWeatherGui *self)
+{
+       gchar *code;
+       GtkTreeIter iter;
+       GtkTreeModel *model = gtk_combo_box_get_model(combo);
+       gtk_combo_box_get_active_iter(combo, &iter);
+       gtk_tree_model_get(model, &iter, 0, &code, -1);
+       g_debug("AWeatherGui: on_initial_site_changed - code=%s", code);
+       gis_prefs_set_string(self->prefs, "aweather/initial_site", code);
+       g_free(code);
+}
+
 void on_nexrad_url_changed(GtkEntry *entry, AWeatherGui *self)
 {
        const gchar *text = gtk_entry_get_text(entry);
@@ -172,6 +184,34 @@ int on_log_level_changed(GtkSpinButton *spinner, AWeatherGui *self)
 /*****************
  * Setup helpers *
  *****************/
+static void combo_sensitive(GtkCellLayout *cell_layout, GtkCellRenderer *cell,
+               GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)
+{
+       gboolean sensitive = !gtk_tree_model_iter_has_child(tree_model, iter);
+       g_object_set(cell, "sensitive", sensitive, NULL);
+}
+static void site_setup(AWeatherGui *self)
+{
+       GtkTreeIter state, city;
+       GtkTreeStore *store = GTK_TREE_STORE(aweather_gui_get_object(self, "sites"));
+       for (int i = 0; cities[i].type; i++) {
+               if (cities[i].type == LOCATION_STATE) {
+                       gtk_tree_store_append(store, &state, NULL);
+                       gtk_tree_store_set   (store, &state, 0, cities[i].code,
+                                                            1, cities[i].name, -1);
+               } else {
+                       gtk_tree_store_append(store, &city, &state);
+                       gtk_tree_store_set   (store, &city, 0, cities[i].code,
+                                                           1, cities[i].name, -1);
+               }
+       }
+
+       GtkWidget *combo    = aweather_gui_get_widget(self, "prefs_general_site");
+       GObject   *renderer = aweather_gui_get_object(self, "prefs_general_site_rend");
+       gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(combo),
+                       GTK_CELL_RENDERER(renderer), combo_sensitive, NULL, NULL);
+}
+
 static void prefs_setup(AWeatherGui *self)
 {
        /* Set values */
@@ -186,7 +226,7 @@ static void prefs_setup(AWeatherGui *self)
        if (is) {
                GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(isw));
                GtkTreeIter iter;
-               if (gtk_tree_model_find_string(model, &iter, NULL, 1, is))
+               if (gtk_tree_model_find_string(model, &iter, NULL, 0, is))
                        gtk_combo_box_set_active_iter(GTK_COMBO_BOX(isw), &iter);
        }
 
@@ -205,13 +245,6 @@ static void prefs_setup(AWeatherGui *self)
        gtk_tree_view_set_model(GTK_TREE_VIEW(tview), GTK_TREE_MODEL(self->gtk_plugins));
 }
 
-static void combo_sensitive(GtkCellLayout *cell_layout, GtkCellRenderer *cell,
-               GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)
-{
-       gboolean sensitive = !gtk_tree_model_iter_has_child(tree_model, iter);
-       g_object_set(cell, "sensitive", sensitive, NULL);
-}
-
 static void time_setup(AWeatherGui *self)
 {
        /* Setup UI */
@@ -355,6 +388,7 @@ static void aweather_gui_init(AWeatherGui *self)
        }
 
        /* Misc, helpers */
+       site_setup(self);
        time_setup(self);
        prefs_setup(self);
 
@@ -377,22 +411,14 @@ static void aweather_gui_dispose(GObject *_self)
 {
        g_debug("AWeatherGui: dispose");
        AWeatherGui *self = AWEATHER_GUI(_self);
-       if (self->builder) {
-               /* Reparent to avoid double unrefs */
-               GtkWidget *body   = aweather_gui_get_widget(self, "main_body");
-               GtkWidget *window = aweather_gui_get_widget(self, "main_window");
-               gtk_widget_reparent(body, window);
-               g_object_unref(self->builder);
-               self->builder = NULL;
-       }
-       if (self->viewer) {
-               g_object_unref(self->viewer);
-               self->viewer = NULL;
-       }
        if (self->plugins) {
                gis_plugins_free(self->plugins);
                self->plugins = NULL;
        }
+       if (self->builder) {
+               g_object_unref(self->builder);
+               self->builder = NULL;
+       }
        if (self->prefs) {
                g_object_unref(self->prefs);
                self->prefs = NULL;
index 15c3b8711558423d23e4d7594456810ad93f691b..6119e906fe570ef80ccf7e2ee8d11fc7f3c88be3 100644 (file)
@@ -150,7 +150,7 @@ city_t cities[] = {
        {LOCATION_CITY,  "KRTX", "Portland",          {45.714,  -122.966, 0}, 0.8},
        {LOCATION_STATE, NULL,   "Pennsylvania",      {0,        0,       0}, 0.0},
        {LOCATION_CITY,  "KCCX", "State College",     {40.923,  -78.0036, 0}, 0.3},
-       {LOCATION_CITY,  "KDIX", "Philadelphia",      {39.946,  -74.4108, 0}, 0.3},
+       {LOCATION_CITY,  "KPHI", "Philadelphia",      {39.946,  -74.4108, 0}, 0.3},
        {LOCATION_CITY,  "KPBZ", "Pittsburgh",        {40.531,  -80.2183, 0}, 0.5},
        {LOCATION_STATE, NULL,   "South Carolina",    {0,        0,       0}, 0.0},
        {LOCATION_CITY,  "KCAE", "Columbia",          {33.948,  -81.1183, 0}, 0.5},
@@ -185,12 +185,9 @@ city_t cities[] = {
        {LOCATION_STATE, NULL,   "Virginia",          {0,        0,       0}, 0.0},
        {LOCATION_CITY,  "KAKQ", "Richmond",          {36.983,  -77.0072, 0}, 0.5},
        {LOCATION_CITY,  "KFCX", "Blacksburg",        {37.024,  -80.2739, 0}, 0.3},
-       {LOCATION_CITY,  "KLWX", "Sterling",          {38.975,  -77.4778, 0}, 0.3},
        {LOCATION_STATE, NULL,   "Washington",        {0,        0,       0}, 0.0},
        {LOCATION_CITY,  "KATX", "Seattle",           {48.194,  -122.496, 0}, 1.5},
        {LOCATION_CITY,  "KOTX", "Spokane",           {47.680,  -117.627, 0}, 0.5},
-       {LOCATION_STATE, NULL,   "Washington DC",     {0,        0,       0}, 0.0},
-       {LOCATION_CITY,  "KLWX", "Washington",        {38.975,  -77.4778, 0}, 0.3},
        {LOCATION_STATE, NULL,   "West Virginia",     {0,        0,       0}, 0.0},
        {LOCATION_CITY,  "KRLX", "Charleston",        {38.311,  -81.7231, 0}, 0.5},
        {LOCATION_STATE, NULL,   "Wisconsin",         {0,        0,       0}, 0.0},
index cb8568e5711d4811ae3c867d0a0348e365a35fe0..5f664aa5b78c5f00f65d259c3b30b6af10f170e2 100644 (file)
@@ -46,6 +46,20 @@ static void on_log_level_changed(GtkSpinButton *spinner, AWeatherGui *self)
        log_levels = (1 << (value+1))-1;
 }
 
+gboolean set_location(gpointer _gui)
+{
+       AWeatherGui *gui = _gui;
+       gchar *site = g_object_get_data(G_OBJECT(gui), "site");
+       for (city_t *city = cities; city->type; city++) {
+               if (city->type == LOCATION_CITY && g_str_equal(city->code, site)) {
+                       gis_viewer_set_location(gui->viewer,
+                               city->pos.lat, city->pos.lon, EARTH_R/25);
+                       break;
+               }
+       }
+       return FALSE;
+}
+
 
 /********
  * Main *
@@ -105,16 +119,12 @@ int main(int argc, char *argv[])
        GObject *action = aweather_gui_get_object(gui, "prefs_general_log");
        g_signal_connect(action, "changed", G_CALLBACK(on_log_level_changed), NULL);
 
-       /* set locaiton */
-       for (city_t *city = cities; city->type; city++)
-               if (city->type == LOCATION_CITY && g_str_equal(city->code, site)) {
-                       gis_viewer_set_location(gui->viewer,
-                               city->pos.lat, city->pos.lon, EARTH_R/25);
-                       break;
-               }
+       g_object_set_data(G_OBJECT(gui), "site", site);
+       g_idle_add(set_location, gui);
 
        gtk_widget_show_all(GTK_WIDGET(gui));
        gtk_main();
        gdk_threads_leave();
+       gdk_display_close(gdk_display_get_default());
        return 0;
 }
index f01f8031976a2103f9ad21eab57d3396f4ac2a47..5156b70065a9f794672ec5a6125e4d0acd8fbf6d 100644 (file)
@@ -74,7 +74,6 @@ static void _load_sweep_gl(Sweep *sweep, AWeatherColormap *colormap, guint *tex)
        int height, width;
        guint8 *data;
        _bscan_sweep(sweep, colormap, &data, &width, &height);
-       glGenTextures(1, tex);
        glBindTexture(GL_TEXTURE_2D, *tex);
        glPixelStorei(GL_PACK_ALIGNMENT, 1);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@@ -145,7 +144,6 @@ static void _draw_radar(GisCallback *_self, gpointer _viewer)
 
        /* Draw the rays */
        glBindTexture(GL_TEXTURE_2D, self->sweep_tex);
-       g_message("Tex = %d", self->sweep_tex);
        glBegin(GL_TRIANGLE_STRIP);
        for (int ri = 0; ri <= sweep->h.nrays; ri++) {
                Ray  *ray = NULL;
@@ -196,8 +194,8 @@ static gboolean _set_sweep_cb(gpointer _self)
 {
        g_debug("AWeatherLevel2: _set_sweep_cb");
        AWeatherLevel2 *self = _self;
-       if (self->sweep_tex)
-               glDeleteTextures(1, &self->sweep_tex);
+       if (!self->sweep_tex)
+                glGenTextures(1, &self->sweep_tex);
        _load_sweep_gl(self->sweep, self->sweep_colors, &self->sweep_tex);
        gtk_widget_queue_draw(GTK_WIDGET(self->viewer));
        g_object_unref(self);
@@ -370,7 +368,11 @@ static void aweather_level2_dispose(GObject *_self)
 }
 static void aweather_level2_finalize(GObject *_self)
 {
+       AWeatherLevel2 *self = AWEATHER_LEVEL2(_self);
        g_debug("AWeatherLevel2: finalize - %p", _self);
+       RSL_free_radar(self->radar);
+       if (self->sweep_tex)
+               glDeleteTextures(1, &self->sweep_tex);
        G_OBJECT_CLASS(aweather_level2_parent_class)->finalize(_self);
 }
 static void aweather_level2_class_init(AWeatherLevel2Class *klass)
index 55b8889d3f9454375ccced7ef99067225de5ccc0..75fc3783de71e9399ec75d570ae9f40ab7ef8f80 100644 (file)
@@ -44,14 +44,13 @@ void _gtk_bin_set_child(GtkBin *bin, GtkWidget *new)
 static gchar *_find_nearest(time_t time, GList *files,
                gsize offset, gchar *format)
 {
-       g_debug("GisPluginRadar: _find_nearest");
+       g_debug("GisPluginRadar: _find_nearest ...");
        time_t  nearest_time = 0;
        char   *nearest_file = NULL;
 
        struct tm tm = {};
        for (GList *cur = files; cur; cur = cur->next) {
                gchar *file = cur->data;
-               g_message("file=%s", file);
                strptime(file+offset, format, &tm);
                if (ABS(time - mktime(&tm)) <
                    ABS(time - nearest_time)) {
@@ -78,10 +77,9 @@ typedef enum {
 } RadarSiteStatus;
 struct _RadarSite {
        /* Information */
-       gchar     *code;   // Site name. e.g. KLSX
-       gchar     *name;   // Site name. e.g. St. Louis
-       GisPoint   pos;    // LLE positions of antena 
-       GisMarker *marker; // Map marker for libgis
+       city_t    *city;
+       GisMarker *marker;     // Map marker for libgis
+       gpointer  *marker_ref; // Reference to maker
 
        /* Stuff from the parents */
        GisViewer     *viewer;
@@ -132,7 +130,7 @@ gboolean _site_update_end(gpointer _site)
 gpointer _site_update_thread(gpointer _site)
 {
        RadarSite *site = _site;
-       g_debug("GisPluginRadar: _update - %s", site->code);
+       g_debug("GisPluginRadar: _update - %s", site->city->code);
        site->status = STATUS_LOADING;
        site->message = NULL;
 
@@ -141,18 +139,18 @@ gpointer _site_update_thread(gpointer _site)
                        "aweather/nexrad_url", NULL);
 
        /* Remove old volume */
-       g_debug("GisPluginRadar: _update - remove - %s", site->code);
+       g_debug("GisPluginRadar: _update - remove - %s", site->city->code);
        if (site->level2_ref) {
                gis_viewer_remove(site->viewer, site->level2_ref);
                site->level2_ref = NULL;
        }
 
        /* Find nearest volume (temporally) */
-       g_debug("GisPluginRadar: _update - find nearest - %s", site->code);
-       gchar *dir_list = g_strconcat(nexrad_url, "/", site->code,
+       g_debug("GisPluginRadar: _update - find nearest - %s", site->city->code);
+       gchar *dir_list = g_strconcat(nexrad_url, "/", site->city->code,
                        "/", "dir.list", NULL);
        GList *files = gis_http_available(site->http,
-                       "^K\\w{3}_\\d{8}_\\d{4}$", site->code,
+                       "^K\\w{3}_\\d{8}_\\d{4}$", site->city->code,
                        "\\d+ (.*)", (offline ? NULL : dir_list));
        g_free(dir_list);
        gchar *nearest = _find_nearest(site->time, files, 5, "%Y%m%d_%H%M");
@@ -165,11 +163,13 @@ gpointer _site_update_thread(gpointer _site)
 
        /* Fetch new volume */
        g_debug("GisPluginRadar: _update - fetch");
-       gchar *local = g_strconcat(site->code, "/", nearest, NULL);
+       gchar *local = g_strconcat(site->city->code, "/", nearest, NULL);
        gchar *uri   = g_strconcat(nexrad_url, "/", local,   NULL);
        gchar *file = gis_http_fetch(site->http, uri, local,
                        offline ? GIS_LOCAL : GIS_UPDATE,
                        _site_update_loading, site);
+       g_free(nexrad_url);
+       g_free(nearest);
        g_free(local);
        g_free(uri);
        if (!file) {
@@ -178,9 +178,10 @@ gpointer _site_update_thread(gpointer _site)
        }
 
        /* Load and add new volume */
-       g_debug("GisPluginRadar: _update - load - %s", site->code);
+       g_debug("GisPluginRadar: _update - load - %s", site->city->code);
        site->level2 = aweather_level2_new_from_file(
-                       site->viewer, colormaps, file, site->code);
+                       site->viewer, colormaps, file, site->city->code);
+       g_free(file);
        if (!site->level2) {
                site->message = "Load failed";
                goto out;
@@ -196,7 +197,7 @@ void _site_update(RadarSite *site)
 {
        site->time = gis_viewer_get_time(site->viewer);
        g_debug("GisPluginRadar: _on_time_changed %s - %d",
-                       site->code, (gint)site->time);
+                       site->city->code, (gint)site->time);
 
        /* Add a progress bar */
        GtkWidget *progress = gtk_progress_bar_new();
@@ -211,16 +212,19 @@ void _site_update(RadarSite *site)
 /* RadarSite methods */
 void radar_site_unload(RadarSite *site)
 {
-       g_debug("GisPluginRadar: radar_site_unload %s", site->code);
-
-       if (site->status == STATUS_LOADING)
+       if (site->status != STATUS_LOADED)
                return; // Abort if it's still loading
 
-       g_signal_handler_disconnect(site->viewer, site->time_id);
-       g_signal_handler_disconnect(site->viewer, site->refresh_id);
+       g_debug("GisPluginRadar: radar_site_unload %s", site->city->code);
+
+       if (site->time_id)
+               g_signal_handler_disconnect(site->viewer, site->time_id);
+       if (site->refresh_id)
+               g_signal_handler_disconnect(site->viewer, site->refresh_id);
 
        /* Remove tab */
-       gtk_widget_destroy(site->config);
+       if (site->config)
+               gtk_widget_destroy(site->config);
 
        /* Remove radar */
        if (site->level2_ref) {
@@ -233,14 +237,14 @@ void radar_site_unload(RadarSite *site)
 
 void radar_site_load(RadarSite *site)
 {
-       g_debug("GisPluginRadar: radar_site_load %s", site->code);
+       g_debug("GisPluginRadar: radar_site_load %s", site->city->code);
        site->status = STATUS_LOADING;
 
        /* Add tab page */
        site->config = gtk_alignment_new(0, 0, 1, 1);
        GtkWidget *tab   = gtk_hbox_new(FALSE, 0);
        GtkWidget *close = gtk_button_new();
-       GtkWidget *label = gtk_label_new(site->name);
+       GtkWidget *label = gtk_label_new(site->city->name);
        gtk_container_add(GTK_CONTAINER(close),
                        gtk_image_new_from_stock(GTK_STOCK_CLOSE,
                                GTK_ICON_SIZE_MENU));
@@ -272,7 +276,7 @@ void _site_on_location_changed(GisViewer *viewer,
        /* Calculate distance, could cache xyz values */
        gdouble eye_xyz[3], site_xyz[3];
        lle2xyz(lat, lon, elev, &eye_xyz[0], &eye_xyz[1], &eye_xyz[2]);
-       lle2xyz(site->pos.lat, site->pos.lon, site->pos.elev,
+       lle2xyz(site->city->pos.lat, site->city->pos.lon, site->city->pos.elev,
                        &site_xyz[0], &site_xyz[1], &site_xyz[2]);
        gdouble dist = distd(site_xyz, eye_xyz);
 
@@ -283,6 +287,16 @@ void _site_on_location_changed(GisViewer *viewer,
                radar_site_unload(site);
 }
 
+gboolean _site_add_marker(gpointer _site)
+{
+       RadarSite *site = _site;
+       site->marker = gis_marker_new(site->city->name);
+       GIS_OBJECT(site->marker)->center = site->city->pos;
+       GIS_OBJECT(site->marker)->lod    = EARTH_R*site->city->lod;
+       site->marker_ref = gis_viewer_add(site->viewer,
+                       GIS_OBJECT(site->marker), GIS_LEVEL_OVERLAY, FALSE);
+       return FALSE;
+}
 RadarSite *radar_site_new(city_t *city, GtkWidget *pconfig,
                GisViewer *viewer, GisPrefs *prefs, GisHttp *http)
 {
@@ -290,21 +304,14 @@ RadarSite *radar_site_new(city_t *city, GtkWidget *pconfig,
        site->viewer  = g_object_ref(viewer);
        site->prefs   = g_object_ref(prefs);
        site->http    = http;
-       site->code    = g_strdup(city->code);
-       site->name    = g_strdup(city->name);
-       site->pos     = city->pos;
+       site->city    = city;
        site->pconfig = pconfig;
 
        /* Add marker */
-       site->marker = gis_marker_new(city->name);
-       GIS_OBJECT(site->marker)->center = site->pos;
-       GIS_OBJECT(site->marker)->lod    = EARTH_R*city->lod;
-       gis_viewer_add(site->viewer, GIS_OBJECT(site->marker),
-                       GIS_LEVEL_OVERLAY, FALSE);
+       g_idle_add(_site_add_marker, site);
 
        /* Connect signals */
-       site->location_id  =
-               g_signal_connect(viewer, "location-changed",
+       site->location_id  = g_signal_connect(viewer, "location-changed",
                        G_CALLBACK(_site_on_location_changed), site);
        return site;
 }
@@ -312,9 +319,11 @@ RadarSite *radar_site_new(city_t *city, GtkWidget *pconfig,
 void radar_site_free(RadarSite *site)
 {
        radar_site_unload(site);
-       /* Stuff? */
+       gis_viewer_remove(site->viewer, site->marker_ref);
+       if (site->location_id)
+               g_signal_handler_disconnect(site->viewer, site->location_id);
        g_object_unref(site->viewer);
-       g_free(site->code);
+       g_object_unref(site->prefs);
        g_free(site);
 }
 
@@ -323,14 +332,18 @@ void radar_site_free(RadarSite *site)
  * RadarConus *
  **************/
 struct _RadarConus {
-       GisViewer  *viewer;
-       GisTile    *tile;
-       GisHttp    *http;
-       GtkWidget  *config;
-       time_t      time;
-       GdkPixbuf  *pixbuf;
-       gchar      *message;
-       gchar      *nearest;
+       GisViewer   *viewer;
+       GisHttp     *http;
+       GtkWidget   *config;
+       time_t       time;
+       GisTile     *tile;
+       gpointer    *tile_ref;
+       GdkPixbuf   *pixbuf;
+       const gchar *message;
+       gchar       *nearest;
+
+       guint        time_id;     // "time-changed"     callback ID
+       guint        refresh_id;  // "refresh"          callback ID
 };
 
 void _conus_update_loading(gchar *file, goffset cur,
@@ -377,7 +390,10 @@ gboolean _conus_update_end(gpointer _conus)
        _gtk_bin_set_child(GTK_BIN(conus->config),
                        gtk_label_new(conus->nearest));
        gtk_widget_queue_draw(GTK_WIDGET(conus->viewer));
+
+       /* free data */
        g_object_unref(conus->pixbuf);
+       g_free(conus->nearest);
 
        return FALSE;
 }
@@ -404,6 +420,7 @@ gpointer _conus_update_thread(gpointer _conus)
        gchar *uri     = g_strconcat(conus_url, conus->nearest, NULL);
        gchar *path    = gis_http_fetch(conus->http, uri, conus->nearest, GIS_ONCE,
                        _conus_update_loading, conus);
+       g_free(uri);
        if (!path) {
                conus->message = "Fetch failed";
                goto out;
@@ -412,6 +429,7 @@ gpointer _conus_update_thread(gpointer _conus)
        /* Load the image to a pixbuf */
        GError *error = NULL;
        conus->pixbuf = gdk_pixbuf_new_from_file(path, &error);
+       g_free(path);
        if (!gdk_pixbuf_get_has_alpha(conus->pixbuf)) {
                GdkPixbuf *tmp = gdk_pixbuf_add_alpha(conus->pixbuf, TRUE, 0xff, 0xff, 0xff);
                g_object_unref(conus->pixbuf);
@@ -477,9 +495,14 @@ RadarConus *radar_conus_new(GtkWidget *pconfig,
                        50.406626367301044,   50.406626367301044-0.017971305190311*1600,
                        -127.620375523875420+0.017971305190311*3400, -127.620375523875420);
        conus->tile->zindex = 1;
-       g_signal_connect_swapped(viewer, "time-changed", G_CALLBACK(_conus_update), conus);
-       g_signal_connect_swapped(viewer, "refresh",      G_CALLBACK(_conus_update), conus);
-       gis_viewer_add(viewer, GIS_OBJECT(conus->tile), GIS_LEVEL_WORLD, TRUE);
+       conus->tile_ref = gis_viewer_add(viewer,
+                       GIS_OBJECT(conus->tile), GIS_LEVEL_WORLD, TRUE);
+
+       conus->time_id = g_signal_connect_swapped(viewer, "time-changed",
+                       G_CALLBACK(_conus_update), conus);
+       conus->refresh_id = g_signal_connect_swapped(viewer, "refresh",
+                       G_CALLBACK(_conus_update), conus);
+
        gtk_notebook_append_page(GTK_NOTEBOOK(pconfig), conus->config, gtk_label_new("Conus"));
        _conus_update(conus);
        return conus;
@@ -487,6 +510,15 @@ RadarConus *radar_conus_new(GtkWidget *pconfig,
 
 void radar_conus_free(RadarConus *conus)
 {
+       g_signal_handler_disconnect(conus->viewer, conus->time_id);
+       g_signal_handler_disconnect(conus->viewer, conus->refresh_id);
+
+       if (conus->tile->data) {
+               glDeleteTextures(1, conus->tile->data);
+               g_free(conus->tile->data);
+       }
+       gis_viewer_remove(conus->viewer, conus->tile_ref);
+
        g_object_unref(conus->viewer);
        g_free(conus);
 }
@@ -534,7 +566,7 @@ GisPluginRadar *gis_plugin_radar_new(GisViewer *viewer, GisPrefs *prefs)
 
        /* Load HUD */
        GisCallback *hud_cb = gis_callback_new(_draw_hud, self);
-       gis_viewer_add(viewer, GIS_OBJECT(hud_cb), GIS_LEVEL_HUD, FALSE);
+       self->hud_ref = gis_viewer_add(viewer, GIS_OBJECT(hud_cb), GIS_LEVEL_HUD, FALSE);
 
        /* Load Conus */
        self->conus = radar_conus_new(self->config, self->viewer, self->conus_http);
@@ -574,7 +606,8 @@ static void gis_plugin_radar_init(GisPluginRadar *self)
        /* Set defaults */
        self->sites_http = gis_http_new(G_DIR_SEPARATOR_S "nexrad" G_DIR_SEPARATOR_S "level2" G_DIR_SEPARATOR_S);
        self->conus_http = gis_http_new(G_DIR_SEPARATOR_S "nexrad" G_DIR_SEPARATOR_S "conus" G_DIR_SEPARATOR_S);
-       self->sites      = g_hash_table_new(g_str_hash, g_str_equal);
+       self->sites      = g_hash_table_new_full(g_str_hash, g_str_equal,
+                               NULL, (GDestroyNotify)radar_site_free);
        self->config     = gtk_notebook_new();
        gtk_notebook_set_tab_pos(GTK_NOTEBOOK(self->config), GTK_POS_LEFT);
 }
@@ -582,6 +615,8 @@ static void gis_plugin_radar_dispose(GObject *gobject)
 {
        g_debug("GisPluginRadar: dispose");
        GisPluginRadar *self = GIS_PLUGIN_RADAR(gobject);
+       gis_viewer_remove(self->viewer, self->hud_ref);
+       radar_conus_free(self->conus);
        /* Drop references */
        G_OBJECT_CLASS(gis_plugin_radar_parent_class)->dispose(gobject);
 }
index 31152dbf52db79f7f51307e22bdd6aaf9c2ba606..2ed86acb1568c9af3f4935c957364bafb000b8e5 100644 (file)
@@ -45,6 +45,7 @@ struct _GisPluginRadar {
        GisPrefs   *prefs;
        GtkWidget  *config;
        AWeatherColormap *colormap;
+       gpointer    *hud_ref;
 
        GHashTable *sites;
        GisHttp    *sites_http;