* Fixing some memory leaks. A few minor ones in AWeather and a major one in RSL
authorAndy Spencer <andy753421@gmail.com>
Thu, 14 May 2009 12:00:02 +0000 (12:00 +0000)
committerAndy Spencer <andy753421@gmail.com>
Thu, 14 May 2009 12:00:02 +0000 (12:00 +0000)
* Adding check boxes to toggle ridge layers

opt/rsl/rsl-gzip.patch [new file with mode: 0644]
opt/rsl/rsl-valgrind.patch [new file with mode: 0644]
src/aweather-gui.c
src/data.c
src/plugin-radar.c
src/plugin-ridge.c

diff --git a/opt/rsl/rsl-gzip.patch b/opt/rsl/rsl-gzip.patch
new file mode 100644 (file)
index 0000000..9b5f8a5
--- /dev/null
@@ -0,0 +1,270 @@
+diff -ru rsl-v1.40.pre/africa_to_radar.c rsl-v1.40/africa_to_radar.c
+--- rsl-v1.40.pre/africa_to_radar.c    2009-05-14 10:26:55.000000000 +0000
++++ rsl-v1.40/africa_to_radar.c        2009-05-14 10:27:13.000000000 +0000
+@@ -73,7 +73,7 @@
+   } else {
+       fp = fopen(infile, "r");
+   }
+-  fp = uncompress_pipe(fp);
++  fp = gunzip_pipe(fp);
+   n = 0;
+   
+   radar = RSL_new_radar(MAX_RADAR_VOLUMES);
+diff -ru rsl-v1.40.pre/anyformat_to_radar.c rsl-v1.40/anyformat_to_radar.c
+--- rsl-v1.40.pre/anyformat_to_radar.c 2009-05-14 10:26:55.000000000 +0000
++++ rsl-v1.40/anyformat_to_radar.c     2009-05-14 10:27:13.000000000 +0000
+@@ -65,7 +65,7 @@
+   }
+   /* Read the magic bytes. */
+-  fp = uncompress_pipe(fp); /* If gzip available. */
++  fp = gunzip_pipe(fp); /* If gzip available. */
+   if (fread(magic, sizeof(magic), 1, fp) != 1) {
+       char *magic_str = (char *)calloc(sizeof(magic)+1, sizeof(char));
+       memcpy(magic_str, magic, sizeof(magic));
+diff -ru rsl-v1.40.pre/dorade_to_radar.c rsl-v1.40/dorade_to_radar.c
+--- rsl-v1.40.pre/dorade_to_radar.c    2009-05-14 10:26:55.000000000 +0000
++++ rsl-v1.40/dorade_to_radar.c        2009-05-14 10:27:13.000000000 +0000
+@@ -97,7 +97,7 @@
+         return radar;
+     }
+-  fp = uncompress_pipe(fp); /* Transparently, use gunzip. */
++  fp = gunzip_pipe(fp); /* Transparently, use gunzip. */
+   /**********************************************************************/
+diff -ru rsl-v1.40.pre/gzip.c rsl-v1.40/gzip.c
+--- rsl-v1.40.pre/gzip.c       2009-05-14 10:26:55.000000000 +0000
++++ rsl-v1.40/gzip.c   2009-05-14 10:28:40.000000000 +0000
+@@ -32,8 +32,8 @@
+ /* Prototype definitions within this file. */
+ int no_command (char *cmd);
+-FILE *uncompress_pipe (FILE *fp);
+-FILE *compress_pipe (FILE *fp);
++FILE *gunzip_pipe (FILE *fp);
++FILE *gzip_pipe (FILE *fp);
+ /* Avoids the 'Broken pipe' message by reading the rest of the stream. */
+@@ -67,7 +67,7 @@
+   else return !0;
+ }
+-FILE *uncompress_pipe (FILE *fp)
++FILE *gunzip_pipe (FILE *fp)
+ {
+   /* Pass the file pointed to by 'fp' through the gzip pipe. */
+@@ -80,13 +80,13 @@
+   dup(fileno(fp));
+   fpipe = popen("gzip -q -d -f --stdout", "r");
+-  if (fpipe == NULL) perror("uncompress_pipe");
++  if (fpipe == NULL) perror("gunzip_pipe");
+   close(0);
+   dup(save_fd);
+   return fpipe;
+ }
+-FILE *compress_pipe (FILE *fp)
++FILE *gzip_pipe (FILE *fp)
+ {
+   /* Pass the file pointed to by 'fp' through the gzip pipe. */
+@@ -100,7 +100,7 @@
+   dup(fileno(fp));
+   fpipe = popen("gzip -q -1 -c", "w");
+-  if (fpipe == NULL) perror("compress_pipe");
++  if (fpipe == NULL) perror("gzip_pipe");
+   close(1);
+   dup(save_fd);
+   return fpipe;
+diff -ru rsl-v1.40.pre/lassen_to_radar.c rsl-v1.40/lassen_to_radar.c
+--- rsl-v1.40.pre/lassen_to_radar.c    2009-05-14 10:26:55.000000000 +0000
++++ rsl-v1.40/lassen_to_radar.c        2009-05-14 10:27:13.000000000 +0000
+@@ -285,7 +285,7 @@
+         perror(infile);
+         return NULL;
+     }
+-  f = uncompress_pipe(f); /* Transparently, use gunzip. */
++  f = gunzip_pipe(f); /* Transparently, use gunzip. */
+ #define NEW_BUFSIZ 16384
+   setvbuf(f,NULL,_IOFBF,(size_t)NEW_BUFSIZ); /* Faster i/o? */
+   
+diff -ru rsl-v1.40.pre/mcgill.c rsl-v1.40/mcgill.c
+--- rsl-v1.40.pre/mcgill.c     2009-05-14 10:26:55.000000000 +0000
++++ rsl-v1.40/mcgill.c 2009-05-14 10:27:13.000000000 +0000
+@@ -97,7 +97,7 @@
+    120, 120, 120, 120
+    };
+-FILE *uncompress_pipe (FILE *fp);
++FILE *gunzip_pipe (FILE *fp);
+ /**********************************************************************/
+ mcgFile_t *mcgFileOpen(int *code, char *filename)
+@@ -131,7 +131,7 @@
+         *code = MCG_OPEN_FILE_ERR;
+         return(NULL);
+         }
+-   file->fp = uncompress_pipe(file->fp); /* Transparently, use gunzip. */
++   file->fp = gunzip_pipe(file->fp); /* Transparently, use gunzip. */
+    /* Read first (header) record from data file into buffer */
+    if (fread(buffer, sizeof(char), MCG_RECORD, file->fp) < MCG_RECORD)
+         {
+diff -ru rsl-v1.40.pre/nsig.c rsl-v1.40/nsig.c
+--- rsl-v1.40.pre/nsig.c       2009-05-14 10:26:55.000000000 +0000
++++ rsl-v1.40/nsig.c   2009-05-14 10:27:13.000000000 +0000
+@@ -52,7 +52,7 @@
+ #include "nsig.h"
+-FILE *uncompress_pipe(FILE *fp);
++FILE *gunzip_pipe(FILE *fp);
+ int big_endian(void);
+ int little_endian(void);
+ void swap_4_bytes(void *word);
+@@ -76,7 +76,7 @@
+       return fp;
+   }
+-  fp = uncompress_pipe(fp); /* Transparently gunzip. */
++  fp = gunzip_pipe(fp); /* Transparently gunzip. */
+   return fp;
+ }
+diff -ru rsl-v1.40.pre/radar_to_uf.c rsl-v1.40/radar_to_uf.c
+--- rsl-v1.40.pre/radar_to_uf.c        2009-05-14 10:26:55.000000000 +0000
++++ rsl-v1.40/radar_to_uf.c    2009-05-14 10:27:13.000000000 +0000
+@@ -533,7 +533,7 @@
+       return;
+   }
+-  fp = compress_pipe(fp);
++  fp = gzip_pipe(fp);
+   RSL_radar_to_uf_fp(r, fp);
+   rsl_pclose(fp);
+ }
+diff -ru rsl-v1.40.pre/rainbow_to_radar.c rsl-v1.40/rainbow_to_radar.c
+--- rsl-v1.40.pre/rainbow_to_radar.c   2009-05-14 10:26:55.000000000 +0000
++++ rsl-v1.40/rainbow_to_radar.c       2009-05-14 10:27:13.000000000 +0000
+@@ -88,7 +88,7 @@
+       perror(infile);
+       return NULL;
+     }
+-    fp = uncompress_pipe(fp); /* Transparently gunzip. */
++    fp = gunzip_pipe(fp); /* Transparently gunzip. */
+     /* Read first character and verify file format. */
+diff -ru rsl-v1.40.pre/rapic_to_radar.c rsl-v1.40/rapic_to_radar.c
+--- rsl-v1.40.pre/rapic_to_radar.c     2009-05-14 10:26:55.000000000 +0000
++++ rsl-v1.40/rapic_to_radar.c 2009-05-14 10:27:13.000000000 +0000
+@@ -22,7 +22,7 @@
+         return radar;
+       }
+   }
+-  fp = uncompress_pipe(fp); /* Transparently gunzip. */
++  fp = gunzip_pipe(fp); /* Transparently gunzip. */
+   close(0); dup(fileno(fp)); /* Redirect stdin. */
+   rapicparse();
+diff -ru rsl-v1.40.pre/read_write.c rsl-v1.40/read_write.c
+--- rsl-v1.40.pre/read_write.c 2009-05-14 10:26:55.000000000 +0000
++++ rsl-v1.40/read_write.c     2009-05-14 10:27:13.000000000 +0000
+@@ -189,7 +189,7 @@
+       perror(infile);
+       return NULL;
+   }
+-  fp = uncompress_pipe(fp);
++  fp = gunzip_pipe(fp);
+   (void)fread(title, sizeof(char), sizeof(title), fp);
+   if (strncmp(title, "RSL", 3) != 0) return NULL;
+@@ -372,7 +372,7 @@
+       perror(outfile);
+       return -1;
+   }
+-  fp = compress_pipe(fp);
++  fp = gzip_pipe(fp);
+   n = RSL_write_radar_fp(radar, fp);
+   rsl_pclose(fp);
+diff -ru rsl-v1.40.pre/rsl.h rsl-v1.40/rsl.h
+--- rsl-v1.40.pre/rsl.h        2009-05-14 10:26:55.000000000 +0000
++++ rsl-v1.40/rsl.h    2009-05-14 10:27:13.000000000 +0000
+@@ -697,8 +697,10 @@
+ Histogram *RSL_read_histogram(char *infile);
+ int no_command (char *cmd);
+-FILE *uncompress_pipe (FILE *fp);
+-FILE *compress_pipe (FILE *fp);
++FILE *gunzip_pipe (FILE *fp);
++FILE *gzip_pipe (FILE *fp);
++FILE *bunzip2_pipe (FILE *fp);
++FILE *bzip2_pipe (FILE *fp);
+ int rsl_pclose(FILE *fp);
+ /* Carpi image generation functions. These are modified clones of the
+diff -ru rsl-v1.40.pre/toga.c rsl-v1.40/toga.c
+--- rsl-v1.40.pre/toga.c       2009-05-14 10:26:55.000000000 +0000
++++ rsl-v1.40/toga.c   2009-05-14 10:27:13.000000000 +0000
+@@ -84,7 +84,7 @@
+ int tg_read_ray(tg_file_str *);
+ void tg_prt_head(tg_map_head_str *,int);
+-FILE *uncompress_pipe (FILE *fp);
++FILE *gunzip_pipe (FILE *fp);
+ int tg_open(char *filename,tg_file_str *tg_file)
+@@ -102,7 +102,7 @@
+    /* Unfortunately, there is no tg_close to modularize the following
+     * pipe close.  Shouldn't be any problems anyway.
+     */
+-   (void) uncompress_pipe(fdopen(tg_file->fd, "r")); /* Redirect through gunzip. */
++   (void) gunzip_pipe(fdopen(tg_file->fd, "r")); /* Redirect through gunzip. */
+    /* initialize buffer pointers, flags */
+    tg_file->buf_ind = 32769;
+    tg_file->buf_end = 32769;
+diff -ru rsl-v1.40.pre/uf_to_radar.c rsl-v1.40/uf_to_radar.c
+--- rsl-v1.40.pre/uf_to_radar.c        2009-05-14 10:26:55.000000000 +0000
++++ rsl-v1.40/uf_to_radar.c    2009-05-14 10:27:13.000000000 +0000
+@@ -625,7 +625,7 @@
+       perror(infile);
+       return radar;
+   }
+-  fp = uncompress_pipe(fp); /* Transparently gunzip. */
++  fp = gunzip_pipe(fp); /* Transparently gunzip. */
+   radar = RSL_uf_to_radar_fp(fp);
+   rsl_pclose(fp);
+       
+diff -ru rsl-v1.40.pre/wsr88d.c rsl-v1.40/wsr88d.c
+--- rsl-v1.40.pre/wsr88d.c     2009-05-14 10:26:55.000000000 +0000
++++ rsl-v1.40/wsr88d.c 2009-05-14 10:27:13.000000000 +0000
+@@ -246,7 +246,7 @@
+   }
+   if (wf->fptr == NULL) return NULL;
+-  wf->fptr = uncompress_pipe(wf->fptr);
++  wf->fptr = gunzip_pipe(wf->fptr);
+ #define NEW_BUFSIZ 16384
+   setvbuf(wf->fptr,NULL,_IOFBF,(size_t)NEW_BUFSIZ); /* Faster i/o? */
+   return wf;
+diff -ru rsl-v1.40.pre/wsr88d.h rsl-v1.40/wsr88d.h
+--- rsl-v1.40.pre/wsr88d.h     2009-05-14 10:26:55.000000000 +0000
++++ rsl-v1.40/wsr88d.h 2009-05-14 10:27:13.000000000 +0000
+@@ -212,8 +212,8 @@
+ float wsr88d_get_frequency(Wsr88d_ray *ray);
+ int no_command (char *cmd);
+-FILE *uncompress_pipe (FILE *fp);
+-FILE *compress_pipe (FILE *fp);
++FILE *gunzip_pipe (FILE *fp);
++FILE *gzip_pipe (FILE *fp);
+ int rsl_pclose(FILE *fp);
+ #endif
diff --git a/opt/rsl/rsl-valgrind.patch b/opt/rsl/rsl-valgrind.patch
new file mode 100644 (file)
index 0000000..bf8016b
--- /dev/null
@@ -0,0 +1,135 @@
+diff -w -ru rsl-v1.40/wsr88d_m31.c rsl-v1.40.test/wsr88d_m31.c
+--- rsl-v1.40/wsr88d_m31.c     2008-10-08 23:43:03.000000000 +0000
++++ rsl-v1.40.test/wsr88d_m31.c        2009-05-14 10:06:23.000000000 +0000
+@@ -515,6 +515,7 @@
+     m1_ray.vol_cpat = vcp_data.vcp;
+     m1_ray.elev_num = ray_hdr.elev_num;
+     m1_ray.unam_rng = wsr88d_ray.unamb_rng;
++    m1_ray.nyq_vel  = wsr88d_ray.nyq_vel; // TODO: is this correct?
+     if (ray_hdr.azm_res != 1)
+       ray->h.beam_width = 1.0;
+     else ray->h.beam_width = 0.5;
+@@ -603,6 +604,8 @@
+           radar->v[vol_index]->sweep[isweep]->ray[iray] = ray;
+           radar->v[vol_index]->sweep[isweep]->h.nrays = iray+1;
+       }
++      free(wsr88d_ray.ref->data);
++      free(wsr88d_ray.ref);
+     }
+     if (wsr88d_ray.ray_hdr.dbptr_vel > 0) {
+@@ -628,6 +631,8 @@
+       wsr88d_load_ray_hdr(wsr88d_ray, ray);
+       radar->v[vol_index]->sweep[isweep]->ray[iray] = ray;
+       radar->v[vol_index]->sweep[isweep]->h.nrays = iray+1;
++      free(wsr88d_ray.vel->data);
++      free(wsr88d_ray.vel);
+     }
+     if (wsr88d_ray.ray_hdr.dbptr_sw > 0) {
+@@ -653,6 +658,8 @@
+       wsr88d_load_ray_hdr(wsr88d_ray, ray);
+       radar->v[vol_index]->sweep[isweep]->ray[iray] = ray;
+       radar->v[vol_index]->sweep[isweep]->h.nrays = iray+1;
++      free(wsr88d_ray.sw->data);
++      free(wsr88d_ray.sw);
+     }
+ }
+@@ -706,15 +713,27 @@
+  * at the WSR-88D Radar Operations Center web site.
+  */
+-    n = fread(&msghdr, sizeof(Wsr88d_msg_hdr), 1, wf->fptr);
+-
+-    /* printf("msgtype = %d\n", msghdr.msg_type); */
+-    msg_hdr_size = sizeof(Wsr88d_msg_hdr) - sizeof(msghdr.rpg);
+     radar = RSL_new_radar(MAX_RADAR_VOLUMES);
+     
+     while (! end_of_vos) {
++      /* Read current header */
++      n = fread(&msghdr, sizeof(Wsr88d_msg_hdr), 1, wf->fptr);
++      if (n < 1) {
++          fprintf(stderr,"Warning: load_wsr88d_m31_into_radar: ");
++          if (feof(wf->fptr) != 0) fprintf(stderr,
++                  "Unexpected end of file.\n");
++          else fprintf(stderr,"Failed reading msghdr.\n");
++          fprintf(stderr,"Current sweep number: %d\n"
++                  "Last ray read: %d\n", isweep+1, iray);
++          wsr88d_load_sweep_header(radar, isweep, wsr88d_ray);
++          return radar;
++      }
++
++      /* printf("msgtype = %d\n", msghdr.msg_type); */
++      msg_hdr_size = sizeof(Wsr88d_msg_hdr) - sizeof(msghdr.rpg);
++
+       if (msghdr.msg_type == 31) {
+           if (little_endian()) wsr88d_swap_m31_hdr(&msghdr);
+@@ -729,6 +748,18 @@
+           /* Load this ray into radar structure ray. */
+           wsr88d_load_ray_into_radar(wsr88d_ray, isweep, iray, radar);
+           iray++;
++
++          /* Check for end of sweep */
++          if (wsr88d_ray.ray_hdr.radial_status == END_OF_ELEV) {
++              wsr88d_load_sweep_header(radar, isweep, wsr88d_ray);
++              isweep++;
++              iray = 0;
++          }
++
++          if (wsr88d_ray.ray_hdr.radial_status == END_VOS) {
++              //wsr88d_load_sweep_header(radar, isweep, wsr88d_ray);
++              end_of_vos = 1;
++          }
+       }
+       else { /* msg_type not 31 */
+           n = fread(&non31_seg_remainder, sizeof(non31_seg_remainder), 1,
+@@ -748,33 +779,11 @@
+               radar->h.vcp = vcp_data.vcp;
+               /* printf("VCP = %d\n", vcp_data.vcp); */
+           }
++          /* TODO: check for end of sweep/volume */
+       }
+-      /* Check for end of sweep */
+-      if (wsr88d_ray.ray_hdr.radial_status == END_OF_ELEV) {
+-          wsr88d_load_sweep_header(radar, isweep, wsr88d_ray);
+-          isweep++;
+-          iray = 0;
+-      }
+-
+-      if (wsr88d_ray.ray_hdr.radial_status != END_VOS) {
+-          n = fread(&msghdr, sizeof(Wsr88d_msg_hdr), 1, wf->fptr);
+-          if (n < 1) {
+-              fprintf(stderr,"Warning: load_wsr88d_m31_into_radar: ");
+-              if (feof(wf->fptr) != 0) fprintf(stderr,
+-                      "Unexpected end of file.\n");
+-              else fprintf(stderr,"Failed reading msghdr.\n");
+-              fprintf(stderr,"Current sweep number: %d\n"
+-                      "Last ray read: %d\n", isweep+1, iray);
+-              wsr88d_load_sweep_header(radar, isweep, wsr88d_ray);
+-              return radar;
+-          }
+-      }
+-      else {
++      if (feof(wf->fptr) != 0)
+           end_of_vos = 1;
+-          wsr88d_load_sweep_header(radar, isweep, wsr88d_ray);
+-      }
+-      if (feof(wf->fptr) != 0) end_of_vos = 1;
+     }
+     return radar;
+diff -w -ru rsl-v1.40/wsr88d_to_radar.c rsl-v1.40.test/wsr88d_to_radar.c
+--- rsl-v1.40/wsr88d_to_radar.c        2008-07-30 22:41:20.000000000 +0000
++++ rsl-v1.40.test/wsr88d_to_radar.c   2009-05-14 10:07:09.000000000 +0000
+@@ -429,5 +429,6 @@
+       radar->h.lpulse = sitep->lpulse;
+               
+   radar = RSL_prune_radar(radar);
++  free(sitep);
+   return radar;
+ }
index 1dd85a5bbcb1f776c7af3bbdd556da5e85be7659..320a14d59de224a17a8a36c9de2d45c5981ea44e 100644 (file)
@@ -69,7 +69,7 @@ static gboolean map(GtkWidget *da, GdkEventConfigure *event, AWeatherGui *gui)
        /* Misc */
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-       glClearColor(0.8f, 0.8f, 1.0f, 0.0f);
+       glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
 
        /* Tessellation, "finding intersecting triangles" */
        /* http://research.microsoft.com/pubs/70307/tr-2006-81.pdf */
@@ -165,8 +165,10 @@ static void update_location_widget(AWeatherView *view, char *location, AWeatherG
                                g_signal_handlers_block_by_func(combo, G_CALLBACK(on_site_changed), gui);
                                gtk_combo_box_set_active_iter(combo, &iter2);
                                g_signal_handlers_unblock_by_func(combo, G_CALLBACK(on_site_changed), gui);
+                               g_free(text);
                                return;
                        }
+                       g_free(text);
                }
        }
 }
index fa11ea8460f03cdfb1738c89e4ccac416c182e81..ab373114c6b0f3e3529f2208d1d1d8bc53860951 100644 (file)
@@ -70,11 +70,17 @@ void cache_file(char *base, char *path, AWeatherCacheDoneCallback callback, gpoi
        else if (g_file_get_size(src) != g_file_get_size(dst))
                g_message("Caching file: sizes mismatch - %lld != %lld",
                                g_file_get_size(src), g_file_get_size(dst));
-       else
-               return callback(local, user_data);
+       else {
+               callback(local, user_data);
+               g_free(local);
+               g_free(url);
+               return;
+       }
 
-       if (!g_file_test(g_path_get_dirname(local), G_FILE_TEST_IS_DIR))
-               g_mkdir_with_parents(g_path_get_dirname(local), 0755);
+       char *dir = g_path_get_dirname(local);
+       if (!g_file_test(dir, G_FILE_TEST_IS_DIR))
+               g_mkdir_with_parents(dir, 0755);
+       g_free(dir);
        cache_file_end_t *info = g_malloc0(sizeof(cache_file_end_t));
        info->callback  = callback;
        info->src       = url;
index 0ee67ba4528cbdd50720b4b075e6666a9b7a333b..0990858d9087d499385dfc67cfb4ec63746d7ec4 100644 (file)
@@ -34,9 +34,9 @@ static Sweep *cur_sweep = NULL;  // make this not global
 //static char red[256], green[256], blue[256];
 static colormap_t *colormap;
 static guint sweep_tex = 0;
+static Radar *radar = NULL;
 
 static AWeatherGui *gui = NULL;
-static Radar *radar = NULL;
 
 /**************************
  * Data loading functions *
@@ -119,7 +119,7 @@ static void load_radar_gui(Radar *radar)
        for (vi = 0; vi < radar->h.nvolumes; vi++) {
                Volume *vol = radar->v[vi];
                if (vol == NULL) continue;
-               GtkWidget *vbox = gtk_vbox_new(TRUE, 0);
+               GtkWidget *vbox = gtk_vbox_new(FALSE, 0);
                for (si = vol->h.nsweeps-1; si >= 0; si--) {
                        Sweep *sweep = vol->sweep[si];
                        if (sweep == NULL) continue;
@@ -131,7 +131,6 @@ static void load_radar_gui(Radar *radar)
                        gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, TRUE, 0);
                        g_free(label);
                }
-               gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE);
                gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
        }
        gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(config_body), hbox);
@@ -147,8 +146,12 @@ static void load_radar_rsl(GPid pid, gint status, gpointer _path)
                return;
        }
        char *site = g_path_get_basename(g_path_get_dirname(path));
-       if (radar) RSL_free_radar(radar);
        RSL_read_these_sweeps("all", NULL);
+       if (radar) {
+               g_message("Freeing radar");
+               RSL_free_radar(radar);
+       }
+       g_message("Allocating radar");
        radar = RSL_wsr88d_to_radar(path, site);
        if (radar == NULL) {
                g_warning("fail to load radar: path=%s, site=%s", path, site);
@@ -292,6 +295,7 @@ static void set_time(AWeatherView *view, char *time, gpointer user_data)
        cur_sweep = NULL; // Clear radar
        gtk_widget_queue_draw(aweather_gui_get_widget(gui, "drawing"));
        cache_file(base, path, load_radar, NULL);
+       g_free(path);
 }
 
 static void set_site(AWeatherView *view, char *site, gpointer user_data)
@@ -302,6 +306,7 @@ static void set_site(AWeatherView *view, char *site, gpointer user_data)
        GError *error = NULL;
        char *list_uri = g_strdup_printf("http://mesonet.agron.iastate.edu/data/nexrd2/raw/K%s/dir.list", site);
        GFile *list    = g_file_new_for_uri(list_uri);
+       g_free(list_uri);
        cur_sweep = NULL; // Clear radar
        gtk_widget_queue_draw(aweather_gui_get_widget(gui, "drawing"));
        g_file_load_contents(list, NULL, &data, &length, NULL, &error);
@@ -326,6 +331,8 @@ static void set_site(AWeatherView *view, char *site, gpointer user_data)
        }
        if (time != NULL) 
                aweather_view_set_time(view, time);
+       g_free(data);
+       g_strfreev(lines);
 }
 
 /* Init */
@@ -340,7 +347,7 @@ gboolean radar_init(AWeatherGui *_gui)
        config_body = gtk_scrolled_window_new(NULL, NULL);
        gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(config_body), gtk_label_new("No radar loaded"));
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(config_body), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-       gtk_notebook_append_page(GTK_NOTEBOOK(config), config_body, gtk_label_new("Radar"));
+       gtk_notebook_prepend_page(GTK_NOTEBOOK(config), config_body, gtk_label_new("Radar"));
 
        /* Set up OpenGL Stuff */
        g_signal_connect(drawing, "expose-event",     G_CALLBACK(expose),   NULL);
index cd8c447996bf2ede782c3ab9b693440ebc048852..ea6068a8272726803f97a36ac53d2ead8f7b506e 100644 (file)
@@ -35,17 +35,19 @@ enum {
 };
 
 typedef struct {
+       gchar *name;
        gchar *fmt;
+       gboolean enabled;
        float z;
        guint tex;
 } layer_t;
 
 static layer_t layers[] = {
-       [LAYER_TOPO]     = { "Overlays/" "Topo/"     "Short/" "%s_Topo_Short.jpg",     1, 0 },
-       [LAYER_COUNTY]   = { "Overlays/" "County/"   "Short/" "%s_County_Short.gif",   3, 0 },
-       [LAYER_RIVERS]   = { "Overlays/" "Rivers/"   "Short/" "%s_Rivers_Short.gif",   4, 0 },
-       [LAYER_HIGHWAYS] = { "Overlays/" "Highways/" "Short/" "%s_Highways_Short.gif", 5, 0 },
-       [LAYER_CITY]     = { "Overlays/" "Cities/"   "Short/" "%s_City_Short.gif",     6, 0 },
+       [LAYER_TOPO]     = { "Topo",     "Overlays/" "Topo/"     "Short/" "%s_Topo_Short.jpg",     TRUE,  1, 0 },
+       [LAYER_COUNTY]   = { "Counties", "Overlays/" "County/"   "Short/" "%s_County_Short.gif",   TRUE,  3, 0 },
+       [LAYER_RIVERS]   = { "Rivers",   "Overlays/" "Rivers/"   "Short/" "%s_Rivers_Short.gif",   FALSE, 4, 0 },
+       [LAYER_HIGHWAYS] = { "Highways", "Overlays/" "Highways/" "Short/" "%s_Highways_Short.gif", TRUE,  5, 0 },
+       [LAYER_CITY]     = { "Cities",   "Overlays/" "Cities/"   "Short/" "%s_City_Short.gif",     TRUE,  6, 0 },
 };
 
 static AWeatherGui *gui = NULL;
@@ -79,9 +81,11 @@ void load_texture(gchar *filename, gpointer _layer)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
+       char *base = g_path_get_basename(filename);
        g_message("loaded image:  w=%-3d  h=%-3d  fmt=%x  px=(%02x,%02x,%02x,%02x)  img=%s",
                width, height, format, pixels[0], pixels[1], pixels[2], pixels[3],
-               g_path_get_basename(filename));
+               base);
+       g_free(base);
 
        aweather_gui_gl_end(gui);
 
@@ -108,8 +112,9 @@ static gboolean expose(GtkWidget *da, GdkEventExpose *event, gpointer user_data)
        glColor4f(1,1,1,1);
 
        for (int i = 0; i < LAYER_COUNT; i++) {
+               if (!layers[i].enabled)
+                       continue;
                glBindTexture(GL_TEXTURE_2D, layers[i].tex);
-
                glBegin(GL_POLYGON);
                glTexCoord2f(0.0, 0.0); glVertex3f(250*1000*-1.0, 250*1000* 1.0, layers[i].z);
                glTexCoord2f(0.0, 1.0); glVertex3f(250*1000*-1.0, 250*1000*-1.0, layers[i].z);
@@ -122,11 +127,32 @@ static gboolean expose(GtkWidget *da, GdkEventExpose *event, gpointer user_data)
        return FALSE;
 }
 
+void toggle_layer(GtkToggleButton *check, gpointer _layer)
+{
+       layer_t *layer = _layer;
+       layer->enabled = gtk_toggle_button_get_active(check);
+       gtk_widget_queue_draw(aweather_gui_get_widget(gui, "drawing"));
+}
+
 gboolean ridge_init(AWeatherGui *_gui)
 {
        gui = _gui;
-       GtkDrawingArea *drawing = GTK_DRAWING_AREA(aweather_gui_get_widget(gui, "drawing"));
-       AWeatherView   *view    = aweather_gui_get_view(gui);
+       AWeatherView *view    = aweather_gui_get_view(gui);
+       GtkWidget    *drawing = aweather_gui_get_widget(gui, "drawing");
+       GtkWidget    *config  = aweather_gui_get_widget(gui, "tabs");
+
+       /* Add configuration tab */
+       GtkWidget *tab  = gtk_label_new("Ridge");
+       GtkWidget *body = gtk_alignment_new(0.5, 0, 0, 0);
+       GtkWidget *hbox = gtk_hbox_new(FALSE, 10);
+       for (int i = 0; i < LAYER_COUNT; i++) {
+               GtkWidget *check = gtk_check_button_new_with_label(layers[i].name);
+               gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), layers[i].enabled);
+               gtk_box_pack_start(GTK_BOX(hbox), check, FALSE, TRUE, 0);
+               g_signal_connect(check, "toggled", G_CALLBACK(toggle_layer), &layers[i]);
+       }
+       gtk_container_add(GTK_CONTAINER(body), hbox);
+       gtk_notebook_append_page(GTK_NOTEBOOK(config), body, tab);
 
        /* Set up OpenGL Stuff */
        g_signal_connect(drawing, "expose-event",     G_CALLBACK(expose),    NULL);