From: Andy Spencer Date: Thu, 14 May 2009 12:00:02 +0000 (+0000) Subject: * Fixing some memory leaks. A few minor ones in AWeather and a major one in RSL X-Git-Tag: v0.1~28 X-Git-Url: http://pileus.org/git/?p=grits;a=commitdiff_plain;h=93c853165104b5119e17be07e325f9097a5ebdb3;hp=c17d694dcf9b73f7034e8100aeb0282ae2dc55cb * Fixing some memory leaks. A few minor ones in AWeather and a major one in RSL * Adding check boxes to toggle ridge layers --- diff --git a/opt/rsl/rsl-gzip.patch b/opt/rsl/rsl-gzip.patch new file mode 100644 index 0000000..9b5f8a5 --- /dev/null +++ b/opt/rsl/rsl-gzip.patch @@ -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 index 0000000..bf8016b --- /dev/null +++ b/opt/rsl/rsl-valgrind.patch @@ -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; + } diff --git a/src/aweather-gui.c b/src/aweather-gui.c index 1dd85a5..320a14d 100644 --- a/src/aweather-gui.c +++ b/src/aweather-gui.c @@ -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); } } } diff --git a/src/data.c b/src/data.c index fa11ea8..ab37311 100644 --- a/src/data.c +++ b/src/data.c @@ -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; diff --git a/src/plugin-radar.c b/src/plugin-radar.c index 0ee67ba..0990858 100644 --- a/src/plugin-radar.c +++ b/src/plugin-radar.c @@ -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); diff --git a/src/plugin-ridge.c b/src/plugin-ridge.c index cd8c447..ea6068a 100644 --- a/src/plugin-ridge.c +++ b/src/plugin-ridge.c @@ -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);