Splitting GIS into a shared library, and a lot more
authorAndy Spencer <andy753421@gmail.com>
Thu, 6 Aug 2009 00:40:17 +0000 (00:40 +0000)
committerAndy Spencer <andy753421@gmail.com>
Thu, 6 Aug 2009 00:40:17 +0000 (00:40 +0000)
35 files changed:
TODO
configure.ac
docs/api/Makefile.am
src/Makefile.am
src/aweather-gui.c
src/aweather-gui.h
src/aweather-location.c [moved from src/location.c with 99% similarity]
src/aweather-location.h [moved from src/location.h with 100% similarity]
src/aweather-plugin.h [deleted file]
src/gis/Makefile.am [new file with mode: 0644]
src/gis/gis-data.c [moved from src/data.c with 99% similarity]
src/gis/gis-data.h [moved from src/data.h with 100% similarity]
src/gis/gis-marshal.c [new file with mode: 0644]
src/gis/gis-marshal.h [new file with mode: 0644]
src/gis/gis-marshal.list [moved from src/marshal.list with 50% similarity]
src/gis/gis-opengl.c [moved from src/gis-opengl.c with 94% similarity]
src/gis/gis-opengl.h [moved from src/gis-opengl.h with 94% similarity]
src/gis/gis-plugin.c [new file with mode: 0644]
src/gis/gis-plugin.h [new file with mode: 0644]
src/gis/gis-prefs.c [new file with mode: 0644]
src/gis/gis-prefs.h [new file with mode: 0644]
src/gis/gis-view.c [moved from src/gis-view.c with 97% similarity]
src/gis/gis-view.h [moved from src/gis-view.h with 100% similarity]
src/gis/gis-world.c [moved from src/gis-world.c with 99% similarity]
src/gis/gis-world.h [moved from src/gis-world.h with 100% similarity]
src/gis/gis.h [moved from src/aweather-plugin.c with 50% similarity]
src/main.c
src/plugins/Makefile.am
src/plugins/example.c
src/plugins/example.h
src/plugins/radar-misc.h [moved from src/misc.h with 91% similarity]
src/plugins/radar.c
src/plugins/radar.h
src/plugins/ridge.c
src/plugins/ridge.h

diff --git a/TODO b/TODO
index 9f8711f..1ed0735 100644 (file)
--- a/TODO
+++ b/TODO
@@ -3,7 +3,6 @@ Road plan
 0.x - Misc
   * Fix all memory leaks
   * Pre-load textures and polys in OpenGL
-  * Fetch radar list aysnc
   * Configuration file
     * Default site
     * Keybindings?
index 4433b5a..18311d7 100644 (file)
@@ -24,6 +24,7 @@ AC_SUBST(RSL_LIBS,   "-lrsl")
 AC_CONFIG_FILES([
        Makefile
        src/Makefile
+       src/gis/Makefile
        src/plugins/Makefile
        data/Makefile
        docs/Makefile
index 6fdc850..ac63adc 100644 (file)
@@ -1,10 +1,7 @@
 AM_CPPFLAGS= $(RSL_CFLAGS) $(SOUP_CFLAGS) $(GLIB_CFLAGS) $(GTK_CFLAGS)
 GTKDOC_LIBS=$(RSL_LIBS) $(SOUP_LIBS) $(GLIB_LIBS) $(GTK_LIBS) \
        $(top_srcdir)/src/aweather-aweather-*.o \
-       $(top_srcdir)/src/aweather-gis-*.o \
-       $(top_srcdir)/src/aweather-data.o \
-       $(top_srcdir)/src/aweather-location.o \
-       $(top_srcdir)/src/aweather-marshal.o \
+       $(top_srcdir)/src/gis/*.o \
        $(top_srcdir)/src/plugins/*.o
 DOC_MODULE=aweather
 DOC_SOURCE_DIR=$(top_srcdir)/src/
index 191dfab..18976bc 100644 (file)
@@ -1,37 +1,20 @@
-SUBDIRS = plugins
+SUBDIRS = gis plugins
 
-AM_CFLAGS     = -Wall -Werror -Wno-unused --std=gnu99 
-bin_PROGRAMS  = aweather wsr88ddec
-
-BUILT_SOURCES = marshal.c marshal.h
+AM_CFLAGS = -Wall -Werror -Wno-unused --std=gnu99 
 
+bin_PROGRAMS = aweather wsr88ddec
 aweather_SOURCES  = main.c \
-       marshal.c         marshal.h         \
-       aweather-gui.c    aweather-gui.h    \
-       aweather-plugin.c aweather-plugin.h \
-       gis-opengl.c      gis-opengl.h      \
-       gis-view.c        gis-view.h        \
-       gis-world.c       gis-world.h       \
-       data.c            data.h            \
-       location.c        location.h        \
-       marching.c        marching.h
-aweather_CPPFLAGS = \
-       -DDATADIR="\"$(datadir)\"" \
-       -DPLUGINDIR="\"$(libdir)/aweather\"" \
-       $(RSL_CFLAGS) $(SOUP_CFLAGS) $(GLIB_CFLAGS) $(GTK_CFLAGS)
-aweather_LDADD    = $(RSL_LIBS) $(SOUP_LIBS) $(GLIB_LIBS) $(GTK_LIBS)
+       aweather-gui.c      aweather-gui.h \
+       aweather-location.c aweather-location.h
+aweather_CPPFLAGS = -DDATADIR="\"$(datadir)\"" $(SOUP_CFLAGS) $(GLIB_CFLAGS) $(GTK_CFLAGS)
+aweather_LDADD    = gis/libgis.la $(SOUP_LIBS) $(GLIB_LIBS) $(GTK_LIBS)
 
 wsr88ddec         = wsr88ddec.c
-wsr88ddec_LDADD   = -lbz2
+wsr88ddec_LDFLAGS = -lbz2
 
 CLEANFILES = gmon.out valgrind.out
 MAINTAINERCLEANFILES = Makefile.in
 
-.list.c:
-       glib-genmarshal --prefix=aweather_cclosure_marshal --body   $< > $@
-.list.h:
-       glib-genmarshal --prefix=aweather_cclosure_marshal --header $< > $@
-
 test: all
        ./aweather -o -d 7 -s KVNX
 
index 64c11a7..2720a00 100644 (file)
 #include <gdk/gdkkeysyms.h>
 #include <math.h>
 
-#include "misc.h"
+#include <gis/gis.h>
+
 #include "aweather-gui.h"
-#include "aweather-plugin.h"
-#include "gis-opengl.h"
-#include "location.h"
+#include "aweather-location.h"
 
 /* Needed prototpes */
 gboolean on_gui_key_press(GtkWidget *widget, GdkEventKey *event, AWeatherGui *self);
+static void on_gis_refresh(GisWorld *world, gpointer _self);
+static void on_gis_site_changed(GisView *view, char *site, gpointer _self);
 static void site_setup(AWeatherGui *self);
 static void time_setup(AWeatherGui *self);
 
@@ -39,6 +40,12 @@ static void aweather_gui_init(AWeatherGui *self)
 {
        g_debug("AWeatherGui: init");
 
+       /* Simple things */
+       self->prefs   = gis_prefs_new("aweather");
+       self->plugins = gis_plugins_new();
+       self->world   = gis_world_new();
+       self->view    = gis_view_new();
+
        /* Setup window */
        self->builder = gtk_builder_new();
        GError *error = NULL;
@@ -48,31 +55,27 @@ static void aweather_gui_init(AWeatherGui *self)
 
        /* GIS things */
        GtkWidget *drawing = aweather_gui_get_widget(self, "drawing");
-       self->world   = gis_world_new();
-       self->view    = gis_view_new();
-       self->opengl  = gis_opengl_new(self->world, self->view, GTK_DRAWING_AREA(drawing));
-
-       /* Plugins */
-       self->plugins     = NULL;
-       // TODO: set/load these with prefereces
-       aweather_gui_load_plugin(self, "example");
-       //aweather_gui_load_plugin(self, "radar");
-       //aweather_gui_load_plugin(self, "ridge");
-       self->gtk_plugins = GTK_LIST_STORE(aweather_gui_get_object(self, "plugins"));
-       GDir *dir = g_dir_open(PLUGINDIR, 0, NULL);
-       const gchar *name;
-       GtkTreeIter iter;
-       while ((name = g_dir_read_name(dir))) {
-               if (g_pattern_match_simple("*.so", name)) {
-                       gtk_list_store_append(self->gtk_plugins, &iter);
-                       gtk_list_store_set(self->gtk_plugins, &iter, 0, name, 1, FALSE, -1);
-               }
-       }
+       g_message("drawing = %p", drawing);
+       self->opengl = gis_opengl_new(self->world, self->view, GTK_DRAWING_AREA(drawing));
+       self->opengl->plugins = self->plugins;
+       //gtk_widget_show_all(GTK_WIDGET(self));
 
        /* Misc, helpers */
        site_setup(self);
        time_setup(self);
 
+       /* Plugins */
+       GtkTreeIter iter;
+       self->gtk_plugins = GTK_LIST_STORE(aweather_gui_get_object(self, "plugins"));
+       for (GList *cur = gis_plugins_available(); cur; cur = cur->next) {
+               gchar *name = cur->data;
+               gboolean enabled = gis_prefs_get_boolean_v(self->prefs, cur->data, "enabled");
+               gtk_list_store_append(self->gtk_plugins, &iter);
+               gtk_list_store_set(self->gtk_plugins, &iter, 0, name, 1, enabled, -1);
+               if (enabled)
+                       aweather_gui_attach_plugin(self, name);
+       }
+
        /* Connect signals */
        gtk_builder_connect_signals(self->builder, self);
        g_signal_connect(self, "key-press-event",
@@ -81,11 +84,9 @@ static void aweather_gui_init(AWeatherGui *self)
                        G_CALLBACK(gtk_toggle_action_set_active),
                        aweather_gui_get_object(self, "offline"));
 
-       /* Preferences */
-       gchar *filename = g_build_filename(g_get_user_config_dir(),
-                       "aweather", "config.ini", NULL);
-       self->prefs = g_key_file_new();
-       g_key_file_load_from_file(self->prefs, filename, G_KEY_FILE_KEEP_COMMENTS, &error);
+       /* deprecated site stuff */
+       g_signal_connect(self->view,  "site-changed", G_CALLBACK(on_gis_site_changed), self);
+       g_signal_connect(self->world, "refresh",      G_CALLBACK(on_gis_refresh),      self);
 }
 static GObject *aweather_gui_constructor(GType gtype, guint n_properties,
                GObjectConstructParam *properties)
@@ -119,18 +120,11 @@ static void aweather_gui_dispose(GObject *_self)
                self->opengl = NULL;
        }
        if (self->plugins) {
-               g_list_foreach(self->plugins, (GFunc)g_object_unref, NULL);
-               g_list_free(self->plugins);
+               gis_plugins_free(self->plugins);
                self->plugins = NULL;
        }
        if (self->prefs) {
-               gchar *filename = g_build_filename(g_get_user_config_dir(),
-                               "aweather", "config.ini", NULL);
-               gsize length;
-               g_mkdir_with_parents(g_path_get_dirname(filename), 0755);
-               gchar *data = g_key_file_to_data(self->prefs, &length, NULL);
-               g_file_set_contents(filename, data, length, NULL);
-               g_key_file_free(self->prefs);
+               g_object_unref(self->prefs);
                self->prefs = NULL;
        }
        G_OBJECT_CLASS(aweather_gui_parent_class)->dispose(_self);
@@ -218,26 +212,25 @@ void on_plugin_toggled(GtkCellRendererToggle *cell, gchar *path_str, AWeatherGui
        GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(tview));
        g_message("model=%p", model);
        gboolean state;
-       gchar *so;
+       gchar *name;
        GtkTreeIter iter;
        gtk_tree_model_get_iter_from_string(model, &iter, path_str);
-       gtk_tree_model_get(model, &iter, 0, &so, 1, &state, -1);
+       gtk_tree_model_get(model, &iter, 0, &name, 1, &state, -1);
        state = !state;
        gtk_list_store_set(GTK_LIST_STORE(model), &iter, 1, state, -1);
-       g_strdelimit(so, ".", '\0');
        if (state)
-               aweather_gui_load_plugin(self, so);
+               aweather_gui_attach_plugin(self, name);
        else
-               aweather_gui_unload_plugin(self, so);
-       g_free(so);
-       gtk_widget_show_all(aweather_gui_get_widget(self, "tabs"));
+               aweather_gui_deattach_plugin(self, name);
+       gis_prefs_set_boolean_v(self->prefs, name, "enabled", state);
+       g_free(name);
 }
 void on_prefs(GtkAction *action, AWeatherGui *self)
 {
        /* get prefs */
-       gchar *is = g_key_file_get_string(self->prefs,  "general", "initial_site", NULL);
-       gchar *nu = g_key_file_get_string(self->prefs,  "general", "nexrad_url",   NULL);
-       gint   ll = g_key_file_get_integer(self->prefs, "general", "log_level",    NULL);
+       gchar *is = gis_prefs_get_string (self->prefs, "aweather/initial_site");
+       gchar *nu = gis_prefs_get_string (self->prefs, "aweather/nexrad_url");
+       gint   ll = gis_prefs_get_integer(self->prefs, "aweather/log_level");
        load_window("prefs_window", self);
        /* set prefs */
        GtkWidget *isw = aweather_gui_get_widget(self, "initial_site");
@@ -342,27 +335,26 @@ void on_offline(GtkToggleAction *action, AWeatherGui *self)
 {
        gboolean value = gtk_toggle_action_get_active(action);
        g_debug("AWeatherGui: on_offline - offline=%d", value);
-       g_key_file_set_boolean(self->prefs, "general", "offline", value);
+       gis_prefs_set_boolean(self->prefs, "gis/offline", value);
        gis_world_set_offline(self->world, value);
 }
 void on_initial_site_changed(GtkEntry *entry, AWeatherGui *self)
 {
        const gchar *text = gtk_entry_get_text(entry);
        g_debug("AWeatherGui: on_initial_site_changed - site=%s", text);
-       g_key_file_set_string(self->prefs, "general", "initial_site", text);
+       gis_prefs_set_string(self->prefs, "aweather/initial_site", text);
 }
 void on_nexrad_url_changed(GtkEntry *entry, AWeatherGui *self)
 {
        const gchar *text = gtk_entry_get_text(entry);
        g_debug("AWeatherGui: on_nexrad_url_changed - url=%s", text);
-       g_key_file_set_string(self->prefs, "general", "nexrad_url", text);
+       gis_prefs_set_string(self->prefs, "aweather/nexrad_url", text);
 }
 int on_log_level_changed(GtkSpinButton *spinner, AWeatherGui *self)
 {
        gint value = gtk_spin_button_get_value_as_int(spinner);
        g_debug("AWeatherGui: on_log_level_changed - %p, level=%d", self, value);
-       g_key_file_set_integer(self->prefs, "general", "log_level", value);
-       g_debug("test");
+       gis_prefs_set_integer(self->prefs, "aweather/log_level", value);
        return TRUE;
 }
 // plugins
@@ -417,6 +409,90 @@ static void time_setup(AWeatherGui *self)
 }
 
 
+/*************************
+ * Deprecated site stuff *
+ *************************/
+/* TODO: These update times functions are getting ugly... */
+static void update_times_gtk(AWeatherGui *self, GList *times)
+{
+       gchar *last_time = NULL;
+       GRegex *regex = g_regex_new("^[A-Z]{4}_([0-9]{8}_[0-9]{4})$", 0, 0, NULL); // KLSX_20090622_2113
+       GMatchInfo *info;
+
+       GtkTreeView  *tview  = GTK_TREE_VIEW(aweather_gui_get_widget(self, "time"));
+       GtkListStore *lstore = GTK_LIST_STORE(gtk_tree_view_get_model(tview));
+       gtk_list_store_clear(lstore);
+       GtkTreeIter iter;
+       times = g_list_reverse(times);
+       for (GList *cur = times; cur; cur = cur->next) {
+               g_message("trying time %s", (gchar*)cur->data);
+               if (g_regex_match(regex, cur->data, 0, &info)) {
+                       gchar *time = g_match_info_fetch(info, 1);
+                       g_message("adding time %s", (gchar*)cur->data);
+                       gtk_list_store_insert(lstore, &iter, 0);
+                       gtk_list_store_set(lstore, &iter, 0, time, -1);
+                       last_time = time;
+               }
+       }
+
+       gis_view_set_time(self->view, last_time);
+
+       g_regex_unref(regex);
+       g_list_foreach(times, (GFunc)g_free, NULL);
+       g_list_free(times);
+}
+static void update_times_online_cb(char *path, gboolean updated, gpointer _self)
+{
+       GList *times = NULL;
+       gchar *data;
+       gsize length;
+       g_file_get_contents(path, &data, &length, NULL);
+       gchar **lines = g_strsplit(data, "\n", -1);
+       for (int i = 0; lines[i] && lines[i][0]; i++) {
+               char **parts = g_strsplit(lines[i], " ", 2);
+               times = g_list_prepend(times, g_strdup(parts[1]));
+               g_strfreev(parts);
+       }
+       g_strfreev(lines);
+       g_free(data);
+
+       update_times_gtk(_self, times);
+}
+static void update_times(AWeatherGui *self, GisView *view, char *site)
+{
+       if (gis_world_get_offline(self->world)) {
+               GList *times = NULL;
+               gchar *path = g_build_filename(g_get_user_cache_dir(), PACKAGE, "nexrd2", "raw", site, NULL);
+               GDir *dir = g_dir_open(path, 0, NULL);
+               if (dir) {
+                       const gchar *name;
+                       while ((name = g_dir_read_name(dir))) {
+                               times = g_list_prepend(times, g_strdup(name));
+                       }
+                       g_dir_close(dir);
+               }
+               g_free(path);
+               update_times_gtk(self, times);
+       } else {
+               gchar *path = g_strdup_printf("nexrd2/raw/%s/dir.list", site);
+               char *base = gis_prefs_get_string(self->prefs, "general/nexrad_url");
+               cache_file(base, path, AWEATHER_REFRESH, NULL, update_times_online_cb, self);
+               /* update_times_gtk from update_times_online_cb */
+       }
+}
+static void on_gis_site_changed(GisView *view, char *site, gpointer _self)
+{
+       AWeatherGui *self = AWEATHER_GUI(_self);
+       g_debug("GisPluginRadar: on_site_changed - Loading wsr88d list for %s", site);
+       update_times(self, view, site);
+}
+static void on_gis_refresh(GisWorld *world, gpointer _self)
+{
+       AWeatherGui *self = AWEATHER_GUI(_self);
+       char *site = gis_view_get_site(self->view);
+       update_times(self, self->view, site);
+}
+
 /***********
  * Methods *
  ***********/
@@ -461,32 +537,17 @@ GObject *aweather_gui_get_object(AWeatherGui *self, const gchar *name)
        g_assert(AWEATHER_IS_GUI(self));
        return gtk_builder_get_object(self->builder, name);
 }
-gboolean aweather_gui_load_plugin(AWeatherGui *self, const char *name)
+void aweather_gui_attach_plugin(AWeatherGui *self, const gchar *name)
 {
-       gchar *path = g_strdup_printf("%s/%s.%s", PLUGINDIR, name, G_MODULE_SUFFIX);
-       GModule *module = g_module_open(path, 0);
-       g_free(path);
-       if (module == NULL) {
-               g_warning("Unable to load module %s: %s", name, g_module_error());
-               return FALSE;
-       }
-
-       AWeatherPlugin *(*constructor)();
-       gchar *constructor_str = g_strconcat("aweather_", name, "_new", NULL);
-       if (!g_module_symbol(module, constructor_str, (gpointer*)&constructor)) {
-               g_warning("Unable to load symbol %s from %s: %s",
-                               constructor_str, name, g_module_error());
-               g_module_close(module);
-               g_free(constructor_str);
-               return FALSE;
-       }
-       g_free(constructor_str);
-
-       self->plugins = g_list_append(self->plugins, constructor(self));
-       self->opengl->plugins = self->plugins;
-       return TRUE;
+       GisPlugin *plugin = gis_plugins_load(self->plugins, name,
+                       self->world, self->view, self->opengl, self->prefs);
+       GtkWidget *config = aweather_gui_get_widget(self, "tabs");
+       GtkWidget *tab    = gtk_label_new(name);
+       GtkWidget *body   = gis_plugin_get_config(plugin);
+       gtk_notebook_append_page(GTK_NOTEBOOK(config), body, tab);
+       gtk_widget_show_all(config);
 }
-gboolean aweather_gui_unload_plugin(AWeatherGui *self, const char *name)
+void aweather_gui_deattach_plugin(AWeatherGui *self, const gchar *name)
 {
-       return FALSE;
+       gis_plugins_unload(self->plugins, name);
 }
index 476cab1..eb28a55 100644 (file)
 
 #include <gtk/gtk.h>
 #include <glib-object.h>
-#include "gis-opengl.h"
-#include "gis-world.h"
-#include "gis-view.h"
-#include "aweather-plugin.h"
+
+#include <gis/gis.h>
 
 /* Type macros */
 #define AWEATHER_TYPE_GUI            (aweather_gui_get_type())
@@ -40,12 +38,12 @@ struct _AWeatherGui {
        GtkWindow parent_instance;
 
        /* instance members */
-       GtkBuilder *builder;
-       GisWorld   *world;
-       GisView    *view;
-       GisOpenGL  *opengl;
-       GList      *plugins;
-       GKeyFile   *prefs;
+       GtkBuilder   *builder;
+       GisWorld     *world;
+       GisView      *view;
+       GisOpenGL    *opengl;
+       GisPlugins   *plugins;
+       GisPrefs     *prefs;
        GtkListStore *gtk_plugins;
 };
 
@@ -67,7 +65,7 @@ GisView     *aweather_gui_get_view(AWeatherGui *gui);
 GtkWidget   *aweather_gui_get_widget(AWeatherGui *gui, const gchar *name);
 GObject     *aweather_gui_get_object(AWeatherGui *gui, const gchar *name);
 
-gboolean     aweather_gui_load_plugin(AWeatherGui *gui, const gchar *name);
-gboolean     aweather_gui_unload_plugin(AWeatherGui *gui, const gchar *name);
+void         aweather_gui_attach_plugin(AWeatherGui *self, const gchar *name);
+void         aweather_gui_deattach_plugin(AWeatherGui *self, const gchar *name);
 
 #endif
similarity index 99%
rename from src/location.c
rename to src/aweather-location.c
index 7d8ebe5..b893f39 100644 (file)
@@ -18,7 +18,7 @@
 #include <config.h>
 #include <gtk/gtk.h>
 
-#include "location.h"
+#include "aweather-location.h"
 
 city_t cities[] = {
        {LOCATION_STATE, NULL,   "Alabama",           {0, 0, 0, 0, 0, 0, 0, 0}},
similarity index 100%
rename from src/location.h
rename to src/aweather-location.h
diff --git a/src/aweather-plugin.h b/src/aweather-plugin.h
deleted file mode 100644 (file)
index 7ef76cd..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
- * 
- * 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 3 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __AWEATHER_PLUGIN_H__
-#define __AWEATHER_PLUGIN_H__
-
-#include <glib-object.h>
-
-#define AWEATHER_TYPE_PLUGIN                (aweather_plugin_get_type())
-#define AWEATHER_PLUGIN(obj)                (G_TYPE_CHECK_INSTANCE_CAST   ((obj),  AWEATHER_TYPE_PLUGIN, AWeatherPlugin))
-#define AWEATHER_IS_PLUGIN(obj)             (G_TYPE_CHECK_INSTANCE_TYPE   ((obj),  AWEATHER_TYPE_PLUGIN))
-#define AWEATHER_PLUGIN_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), AWEATHER_TYPE_PLUGIN, AWeatherPluginInterface))
-
-
-typedef struct _AWeatherPlugin          AWeatherPlugin;
-typedef struct _AWeatherPluginInterface AWeatherPluginInterface;
-
-struct _AWeatherPluginInterface
-{
-       GTypeInterface parent_iface;
-
-       /* Virtual functions */
-       void (*expose)(AWeatherPlugin *self);
-};
-
-GType aweather_plugin_get_type();
-
-/* Methods */
-void aweather_plugin_expose(AWeatherPlugin *self);
-
-#endif
diff --git a/src/gis/Makefile.am b/src/gis/Makefile.am
new file mode 100644 (file)
index 0000000..dd2588a
--- /dev/null
@@ -0,0 +1,21 @@
+AM_CFLAGS = -Wall -Werror -Wno-unused --std=gnu99 
+
+BUILT_SOURCES = gis-marshal.c gis-marshal.h
+lib_LTLIBRARIES  = libgis.la
+libgis_la_SOURCES = \
+       gis-prefs.c   gis-prefs.h  \
+       gis-world.c   gis-world.h  \
+       gis-view.c    gis-view.h   \
+       gis-opengl.c  gis-opengl.h \
+       gis-plugin.c  gis-plugin.h \
+       gis-data.c    gis-data.h   \
+       gis-marshal.c gis-marshal.h
+libgis_la_CPPFLAGS = -DPLUGINDIR="\"$(libdir)/aweather\"" $(SOUP_CFLAGS) $(GLIB_CFLAGS) $(GTK_CFLAGS)
+libgis_la_LIBADD = $(SOUP_LIBS) $(GLIB_LIBS) $(GTK_LIBS)
+
+MAINTAINERCLEANFILES = Makefile.in
+
+.list.c:
+       glib-genmarshal --prefix=gis_cclosure_marshal --body   $< > $@
+.list.h:
+       glib-genmarshal --prefix=gis_cclosure_marshal --header $< > $@
similarity index 99%
rename from src/data.c
rename to src/gis/gis-data.c
index 6186883..7c9f2c9 100644 (file)
@@ -20,7 +20,7 @@
 #include <glib.h>
 #include <libsoup/soup.h>
 
-#include "data.h"
+#include "gis-data.h"
 
 typedef struct {
        gchar *uri;
similarity index 100%
rename from src/data.h
rename to src/gis/gis-data.h
diff --git a/src/gis/gis-marshal.c b/src/gis/gis-marshal.c
new file mode 100644 (file)
index 0000000..23aa1db
--- /dev/null
@@ -0,0 +1,127 @@
+
+#include       <glib-object.h>
+
+
+#ifdef G_ENABLE_DEBUG
+#define g_marshal_value_peek_boolean(v)  g_value_get_boolean (v)
+#define g_marshal_value_peek_char(v)     g_value_get_char (v)
+#define g_marshal_value_peek_uchar(v)    g_value_get_uchar (v)
+#define g_marshal_value_peek_int(v)      g_value_get_int (v)
+#define g_marshal_value_peek_uint(v)     g_value_get_uint (v)
+#define g_marshal_value_peek_long(v)     g_value_get_long (v)
+#define g_marshal_value_peek_ulong(v)    g_value_get_ulong (v)
+#define g_marshal_value_peek_int64(v)    g_value_get_int64 (v)
+#define g_marshal_value_peek_uint64(v)   g_value_get_uint64 (v)
+#define g_marshal_value_peek_enum(v)     g_value_get_enum (v)
+#define g_marshal_value_peek_flags(v)    g_value_get_flags (v)
+#define g_marshal_value_peek_float(v)    g_value_get_float (v)
+#define g_marshal_value_peek_double(v)   g_value_get_double (v)
+#define g_marshal_value_peek_string(v)   (char*) g_value_get_string (v)
+#define g_marshal_value_peek_param(v)    g_value_get_param (v)
+#define g_marshal_value_peek_boxed(v)    g_value_get_boxed (v)
+#define g_marshal_value_peek_pointer(v)  g_value_get_pointer (v)
+#define g_marshal_value_peek_object(v)   g_value_get_object (v)
+#else /* !G_ENABLE_DEBUG */
+/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
+ *          Do not access GValues directly in your code. Instead, use the
+ *          g_value_get_*() functions
+ */
+#define g_marshal_value_peek_boolean(v)  (v)->data[0].v_int
+#define g_marshal_value_peek_char(v)     (v)->data[0].v_int
+#define g_marshal_value_peek_uchar(v)    (v)->data[0].v_uint
+#define g_marshal_value_peek_int(v)      (v)->data[0].v_int
+#define g_marshal_value_peek_uint(v)     (v)->data[0].v_uint
+#define g_marshal_value_peek_long(v)     (v)->data[0].v_long
+#define g_marshal_value_peek_ulong(v)    (v)->data[0].v_ulong
+#define g_marshal_value_peek_int64(v)    (v)->data[0].v_int64
+#define g_marshal_value_peek_uint64(v)   (v)->data[0].v_uint64
+#define g_marshal_value_peek_enum(v)     (v)->data[0].v_long
+#define g_marshal_value_peek_flags(v)    (v)->data[0].v_ulong
+#define g_marshal_value_peek_float(v)    (v)->data[0].v_float
+#define g_marshal_value_peek_double(v)   (v)->data[0].v_double
+#define g_marshal_value_peek_string(v)   (v)->data[0].v_pointer
+#define g_marshal_value_peek_param(v)    (v)->data[0].v_pointer
+#define g_marshal_value_peek_boxed(v)    (v)->data[0].v_pointer
+#define g_marshal_value_peek_pointer(v)  (v)->data[0].v_pointer
+#define g_marshal_value_peek_object(v)   (v)->data[0].v_pointer
+#endif /* !G_ENABLE_DEBUG */
+
+
+/* VOID:DOUBLE,DOUBLE,DOUBLE (gis-marshal.list:1) */
+void
+gis_cclosure_marshal_VOID__DOUBLE_DOUBLE_DOUBLE (GClosure     *closure,
+                                                 GValue       *return_value G_GNUC_UNUSED,
+                                                 guint         n_param_values,
+                                                 const GValue *param_values,
+                                                 gpointer      invocation_hint G_GNUC_UNUSED,
+                                                 gpointer      marshal_data)
+{
+  typedef void (*GMarshalFunc_VOID__DOUBLE_DOUBLE_DOUBLE) (gpointer     data1,
+                                                           gdouble      arg_1,
+                                                           gdouble      arg_2,
+                                                           gdouble      arg_3,
+                                                           gpointer     data2);
+  register GMarshalFunc_VOID__DOUBLE_DOUBLE_DOUBLE callback;
+  register GCClosure *cc = (GCClosure*) closure;
+  register gpointer data1, data2;
+
+  g_return_if_fail (n_param_values == 4);
+
+  if (G_CCLOSURE_SWAP_DATA (closure))
+    {
+      data1 = closure->data;
+      data2 = g_value_peek_pointer (param_values + 0);
+    }
+  else
+    {
+      data1 = g_value_peek_pointer (param_values + 0);
+      data2 = closure->data;
+    }
+  callback = (GMarshalFunc_VOID__DOUBLE_DOUBLE_DOUBLE) (marshal_data ? marshal_data : cc->callback);
+
+  callback (data1,
+            g_marshal_value_peek_double (param_values + 1),
+            g_marshal_value_peek_double (param_values + 2),
+            g_marshal_value_peek_double (param_values + 3),
+            data2);
+}
+
+/* VOID:STRING,UINT,POINTER (gis-marshal.list:2) */
+void
+gis_cclosure_marshal_VOID__STRING_UINT_POINTER (GClosure     *closure,
+                                                GValue       *return_value G_GNUC_UNUSED,
+                                                guint         n_param_values,
+                                                const GValue *param_values,
+                                                gpointer      invocation_hint G_GNUC_UNUSED,
+                                                gpointer      marshal_data)
+{
+  typedef void (*GMarshalFunc_VOID__STRING_UINT_POINTER) (gpointer     data1,
+                                                          gpointer     arg_1,
+                                                          guint        arg_2,
+                                                          gpointer     arg_3,
+                                                          gpointer     data2);
+  register GMarshalFunc_VOID__STRING_UINT_POINTER callback;
+  register GCClosure *cc = (GCClosure*) closure;
+  register gpointer data1, data2;
+
+  g_return_if_fail (n_param_values == 4);
+
+  if (G_CCLOSURE_SWAP_DATA (closure))
+    {
+      data1 = closure->data;
+      data2 = g_value_peek_pointer (param_values + 0);
+    }
+  else
+    {
+      data1 = g_value_peek_pointer (param_values + 0);
+      data2 = closure->data;
+    }
+  callback = (GMarshalFunc_VOID__STRING_UINT_POINTER) (marshal_data ? marshal_data : cc->callback);
+
+  callback (data1,
+            g_marshal_value_peek_string (param_values + 1),
+            g_marshal_value_peek_uint (param_values + 2),
+            g_marshal_value_peek_pointer (param_values + 3),
+            data2);
+}
+
diff --git a/src/gis/gis-marshal.h b/src/gis/gis-marshal.h
new file mode 100644 (file)
index 0000000..ca695bf
--- /dev/null
@@ -0,0 +1,28 @@
+
+#ifndef __gis_cclosure_marshal_MARSHAL_H__
+#define __gis_cclosure_marshal_MARSHAL_H__
+
+#include       <glib-object.h>
+
+G_BEGIN_DECLS
+
+/* VOID:DOUBLE,DOUBLE,DOUBLE (gis-marshal.list:1) */
+extern void gis_cclosure_marshal_VOID__DOUBLE_DOUBLE_DOUBLE (GClosure     *closure,
+                                                             GValue       *return_value,
+                                                             guint         n_param_values,
+                                                             const GValue *param_values,
+                                                             gpointer      invocation_hint,
+                                                             gpointer      marshal_data);
+
+/* VOID:STRING,UINT,POINTER (gis-marshal.list:2) */
+extern void gis_cclosure_marshal_VOID__STRING_UINT_POINTER (GClosure     *closure,
+                                                            GValue       *return_value,
+                                                            guint         n_param_values,
+                                                            const GValue *param_values,
+                                                            gpointer      invocation_hint,
+                                                            gpointer      marshal_data);
+
+G_END_DECLS
+
+#endif /* __gis_cclosure_marshal_MARSHAL_H__ */
+
similarity index 50%
rename from src/marshal.list
rename to src/gis/gis-marshal.list
index 32d7404..f588897 100644 (file)
@@ -1 +1,2 @@
 VOID:DOUBLE,DOUBLE,DOUBLE
+VOID:STRING,UINT,POINTER
similarity index 94%
rename from src/gis-opengl.c
rename to src/gis/gis-opengl.c
index 46eae60..acf12eb 100644 (file)
 #include <GL/gl.h>
 #include <GL/glu.h>
 
-#include "misc.h"
-#include "aweather-gui.h"
-#include "gis-world.h"
-#include "gis-view.h"
 #include "gis-opengl.h"
 
 /****************
@@ -40,7 +36,7 @@ static void gis_opengl_init(GisOpenGL *self)
 static GObject *gis_opengl_constructor(GType gtype, guint n_properties,
                GObjectConstructParam *properties)
 {
-       g_debug("gis_opengl: constructor");
+       g_debug("GisOpengl: constructor");
        GObjectClass *parent_class = G_OBJECT_CLASS(gis_opengl_parent_class);
        return  parent_class->constructor(gtype, n_properties, properties);
 }
@@ -141,8 +137,8 @@ gboolean on_configure(GtkWidget *drawing, GdkEventConfigure *event, GisOpenGL *s
        gis_view_get_location(self->view, &x, &y, &z);
 
        /* Window is at 500 m from camera */
-       double width  = GTK_WIDGET(self->drawing)->allocation.width;
-       double height = GTK_WIDGET(self->drawing)->allocation.height;
+       double width  = drawing->allocation.width;
+       double height = drawing->allocation.height;
 
        glViewport(0, 0, width, height);
 
@@ -176,13 +172,7 @@ gboolean on_expose(GtkWidget *drawing, GdkEventExpose *event, GisOpenGL *self)
        glRotatef(rz, 0, 0, 1);
 
        /* Expose plugins */
-       /* TODO: Figure out how to handle plugins:
-        *   - Do they belong to AWeatherGui, GisOpenGL, etc?
-        */
-       for (GList *cur = self->plugins; cur; cur = cur->next) {
-               AWeatherPlugin *plugin = AWEATHER_PLUGIN(cur->data);
-               aweather_plugin_expose(plugin);
-       }
+       gis_plugins_foreach(self->plugins, G_CALLBACK(gis_plugin_expose), NULL);
 
        gis_opengl_end(self);
        gis_opengl_flush(self);
@@ -208,6 +198,7 @@ GisOpenGL *gis_opengl_new(GisWorld *world, GisView *view, GtkDrawingArea *drawin
        self->world   = world;
        self->view    = view;
        self->drawing = drawing;
+       g_message("drawing = %p", drawing);
        g_object_ref(world);
        g_object_ref(view);
        g_object_ref(drawing);
@@ -244,6 +235,7 @@ void gis_opengl_begin(GisOpenGL *self)
 {
        g_assert(GIS_IS_OPENGL(self));
 
+       g_message("drawing = %p", self->drawing);
        GdkGLContext   *glcontext  = gtk_widget_get_gl_context(GTK_WIDGET(self->drawing));
        GdkGLDrawable  *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(self->drawing));
 
similarity index 94%
rename from src/gis-opengl.h
rename to src/gis/gis-opengl.h
index aca186f..e814969 100644 (file)
@@ -23,9 +23,6 @@
 #include <gtk/gtkgl.h>
 #include <glib-object.h>
 
-#include "gis-view.h"
-#include "gis-world.h"
-
 /* Type macros */
 #define GIS_TYPE_OPENGL            (gis_opengl_get_type())
 #define GIS_OPENGL(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),   GIS_TYPE_OPENGL, GisOpenGL))
 typedef struct _GisOpenGL      GisOpenGL;
 typedef struct _GisOpenGLClass GisOpenGLClass;
 
+#include "gis-view.h"
+#include "gis-world.h"
+#include "gis-plugin.h"
+
+#define d2r(deg) (((deg)*M_PI)/180.0)
+#define r2d(rad) (((rad)*180.0)/M_PI)
+
 struct _GisOpenGL {
        GObject parent_instance;
 
        /* instance members */
        GisWorld       *world;
        GisView        *view;
+       GisPlugins     *plugins;
        GtkDrawingArea *drawing;
-       GList          *plugins;
 };
 
 struct _GisOpenGLClass {
diff --git a/src/gis/gis-plugin.c b/src/gis/gis-plugin.c
new file mode 100644 (file)
index 0000000..e15c53c
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
+ * 
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+#include <gmodule.h>
+
+#include "gis-plugin.h"
+
+static void gis_plugin_base_init(gpointer g_class)
+{
+       static gboolean is_initialized = FALSE;
+       if (!is_initialized) {
+               /* add properties and signals to the interface here */
+               is_initialized = TRUE;
+       }
+}
+
+GType gis_plugin_get_type()
+{
+       static GType type = 0;
+       if (type == 0) {
+               static const GTypeInfo info = {
+                       sizeof(GisPluginInterface),
+                       gis_plugin_base_init,
+                       NULL,
+               };
+               type = g_type_register_static(G_TYPE_INTERFACE,
+                               "GisPlugin", &info, 0);
+       }
+       return type;
+}
+
+void gis_plugin_expose(GisPlugin *self)
+{
+       g_return_if_fail(GIS_IS_PLUGIN(self));
+       GIS_PLUGIN_GET_INTERFACE(self)->expose(self);
+}
+
+GtkWidget *gis_plugin_get_config(GisPlugin *self)
+{
+       g_return_val_if_fail(GIS_IS_PLUGIN(self), NULL);
+       return GIS_PLUGIN_GET_INTERFACE(self)->get_config(self);
+}
+
+/* Plugins API */
+typedef struct {
+       gchar *name;
+       GisPlugin *plugin;
+} GisPluginStore;
+
+GisPlugins *gis_plugins_new()
+{
+       return g_ptr_array_new();
+}
+
+void gis_plugins_free(GisPlugins *self)
+{
+       for (int i = 0; i < self->len; i++) {
+               GisPluginStore *store = g_ptr_array_index(self, i);
+               g_object_unref(store->plugin);
+               g_free(store->name);
+               g_free(store);
+               g_ptr_array_remove_index(self, i);
+       }
+       g_ptr_array_free(self, TRUE);
+}
+
+GList *gis_plugins_available()
+{
+       GDir *dir = g_dir_open(PLUGINDIR, 0, NULL);
+       GList *list = NULL;
+       const gchar *name;
+       while ((name = g_dir_read_name(dir))) {
+               if (g_pattern_match_simple("*.so", name)) {
+                       gchar **parts = g_strsplit(name, ".", 2);
+                       list = g_list_prepend(list, g_strdup(parts[0]));
+                       g_strfreev(parts);
+               }
+       }
+       return list;
+}
+
+GisPlugin *gis_plugins_load(GisPlugins *self, const char *name,
+               GisWorld *world, GisView *view, GisOpenGL *opengl, GisPrefs *prefs)
+{
+       gchar *path = g_strdup_printf("%s/%s.%s", PLUGINDIR, name, G_MODULE_SUFFIX);
+       GModule *module = g_module_open(path, 0);
+       g_free(path);
+       if (module == NULL) {
+               g_warning("Unable to load module %s: %s", name, g_module_error());
+               return NULL;
+       }
+
+       GisPluginConstructor constructor;
+       gchar *constructor_str = g_strconcat("gis_plugin_", name, "_new", NULL);
+       if (!g_module_symbol(module, constructor_str, (gpointer*)&constructor)) {
+               g_warning("Unable to load symbol %s from %s: %s",
+                               constructor_str, name, g_module_error());
+               g_module_close(module);
+               g_free(constructor_str);
+               return NULL;
+       }
+       g_free(constructor_str);
+
+       GisPluginStore *store = g_malloc(sizeof(GisPluginStore));
+       store->name = g_strdup(name);
+       store->plugin = constructor(world, view, opengl, prefs);
+       g_ptr_array_add(self, store);
+       return store->plugin;
+}
+
+gboolean gis_plugins_unload(GisPlugins *self, const char *name)
+{
+       for (int i = 0; i < self->len; i++) {
+               GisPluginStore *store = g_ptr_array_index(self, i);
+               if (g_str_equal(store->name, name)) {
+                       g_object_unref(store->plugin);
+                       g_free(store->name);
+                       g_free(store);
+                       g_ptr_array_remove_index(self, i);
+               }
+       }
+       return FALSE;
+}
+void gis_plugins_foreach(GisPlugins *self, GCallback _callback, gpointer user_data)
+{
+       typedef void (*CBFunc)(GisPlugin *, const gchar *, gpointer);
+       CBFunc callback = (CBFunc)_callback;
+       for (int i = 0; i < self->len; i++) {
+               GisPluginStore *store = g_ptr_array_index(self, i);
+               callback(store->plugin, store->name, user_data);
+       }
+}
diff --git a/src/gis/gis-plugin.h b/src/gis/gis-plugin.h
new file mode 100644 (file)
index 0000000..a667fba
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
+ * 
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIS_PLUGIN_H__
+#define __GIS_PLUGIN_H__
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#define GIS_TYPE_PLUGIN                (gis_plugin_get_type())
+#define GIS_PLUGIN(obj)                (G_TYPE_CHECK_INSTANCE_CAST   ((obj),  GIS_TYPE_PLUGIN, GisPlugin))
+#define GIS_IS_PLUGIN(obj)             (G_TYPE_CHECK_INSTANCE_TYPE   ((obj),  GIS_TYPE_PLUGIN))
+#define GIS_PLUGIN_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), GIS_TYPE_PLUGIN, GisPluginInterface))
+
+typedef struct _GisPlugin          GisPlugin;
+typedef struct _GisPluginInterface GisPluginInterface;
+typedef GPtrArray                  GisPlugins;
+
+struct _GisPluginInterface
+{
+       GTypeInterface parent_iface;
+
+       /* Virtual functions */
+       void       (*expose    )(GisPlugin *self);
+       GtkWidget *(*get_config)(GisPlugin *self);
+};
+
+GType gis_plugin_get_type();
+
+/* Methods */
+void       gis_plugin_expose(GisPlugin *self);
+GtkWidget *gis_plugin_get_config(GisPlugin *self);
+
+/* Plugins API */
+#include "gis-world.h"
+#include "gis-view.h"
+#include "gis-opengl.h"
+#include "gis-prefs.h"
+
+typedef GisPlugin *(*GisPluginConstructor)(GisWorld *world, GisView *view, GisOpenGL *opengl, GisPrefs *prefs);
+
+GisPlugins *gis_plugins_new();
+void        gis_plugins_free();
+GList      *gis_plugins_available();
+GisPlugin  *gis_plugins_load(GisPlugins *self, const char *name,
+               GisWorld *world, GisView *view, GisOpenGL *opengl, GisPrefs *prefs);
+gboolean    gis_plugins_unload(GisPlugins *self, const char *name);
+void        gis_plugins_foreach(GisPlugins *self, GCallback callback, gpointer user_data);
+
+#endif
diff --git a/src/gis/gis-prefs.c b/src/gis/gis-prefs.c
new file mode 100644 (file)
index 0000000..2b3829a
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
+ * 
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+#include "gis-marshal.h"
+#include "gis-prefs.h"
+
+/****************
+ * GObject code *
+ ****************/
+enum {
+       SIG_PREF_CHANGED,
+       NUM_SIGNALS,
+};
+static guint signals[NUM_SIGNALS];
+
+G_DEFINE_TYPE(GisPrefs, gis_prefs, G_TYPE_OBJECT);
+static void gis_prefs_init(GisPrefs *self)
+{
+       g_debug("GisPrefs: init");
+       self->key_file = g_key_file_new();
+}
+static GObject *gis_prefs_constructor(GType gtype, guint n_properties,
+               GObjectConstructParam *properties)
+{
+       g_debug("gis_prefs: constructor");
+       GObjectClass *parent_class = G_OBJECT_CLASS(gis_prefs_parent_class);
+       return  parent_class->constructor(gtype, n_properties, properties);
+}
+static void gis_prefs_dispose(GObject *_self)
+{
+       g_debug("GisPrefs: dispose");
+       GisPrefs *self = GIS_PREFS(_self);
+       if (self->key_file) {
+               gsize length;
+               g_mkdir_with_parents(g_path_get_dirname(self->key_path), 0755);
+               gchar *data = g_key_file_to_data(self->key_file, &length, NULL);
+               g_file_set_contents(self->key_path, data, length, NULL);
+               g_key_file_free(self->key_file);
+               self->key_file = NULL;
+       }
+       G_OBJECT_CLASS(gis_prefs_parent_class)->dispose(_self);
+}
+static void gis_prefs_finalize(GObject *_self)
+{
+       g_debug("GisPrefs: finalize");
+       G_OBJECT_CLASS(gis_prefs_parent_class)->finalize(_self);
+}
+static void gis_prefs_class_init(GisPrefsClass *klass)
+{
+       g_debug("GisPrefs: class_init");
+       GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+       gobject_class->constructor  = gis_prefs_constructor;
+       gobject_class->dispose      = gis_prefs_dispose;
+       gobject_class->finalize     = gis_prefs_finalize;
+       signals[SIG_PREF_CHANGED] = g_signal_new(
+                       "pref-changed",
+                       G_TYPE_FROM_CLASS(gobject_class),
+                       G_SIGNAL_RUN_LAST,
+                       0,
+                       NULL,
+                       NULL,
+                       gis_cclosure_marshal_VOID__STRING_UINT_POINTER,
+                       G_TYPE_NONE,
+                       1,
+                       G_TYPE_STRING,
+                       G_TYPE_UINT,
+                       G_TYPE_POINTER);
+}
+
+/***********
+ * Methods *
+ ***********/
+GisPrefs *gis_prefs_new(const gchar *prog)
+{
+       g_debug("GisPrefs: new - %s", prog);
+       GisPrefs *self = g_object_new(GIS_TYPE_PREFS, NULL);
+       self->key_path = g_build_filename(g_get_user_config_dir(),
+                       prog, "config.ini", NULL);
+       GError *error = NULL;
+       g_key_file_load_from_file(self->key_file, self->key_path,
+                       G_KEY_FILE_KEEP_COMMENTS, &error);
+       if (error)
+               g_warning("GisPrefs: init - Unable to load key file `%s': %s",
+                       self->key_path, error->message);
+       return self;
+}
+
+#define make_pref_type(name, c_type, g_type)                                         \
+c_type gis_prefs_get_##name##_v(GisPrefs *self,                                      \
+               const gchar *group, const gchar *key)                                \
+{                                                                                    \
+       GError *error = NULL;                                                        \
+       c_type value = g_key_file_get_##name(self->key_file, group, key, &error);    \
+       if (error && error->code != G_KEY_FILE_ERROR_GROUP_NOT_FOUND)                \
+               g_warning("GisPrefs: get_value_##name - error getting key %s: %s\n", \
+                               key, error->message);                                \
+       return value;                                                                \
+}                                                                                    \
+c_type gis_prefs_get_##name(GisPrefs *self, const gchar *key)                        \
+{                                                                                    \
+       gchar **keys  = g_strsplit(key, "/", 2);                                     \
+       c_type value = gis_prefs_get_##name##_v(self, keys[0], keys[1]);             \
+       g_strfreev(keys);                                                            \
+       return value;                                                                \
+}                                                                                    \
+                                                                                     \
+void gis_prefs_set_##name##_v(GisPrefs *self,                                        \
+               const gchar *group, const gchar *key, const c_type value)            \
+{                                                                                    \
+       g_key_file_set_##name(self->key_file, group, key, value);                    \
+       gchar *all = g_strconcat(group, "/", key, NULL);                             \
+       g_signal_emit(self, signals[SIG_PREF_CHANGED], 0,                            \
+                       all, g_type, &value);                                        \
+       g_free(all);                                                                 \
+}                                                                                    \
+void gis_prefs_set_##name(GisPrefs *self, const gchar *key, const c_type value)      \
+{                                                                                    \
+       gchar **keys = g_strsplit(key, "/", 2);                                      \
+       gis_prefs_set_##name##_v(self, keys[0], keys[1], value);                     \
+       g_strfreev(keys);                                                            \
+}                                                                                    \
+
+make_pref_type(string,  gchar*,   G_TYPE_STRING)
+make_pref_type(boolean, gboolean, G_TYPE_BOOLEAN)
+make_pref_type(integer, gint,     G_TYPE_INT)
+make_pref_type(double,  gdouble,  G_TYPE_DOUBLE)
diff --git a/src/gis/gis-prefs.h b/src/gis/gis-prefs.h
new file mode 100644 (file)
index 0000000..1645734
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
+ * 
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIS_PREFS_H__
+#define __GIS_PREFS_H__
+
+#include <glib-object.h>
+
+/* Type macros */
+#define GIS_TYPE_PREFS            (gis_prefs_get_type())
+#define GIS_PREFS(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),   GIS_TYPE_PREFS, GisPrefs))
+#define GIS_IS_PREFS(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),   GIS_TYPE_PREFS))
+#define GIS_PREFS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST   ((klass), GIS_TYPE_PREFS, GisPrefsClass))
+#define GIS_IS_PREFS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE   ((klass), GIS_TYPE_PREFS))
+#define GIS_PREFS_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),   GIS_TYPE_PREFS, GisPrefsClass))
+
+typedef struct _GisPrefs      GisPrefs;
+typedef struct _GisPrefsClass GisPrefsClass;
+
+struct _GisPrefs {
+       GObject parent_instance;
+
+       /* instance members */
+       gchar    *key_path;
+       GKeyFile *key_file;
+};
+
+struct _GisPrefsClass {
+       GObjectClass parent_class;
+       
+       /* class members */
+};
+
+GType gis_prefs_get_type(void);
+
+/* Methods */
+GisPrefs *gis_prefs_new(const gchar *prog);
+
+gchar    *gis_prefs_get_string   (GisPrefs *prefs, const gchar *key);
+gboolean  gis_prefs_get_boolean  (GisPrefs *prefs, const gchar *key);
+gint      gis_prefs_get_integer  (GisPrefs *prefs, const gchar *key);
+gdouble   gis_prefs_get_double   (GisPrefs *prefs, const gchar *key);
+
+gchar    *gis_prefs_get_string_v (GisPrefs *prefs, const gchar *group, const gchar *key);
+gboolean  gis_prefs_get_boolean_v(GisPrefs *prefs, const gchar *group, const gchar *key);
+gint      gis_prefs_get_integer_v(GisPrefs *prefs, const gchar *group, const gchar *key);
+gdouble   gis_prefs_get_double_v (GisPrefs *prefs, const gchar *group, const gchar *key);
+
+void      gis_prefs_set_string   (GisPrefs *prefs, const gchar *key, const gchar *string);
+void      gis_prefs_set_boolean  (GisPrefs *prefs, const gchar *key, gboolean value);
+void      gis_prefs_set_integer  (GisPrefs *prefs, const gchar *key, gint value);
+void      gis_prefs_set_double   (GisPrefs *prefs, const gchar *key, gdouble value);
+
+void      gis_prefs_set_string_v (GisPrefs *prefs, const gchar *group, const gchar *key, const gchar *string);
+void      gis_prefs_set_boolean_v(GisPrefs *prefs, const gchar *group, const gchar *key, gboolean value);
+void      gis_prefs_set_integer_v(GisPrefs *prefs, const gchar *group, const gchar *key, gint value);
+void      gis_prefs_set_double_v (GisPrefs *prefs, const gchar *group, const gchar *key, gdouble value);
+#endif
similarity index 97%
rename from src/gis-view.c
rename to src/gis/gis-view.c
index e43aefb..409aa68 100644 (file)
@@ -17,7 +17,7 @@
 
 #include <glib.h>
 
-#include "marshal.h"
+#include "gis-marshal.h"
 #include "gis-view.h"
 
 /****************
@@ -138,7 +138,7 @@ static void gis_view_class_init(GisViewClass *klass)
                        0,
                        NULL,
                        NULL,
-                       aweather_cclosure_marshal_VOID__DOUBLE_DOUBLE_DOUBLE,
+                       gis_cclosure_marshal_VOID__DOUBLE_DOUBLE_DOUBLE,
                        G_TYPE_NONE,
                        3,
                        G_TYPE_DOUBLE,
@@ -151,7 +151,7 @@ static void gis_view_class_init(GisViewClass *klass)
                        0,
                        NULL,
                        NULL,
-                       aweather_cclosure_marshal_VOID__DOUBLE_DOUBLE_DOUBLE,
+                       gis_cclosure_marshal_VOID__DOUBLE_DOUBLE_DOUBLE,
                        G_TYPE_NONE,
                        3,
                        G_TYPE_DOUBLE,
@@ -290,6 +290,6 @@ void gis_view_set_site(GisView *view, const gchar *site)
 gchar *gis_view_get_site(GisView *view)
 {
        g_assert(GIS_IS_VIEW(view));
-       g_debug("GisView: get_site");
+       g_debug("GisView: get_site - %s", view->site);
        return view->site;
 }
similarity index 100%
rename from src/gis-view.h
rename to src/gis/gis-view.h
similarity index 99%
rename from src/gis-world.c
rename to src/gis/gis-world.c
index 2987911..9d7ecb2 100644 (file)
@@ -17,7 +17,7 @@
 
 #include <glib.h>
 
-#include "marshal.h"
+#include "gis-marshal.h"
 #include "gis-world.h"
 
 /****************
@@ -125,3 +125,5 @@ gboolean gis_world_get_offline(GisWorld *world)
        g_debug("GisWorld: get_offline - %d", world->offline);
        return world->offline;
 }
+
+
similarity index 100%
rename from src/gis-world.h
rename to src/gis/gis-world.h
similarity index 50%
rename from src/aweather-plugin.c
rename to src/gis/gis.h
index 87cf35c..be6cbc3 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <glib.h>
+#ifndef __GIS_H__
+#define __GIS_H__
 
-#include "aweather-plugin.h"
+/* GIS Core */
+#include "gis-world.h"
+#include "gis-view.h"
+#include "gis-opengl.h"
+#include "gis-prefs.h"
 
-static void aweather_plugin_base_init(gpointer g_class)
-{
-       static gboolean is_initialized = FALSE;
-       if (!is_initialized) {
-               /* add properties and signals to the interface here */
-               is_initialized = TRUE;
-       }
-}
+/* GIS helprs */
+#include "gis-data.h"
+#include "gis-marshal.h"
 
-GType aweather_plugin_get_type()
-{
-       static GType type = 0;
-       if (type == 0) {
-               static const GTypeInfo info = {
-                       sizeof(AWeatherPluginInterface),
-                       aweather_plugin_base_init,
-                       NULL,
-               };
-               type = g_type_register_static(G_TYPE_INTERFACE,
-                               "AWeatherPlugin", &info, 0);
-       }
-       return type;
-}
+/* Plugins */
+#include "gis-plugin.h"
 
-void aweather_plugin_expose(AWeatherPlugin *self)
-{
-       g_return_if_fail(AWEATHER_IS_PLUGIN(self));
-       AWEATHER_PLUGIN_GET_INTERFACE(self)->expose(self);
-}
+#endif
index 6db1393..aa02ea9 100644 (file)
 #include <gtk/gtk.h>
 #include <gtk/gtkgl.h>
 
+#include <gis/gis.h>
+
 #include "aweather-gui.h"
-#include "aweather-plugin.h"
-#include "gis-view.h"
-#include "gis-world.h"
 
 static gint log_levels = 0;
 
@@ -82,9 +81,6 @@ int main(int argc, char *argv[])
        g_log_set_handler(NULL, G_LOG_LEVEL_MASK, log_func, NULL);
 
        /* Set up AWeather */
-       /* TODO: Figure out a better way to do plugins
-        *    AWeatherPlugin interface for tabs?
-        *    GisPlugin      interface for expose? */
        AWeatherGui *gui    = aweather_gui_new();
        GisWorld    *world  = aweather_gui_get_world(gui);
        GisOpenGL   *opengl = aweather_gui_get_opengl(gui);
index 14a3bfc..7a0c4be 100644 (file)
@@ -1,7 +1,6 @@
-AM_CFLAGS = -Wall -Werror -Wno-unused --std=gnu99  -I../ \
-       $(RSL_CFLAGS) $(SOUP_CFLAGS) $(GLIB_CFLAGS) $(GTK_CFLAGS)
-AM_LDFLAGS = -module \
-       $(RSL_LIBS) $(SOUP_LIBS) $(GLIB_LIBS) $(GTK_LIBS)
+AM_CFLAGS   = -Wall -Werror -Wno-unused --std=gnu99  -I../
+AM_CPPFLAGS = $(GLIB_CFLAGS) $(GTK_CFLAGS)
+AM_LDFLAGS  = -module $(GLIB_LIBS) $(GTK_LIBS)
 
 plugindir = $(libdir)/aweather
 
@@ -13,15 +12,18 @@ plugin_LTLIBRARIES = \
 example_la_SOURCES = \
        example.c \
        example.h
+example_la_CPPFLAGS = $(AM_CPPFLAGS) $(SOUP_CFLAGS)
 
 ridge_la_SOURCES = \
        ridge.c \
        ridge.h
+ridge_la_CPPFLAGS = $(AM_CPPFLAGS) $(SOUP_CFLAGS)
 
 radar_la_SOURCES = \
        radar.c \
        radar.h \
        radar-colormap.c
-
+radar_la_CPPFLAGS = $(AM_CPPFLAGS) $(SOUP_CFLAGS) $(RSL_CFLAGS)
+radar_la_LIBADD = $(SOUP_LIBS) $(RSL_LIBS)
 
 MAINTAINERCLEANFILES = Makefile.in
index dd9f905..3930fb5 100644 (file)
 #include <gtk/gtkgl.h>
 #include <GL/gl.h>
 
-#include "aweather-gui.h"
+#include <gis/gis.h>
+
 #include "example.h"
 
 /****************
  * GObject code *
  ****************/
 /* Plugin init */
-static void aweather_example_plugin_init(AWeatherPluginInterface *iface);
-static void aweather_example_expose(AWeatherPlugin *_self);
-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_plugin_init(AWeatherPluginInterface *iface)
+static void gis_plugin_example_plugin_init(GisPluginInterface *iface);
+static void gis_plugin_example_expose(GisPlugin *_self);
+static GtkWidget *gis_plugin_example_get_config(GisPlugin *_self);
+G_DEFINE_TYPE_WITH_CODE(GisPluginExample, gis_plugin_example, G_TYPE_OBJECT,
+               G_IMPLEMENT_INTERFACE(GIS_TYPE_PLUGIN,
+                       gis_plugin_example_plugin_init));
+static void gis_plugin_example_plugin_init(GisPluginInterface *iface)
 {
-       g_debug("AWeatherExample: plugin_init");
+       g_debug("GisPluginExample: plugin_init");
        /* Add methods to the interface */
-       iface->expose = aweather_example_expose;
+       iface->expose     = gis_plugin_example_expose;
+       iface->get_config = gis_plugin_example_get_config;
 }
 /* Class/Object init */
-static void aweather_example_init(AWeatherExample *self)
+static void gis_plugin_example_init(GisPluginExample *self)
 {
-       g_debug("AWeatherExample: init");
+       g_debug("GisPluginExample: init");
        /* Set defaults */
-       self->gui      = NULL;
+       self->opengl   = NULL;
        self->button   = NULL;
        self->rotation = 30.0;
 }
-static void aweather_example_dispose(GObject *gobject)
+static void gis_plugin_example_dispose(GObject *gobject)
 {
-       g_debug("AWeatherExample: dispose");
-       AWeatherExample *self = AWEATHER_EXAMPLE(gobject);
+       g_debug("GisPluginExample: dispose");
+       GisPluginExample *self = GIS_PLUGIN_EXAMPLE(gobject);
        /* Drop references */
-       G_OBJECT_CLASS(aweather_example_parent_class)->dispose(gobject);
+       G_OBJECT_CLASS(gis_plugin_example_parent_class)->dispose(gobject);
 }
-static void aweather_example_finalize(GObject *gobject)
+static void gis_plugin_example_finalize(GObject *gobject)
 {
-       g_debug("AWeatherExample: finalize");
-       AWeatherExample *self = AWEATHER_EXAMPLE(gobject);
+       g_debug("GisPluginExample: finalize");
+       GisPluginExample *self = GIS_PLUGIN_EXAMPLE(gobject);
        /* Free data */
-       G_OBJECT_CLASS(aweather_example_parent_class)->finalize(gobject);
+       G_OBJECT_CLASS(gis_plugin_example_parent_class)->finalize(gobject);
 
 }
-static void aweather_example_class_init(AWeatherExampleClass *klass)
+static void gis_plugin_example_class_init(GisPluginExampleClass *klass)
 {
-       g_debug("AWeatherExample: class_init");
+       g_debug("GisPluginExample: class_init");
        GObjectClass *gobject_class = (GObjectClass*)klass;
-       gobject_class->dispose  = aweather_example_dispose;
-       gobject_class->finalize = aweather_example_finalize;
+       gobject_class->dispose  = gis_plugin_example_dispose;
+       gobject_class->finalize = gis_plugin_example_finalize;
 }
 
 /***********
@@ -75,10 +78,10 @@ static void aweather_example_class_init(AWeatherExampleClass *klass)
  ***********/
 static gboolean rotate(gpointer _self)
 {
-       AWeatherExample *self = _self;
+       GisPluginExample *self = _self;
        if (gtk_toggle_button_get_active(self->button)) {
                self->rotation += 1.0;
-               gis_opengl_redraw(aweather_gui_get_opengl(self->gui));
+               gis_opengl_redraw(self->opengl);
        }
        return TRUE;
 }
@@ -86,31 +89,29 @@ static gboolean rotate(gpointer _self)
 /***********
  * Methods *
  ***********/
-AWeatherExample *aweather_example_new(AWeatherGui *gui)
+GisPluginExample *gis_plugin_example_new(GisWorld *world, GisView *view, GisOpenGL *opengl)
 {
-       g_debug("AWeatherExample: new");
-       AWeatherExample *self = g_object_new(AWEATHER_TYPE_EXAMPLE, NULL);
-       self->gui = gui;
-
-       GtkWidget *drawing = aweather_gui_get_widget(gui, "drawing");
-       GtkWidget *config  = aweather_gui_get_widget(gui, "tabs");
-
-       /* Add configuration tab */
-       GtkWidget *label = gtk_label_new("Example");
+       g_debug("GisPluginExample: new");
+       GisPluginExample *self = g_object_new(GIS_TYPE_PLUGIN_EXAMPLE, NULL);
+       self->opengl = opengl;
        self->button = GTK_TOGGLE_BUTTON(gtk_toggle_button_new_with_label("Rotate"));
-       gtk_notebook_append_page(GTK_NOTEBOOK(config), GTK_WIDGET(self->button), label);
 
        /* Set up OpenGL Stuff */
-       //g_signal_connect(drawing, "expose-event", G_CALLBACK(expose), NULL);
        g_timeout_add(1000/60, rotate, self);
 
        return self;
 }
 
-static void aweather_example_expose(AWeatherPlugin *_self)
+static GtkWidget *gis_plugin_example_get_config(GisPlugin *_self)
+{
+       GisPluginExample *self = GIS_PLUGIN_EXAMPLE(_self);
+       return GTK_WIDGET(self->button);
+}
+
+static void gis_plugin_example_expose(GisPlugin *_self)
 {
-       AWeatherExample *self = AWEATHER_EXAMPLE(_self);
-       g_debug("AWeatherExample: expose");
+       GisPluginExample *self = GIS_PLUGIN_EXAMPLE(_self);
+       g_debug("GisPluginExample: expose");
        glDisable(GL_TEXTURE_2D);
        glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity();
        glOrtho(-1,1,-1,1,-10,10);
@@ -130,7 +131,6 @@ static void aweather_example_expose(AWeatherPlugin *_self)
        glRotatef(self->rotation, 1, 0, 1);
        glColor4f(0.9, 0.9, 0.7, 1.0);
        gdk_gl_draw_teapot(TRUE, 0.25);
-       gdk_gl_draw_cube(TRUE, 0.25);
        glColor4f(1.0, 1.0, 1.0, 1.0);
 
        glDisable(GL_LIGHT0);
index 4ffc78a..e9a2edd 100644 (file)
 
 #include <glib-object.h>
 
-#define AWEATHER_TYPE_EXAMPLE            (aweather_example_get_type ())
-#define AWEATHER_EXAMPLE(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),   AWEATHER_TYPE_EXAMPLE, AWeatherExample))
-#define AWEATHER_IS_EXAMPLE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),   AWEATHER_TYPE_EXAMPLE))
-#define AWEATHER_EXAMPLE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST   ((klass), AWEATHER_TYPE_EXAMPLE, AWeatherExampleClass))
-#define AWEATHER_IS_EXAMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE   ((klass), AWEATHER_TYPE_EXAMPLE))
-#define AWEATHER_EXAMPLE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),   AWEATHER_TYPE_EXAMPLE, AWeatherExampleClass))
+#define GIS_TYPE_PLUGIN_EXAMPLE            (gis_plugin_example_get_type ())
+#define GIS_PLUGIN_EXAMPLE(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),   GIS_TYPE_PLUGIN_EXAMPLE, GisPluginExample))
+#define GIS_IS_PLUGIN_EXAMPLE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),   GIS_TYPE_PLUGIN_EXAMPLE))
+#define GIS_PLUGIN_EXAMPLE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST   ((klass), GIS_TYPE_PLUGIN_EXAMPLE, GisPluginExampleClass))
+#define GIS_IS_PLUGIN_EXAMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE   ((klass), GIS_TYPE_PLUGIN_EXAMPLE))
+#define GIS_PLUGIN_EXAMPLE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),   GIS_TYPE_PLUGIN_EXAMPLE, GisPluginExampleClass))
 
-typedef struct _AWeatherExample        AWeatherExample;
-typedef struct _AWeatherExampleClass   AWeatherExampleClass;
+typedef struct _GisPluginExample        GisPluginExample;
+typedef struct _GisPluginExampleClass   GisPluginExampleClass;
 
-struct _AWeatherExample {
+struct _GisPluginExample {
        GObject parent_instance;
 
        /* instance members */
-       AWeatherGui     *gui;
+       GisOpenGL       *opengl;
        GtkToggleButton *button;
        float            rotation;
 };
 
-struct _AWeatherExampleClass {
+struct _GisPluginExampleClass {
        GObjectClass parent_class;
 };
 
-GType aweather_example_get_type();
+GType gis_plugin_example_get_type();
 
 /* Methods */
-AWeatherExample *aweather_example_new(AWeatherGui *gui);
+GisPluginExample *gis_plugin_example_new(GisWorld *world, GisView *view, GisOpenGL *opengl);
 
 #endif
similarity index 91%
rename from src/misc.h
rename to src/plugins/radar-misc.h
index ab17c74..7e260e8 100644 (file)
@@ -1,6 +1,3 @@
-#define d2r(deg) (((deg)*M_PI)/180.0)
-#define r2d(rad) (((rad)*180.0)/M_PI)
-
 #define RSL_FOREACH_VOL(radar, volume, count, index) \
        guint count = 0; \
        for (guint index = 0; index < radar->h.nvolumes; index++) { \
index ae51128..107ccf2 100644 (file)
 #include <math.h>
 #include <rsl.h>
 
-#include "misc.h"
-#include "aweather-gui.h"
-#include "radar.h"
-#include "data.h"
-#include "marching.h"
+#include <gis/gis.h>
 
-static char *nexrad_base = "http://mesonet.agron.iastate.edu/data/";
+#include "marching.h"
+#include "radar.h"
+#include "radar-misc.h"
 
 /****************
  * 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_plugin_init(AWeatherPluginInterface *iface)
+static void gis_plugin_radar_plugin_init(GisPluginInterface *iface);
+static void gis_plugin_radar_expose(GisPlugin *_radar);
+static GtkWidget *gis_plugin_radar_get_config(GisPlugin *_self);
+G_DEFINE_TYPE_WITH_CODE(GisPluginRadar, gis_plugin_radar, G_TYPE_OBJECT,
+               G_IMPLEMENT_INTERFACE(GIS_TYPE_PLUGIN,
+                       gis_plugin_radar_plugin_init));
+static void gis_plugin_radar_plugin_init(GisPluginInterface *iface)
 {
-       g_debug("AWeatherRadar: plugin_init");
+       g_debug("GisPluginRadar: plugin_init");
        /* Add methods to the interface */
-       iface->expose = _aweather_radar_expose;
+       iface->expose     = gis_plugin_radar_expose;
+       iface->get_config = gis_plugin_radar_get_config;
 }
 /* Class/Object init */
-static void aweather_radar_init(AWeatherRadar *radar)
+static void gis_plugin_radar_init(GisPluginRadar *radar)
 {
-       g_debug("AWeatherRadar: class_init");
+       g_debug("GisPluginRadar: class_init");
        /* Set defaults */
-       radar->gui           = NULL;
        radar->soup          = NULL;
        radar->cur_triangles = NULL;
        radar->cur_num_triangles = 0;
 }
-static void aweather_radar_dispose(GObject *gobject)
+static void gis_plugin_radar_dispose(GObject *gobject)
 {
-       g_debug("AWeatherRadar: dispose");
-       AWeatherRadar *self = AWEATHER_RADAR(gobject);
+       g_debug("GisPluginRadar: dispose");
+       GisPluginRadar *self = GIS_PLUGIN_RADAR(gobject);
        /* Drop references */
-       G_OBJECT_CLASS(aweather_radar_parent_class)->dispose(gobject);
+       G_OBJECT_CLASS(gis_plugin_radar_parent_class)->dispose(gobject);
 }
-static void aweather_radar_finalize(GObject *gobject)
+static void gis_plugin_radar_finalize(GObject *gobject)
 {
-       g_debug("AWeatherRadar: finalize");
-       AWeatherRadar *self = AWEATHER_RADAR(gobject);
+       g_debug("GisPluginRadar: finalize");
+       GisPluginRadar *self = GIS_PLUGIN_RADAR(gobject);
        /* Free data */
-       G_OBJECT_CLASS(aweather_radar_parent_class)->finalize(gobject);
+       G_OBJECT_CLASS(gis_plugin_radar_parent_class)->finalize(gobject);
 
 }
-static void aweather_radar_class_init(AWeatherRadarClass *klass)
+static void gis_plugin_radar_class_init(GisPluginRadarClass *klass)
 {
-       g_debug("AWeatherRadar: class_init");
+       g_debug("GisPluginRadar: class_init");
        GObjectClass *gobject_class = (GObjectClass*)klass;
-       gobject_class->dispose  = aweather_radar_dispose;
-       gobject_class->finalize = aweather_radar_finalize;
+       gobject_class->dispose  = gis_plugin_radar_dispose;
+       gobject_class->finalize = gis_plugin_radar_finalize;
 }
 
 /**************************
  * Data loading functions *
  **************************/
 /* Convert a sweep to an 2d array of data points */
-static void bscan_sweep(AWeatherRadar *self, Sweep *sweep, colormap_t *colormap,
+static void bscan_sweep(GisPluginRadar *self, Sweep *sweep, colormap_t *colormap,
                guint8 **data, int *width, int *height)
 {
        /* Calculate max number of bins */
@@ -120,9 +119,9 @@ static void bscan_sweep(AWeatherRadar *self, Sweep *sweep, colormap_t *colormap,
 }
 
 /* Load a sweep as the active texture */
-static void load_sweep(AWeatherRadar *self, Sweep *sweep)
+static void load_sweep(GisPluginRadar *self, Sweep *sweep)
 {
-       GisOpenGL *opengl = aweather_gui_get_opengl(self->gui);
+       GisOpenGL *opengl = self->opengl;
        gis_opengl_begin(opengl);
        self->cur_sweep = sweep;
        int height, width;
@@ -142,7 +141,7 @@ static void load_sweep(AWeatherRadar *self, Sweep *sweep)
        gis_opengl_end(opengl);
 }
 
-static void load_colormap(AWeatherRadar *self, gchar *table)
+static void load_colormap(GisPluginRadar *self, gchar *table)
 {
        /* Set colormap so we can draw it on expose */
        for (int i = 0; colormaps[i].name; i++)
@@ -152,7 +151,7 @@ static void load_colormap(AWeatherRadar *self, gchar *table)
 
 /* Add selectors to the config area for the sweeps */
 static void on_sweep_clicked(GtkRadioButton *button, gpointer _self);
-static void load_radar_gui(AWeatherRadar *self, Radar *radar)
+static void load_radar_gui(GisPluginRadar *self, Radar *radar)
 {
        /* Clear existing items */
        GtkWidget *child = gtk_bin_get_child(GTK_BIN(self->config_body));
@@ -221,7 +220,7 @@ static void load_radar_gui(AWeatherRadar *self, Radar *radar)
        gtk_widget_show_all(table);
 }
 
-static void _aweather_radar_grid_set(GRIDCELL *grid, int gi, Ray *ray, int bi)
+static void _gis_plugin_radar_grid_set(GRIDCELL *grid, int gi, Ray *ray, int bi)
 {
        Range range = ray->range[bi];
 
@@ -253,12 +252,12 @@ static void _aweather_radar_grid_set(GRIDCELL *grid, int gi, Ray *ray, int bi)
 }
 
 /* Load a radar from a decompressed file */
-static void load_radar(AWeatherRadar *self, gchar *radar_file)
+static void load_radar(GisPluginRadar *self, gchar *radar_file)
 {
        char *dir  = g_path_get_dirname(radar_file);
        char *site = g_path_get_basename(dir);
        g_free(dir);
-       g_debug("AWeatherRadar: load_radar - Loading new radar");
+       g_debug("GisPluginRadar: load_radar - Loading new radar");
        RSL_read_these_sweeps("all", NULL);
        Radar *radar = self->cur_radar = RSL_wsr88d_to_radar(radar_file, site);
        if (radar == NULL) {
@@ -283,7 +282,7 @@ static void load_radar(AWeatherRadar *self, gchar *radar_file)
                        Sweep *sweep0 = radar->v[vi]->sweep[si+0];
                        Sweep *sweep1 = radar->v[vi]->sweep[si+1];
 
-                       //g_debug("_aweather_radar_expose: sweep[%3d-%3d] -- nrays = %d, %d",
+                       //g_debug("_gis_plugin_radar_expose: sweep[%3d-%3d] -- nrays = %d, %d",
                        //      si, si+1,sweep0->h.nrays, sweep1->h.nrays);
 
                        /* Skip super->regular resolution switch for now */
@@ -304,7 +303,7 @@ static void load_radar(AWeatherRadar *self, gchar *radar_file)
                                        sweep1->ray[ri];
 
                        for (guint ri = 0; ri+x < sweep0->h.nrays; ri+=x) {
-                               //g_debug("_aweather_radar_expose: ray[%3d-%3d] -- nbins = %d, %d, %d, %d",
+                               //g_debug("_gis_plugin_radar_expose: ray[%3d-%3d] -- nbins = %d, %d, %d, %d",
                                //      ri, ri+x,
                                //      rays0[ri  ]->h.nbins, 
                                //      rays0[ri+1]->h.nbins, 
@@ -313,14 +312,14 @@ static void load_radar(AWeatherRadar *self, gchar *radar_file)
 
                                for (guint bi = 0; bi+x < rays1[ri]->h.nbins; bi+=x) {
                                        GRIDCELL grid = {};
-                                       _aweather_radar_grid_set(&grid, 7, rays0[(ri  )%sweep0->h.nrays], bi+x);
-                                       _aweather_radar_grid_set(&grid, 6, rays0[(ri+x)%sweep0->h.nrays], bi+x);
-                                       _aweather_radar_grid_set(&grid, 5, rays0[(ri+x)%sweep0->h.nrays], bi  );
-                                       _aweather_radar_grid_set(&grid, 4, rays0[(ri  )%sweep0->h.nrays], bi  );
-                                       _aweather_radar_grid_set(&grid, 3, rays1[(ri  )%sweep0->h.nrays], bi+x);
-                                       _aweather_radar_grid_set(&grid, 2, rays1[(ri+x)%sweep0->h.nrays], bi+x);
-                                       _aweather_radar_grid_set(&grid, 1, rays1[(ri+x)%sweep0->h.nrays], bi  );
-                                       _aweather_radar_grid_set(&grid, 0, rays1[(ri  )%sweep0->h.nrays], bi  );
+                                       _gis_plugin_radar_grid_set(&grid, 7, rays0[(ri  )%sweep0->h.nrays], bi+x);
+                                       _gis_plugin_radar_grid_set(&grid, 6, rays0[(ri+x)%sweep0->h.nrays], bi+x);
+                                       _gis_plugin_radar_grid_set(&grid, 5, rays0[(ri+x)%sweep0->h.nrays], bi  );
+                                       _gis_plugin_radar_grid_set(&grid, 4, rays0[(ri  )%sweep0->h.nrays], bi  );
+                                       _gis_plugin_radar_grid_set(&grid, 3, rays1[(ri  )%sweep0->h.nrays], bi+x);
+                                       _gis_plugin_radar_grid_set(&grid, 2, rays1[(ri+x)%sweep0->h.nrays], bi+x);
+                                       _gis_plugin_radar_grid_set(&grid, 1, rays1[(ri+x)%sweep0->h.nrays], bi  );
+                                       _gis_plugin_radar_grid_set(&grid, 0, rays1[(ri  )%sweep0->h.nrays], bi  );
                                        
                                        TRIANGLE tris[10];
                                        int n = march_one_cube(grid, 40, tris);
@@ -363,86 +362,17 @@ static void load_radar(AWeatherRadar *self, gchar *radar_file)
        load_radar_gui(self, radar);
 }
 
-/* TODO: These update times functions are getting ugly... */
-static void update_times_gtk(AWeatherRadar *self, GList *times)
-{
-       gchar *last_time = NULL;
-       GRegex *regex = g_regex_new("^[A-Z]{4}_([0-9]{8}_[0-9]{4})$", 0, 0, NULL); // KLSX_20090622_2113
-       GMatchInfo *info;
-
-       GtkTreeView  *tview  = GTK_TREE_VIEW(aweather_gui_get_widget(self->gui, "time"));
-       GtkListStore *lstore = GTK_LIST_STORE(gtk_tree_view_get_model(tview));
-       gtk_list_store_clear(lstore);
-       GtkTreeIter iter;
-       times = g_list_reverse(times);
-       for (GList *cur = times; cur; cur = cur->next) {
-               g_message("trying time %s", (gchar*)cur->data);
-               if (g_regex_match(regex, cur->data, 0, &info)) {
-                       gchar *time = g_match_info_fetch(info, 1);
-                       g_message("adding time %s", (gchar*)cur->data);
-                       gtk_list_store_insert(lstore, &iter, 0);
-                       gtk_list_store_set(lstore, &iter, 0, time, -1);
-                       last_time = time;
-               }
-       }
-
-       GisView *view = aweather_gui_get_view(self->gui);
-       gis_view_set_time(view, last_time);
-
-       g_regex_unref(regex);
-       g_list_foreach(times, (GFunc)g_free, NULL);
-       g_list_free(times);
-}
-static void update_times_online_cb(char *path, gboolean updated, gpointer _self)
-{
-       GList *times = NULL;
-       gchar *data;
-       gsize length;
-       g_file_get_contents(path, &data, &length, NULL);
-       gchar **lines = g_strsplit(data, "\n", -1);
-       for (int i = 0; lines[i] && lines[i][0]; i++) {
-               char **parts = g_strsplit(lines[i], " ", 2);
-               times = g_list_prepend(times, g_strdup(parts[1]));
-               g_strfreev(parts);
-       }
-       g_strfreev(lines);
-       g_free(data);
-
-       update_times_gtk(_self, times);
-}
-static void update_times(AWeatherRadar *self, GisView *view, char *site)
-{
-       GisWorld *world = aweather_gui_get_world(self->gui);
-       if (gis_world_get_offline(world)) {
-               GList *times = NULL;
-               gchar *path = g_build_filename(g_get_user_cache_dir(), PACKAGE, "nexrd2", "raw", site, NULL);
-               GDir *dir = g_dir_open(path, 0, NULL);
-               if (dir) {
-                       const gchar *name;
-                       while ((name = g_dir_read_name(dir))) {
-                               times = g_list_prepend(times, g_strdup(name));
-                       }
-                       g_dir_close(dir);
-               }
-               g_free(path);
-               update_times_gtk(self, times);
-       } else {
-               gchar *path = g_strdup_printf("nexrd2/raw/%s/dir.list", site);
-               cache_file(nexrad_base, path, AWEATHER_REFRESH, NULL, update_times_online_cb, self);
-               /* update_times_gtk from update_times_online_cb */
-       }
-}
-
 /*****************
  * ASync helpers *
  *****************/
 typedef struct {
-       AWeatherRadar *self;
+       GisPluginRadar *self;
        gchar *radar_file;
 } decompressed_t;
 
 static void decompressed_cb(GPid pid, gint status, gpointer _udata)
 {
+       g_debug("GisPluginRadar: decompressed_cb");
        decompressed_t *udata = _udata;
        if (status != 0) {
                g_warning("wsr88ddec exited with status %d", status);
@@ -456,10 +386,10 @@ static void decompressed_cb(GPid pid, gint status, gpointer _udata)
 
 static void cache_chunk_cb(char *path, goffset cur, goffset total, gpointer _self)
 {
-       AWeatherRadar *self = AWEATHER_RADAR(_self);
+       GisPluginRadar *self = GIS_PLUGIN_RADAR(_self);
        double percent = (double)cur/total;
 
-       g_message("AWeatherRadar: cache_chunk_cb - %lld/%lld = %.2f%%",
+       g_message("GisPluginRadar: cache_chunk_cb - %lld/%lld = %.2f%%",
                        cur, total, percent*100);
 
        gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(self->progress_bar), MIN(percent, 1.0));
@@ -472,9 +402,10 @@ static void cache_chunk_cb(char *path, goffset cur, goffset total, gpointer _sel
 
 static void cache_done_cb(char *path, gboolean updated, gpointer _self)
 {
-       AWeatherRadar *self = AWEATHER_RADAR(_self);
+       g_debug("GisPluginRadar: cache_done_cb - updated = %d", updated);
+       GisPluginRadar *self = GIS_PLUGIN_RADAR(_self);
        char *decompressed = g_strconcat(path, ".raw", NULL);
-       if (!updated) {
+       if (!updated && g_file_test(decompressed, G_FILE_TEST_EXISTS)) {
                load_radar(self, decompressed);
                return;
        }
@@ -482,7 +413,7 @@ static void cache_done_cb(char *path, gboolean updated, gpointer _self)
        decompressed_t *udata = g_malloc(sizeof(decompressed_t));
        udata->self       = self;
        udata->radar_file = decompressed;
-       g_debug("AWeatherRadar: cache_done_cb - File updated, decompressing..");
+       g_debug("GisPluginRadar: cache_done_cb - File updated, decompressing..");
        char *argv[] = {"wsr88ddec", path, decompressed, NULL};
        GPid pid;
        GError *error = NULL;
@@ -511,15 +442,15 @@ static void cache_done_cb(char *path, gboolean updated, gpointer _self)
  *************/
 static void on_sweep_clicked(GtkRadioButton *button, gpointer _self)
 {
-       AWeatherRadar *self = AWEATHER_RADAR(_self);
+       GisPluginRadar *self = GIS_PLUGIN_RADAR(_self);
        load_colormap(self, g_object_get_data(G_OBJECT(button), "type" ));
        load_sweep   (self, g_object_get_data(G_OBJECT(button), "sweep"));
 }
 
 static void on_time_changed(GisView *view, const char *time, gpointer _self)
 {
-       AWeatherRadar *self = AWEATHER_RADAR(_self);
-       g_debug("AWeatherRadar: on_time_changed - setting time=%s", time);
+       GisPluginRadar *self = GIS_PLUGIN_RADAR(_self);
+       g_debug("GisPluginRadar: on_time_changed - setting time=%s", time);
        // format: http://mesonet.agron.iastate.edu/data/nexrd2/raw/KABR/KABR_20090510_0323
        char *site = gis_view_get_site(view);
        char *path = g_strdup_printf("nexrd2/raw/%s/%s_%s", site, site, time);
@@ -542,70 +473,56 @@ static void on_time_changed(GisView *view, const char *time, gpointer _self)
                RSL_free_radar(self->cur_radar);
        self->cur_radar = NULL;
        self->cur_sweep = NULL;
-       gis_opengl_redraw(aweather_gui_get_opengl(self->gui));
+       gis_opengl_redraw(self->opengl);
 
        /* Start loading the new radar */
        if (self->soup) {
                soup_session_abort(self->soup);
                self->soup = NULL;
        }
-       if (gis_world_get_offline(aweather_gui_get_world(self->gui))) 
-               self->soup = cache_file(nexrad_base, path, AWEATHER_ONCE,
+       gchar *base = gis_prefs_get_string(self->prefs, "general/nexrad_url");
+       if (gis_world_get_offline(self->world)) 
+               self->soup = cache_file(base, path, AWEATHER_ONCE,
                                cache_chunk_cb, cache_done_cb, self);
        else 
-               self->soup = cache_file(nexrad_base, path, AWEATHER_UPDATE,
+               self->soup = cache_file(base, path, AWEATHER_UPDATE,
                                cache_chunk_cb, cache_done_cb, self);
        g_free(path);
 }
 
-static void on_site_changed(GisView *view, char *site, gpointer _self)
-{
-       AWeatherRadar *self = AWEATHER_RADAR(_self);
-       g_debug("AWeatherRadar: on_site_changed - Loading wsr88d list for %s", site);
-       update_times(self, view, site);
-}
-
-static void on_refresh(GisWorld *world, gpointer _self)
-{
-       AWeatherRadar *self = AWEATHER_RADAR(_self);
-       GisView *view = aweather_gui_get_view(AWEATHER_RADAR(_self)->gui);
-       char *site = gis_view_get_site(view);
-       update_times(self, view, site);
-}
-
 /***********
  * Methods *
  ***********/
-AWeatherRadar *aweather_radar_new(AWeatherGui *gui)
+GisPluginRadar *gis_plugin_radar_new(GisWorld *world, GisView *view, GisOpenGL *opengl, GisPrefs *prefs)
 {
-       g_debug("AWeatherRadar: new");
-       AWeatherRadar *self = g_object_new(AWEATHER_TYPE_RADAR, NULL);
-       self->gui  = gui;
-
-       GtkWidget    *config  = aweather_gui_get_widget(gui, "tabs");
+       /* TODO: move to constructor if possible */
+       g_debug("GisPluginRadar: new");
+       GisPluginRadar *self = g_object_new(GIS_TYPE_PLUGIN_RADAR, NULL);
+       self->world  = world;
+       self->view   = view;
+       self->opengl = opengl;
+       self->prefs  = prefs;
 
-       /* Add configuration tab */
        self->config_body = gtk_alignment_new(0, 0, 1, 1);
        gtk_container_set_border_width(GTK_CONTAINER(self->config_body), 5);
        gtk_container_add(GTK_CONTAINER(self->config_body), gtk_label_new("No radar loaded"));
-       gtk_notebook_prepend_page(GTK_NOTEBOOK(config), self->config_body, gtk_label_new("Radar"));
 
        /* Set up OpenGL Stuff */
-       GisView  *view  = aweather_gui_get_view(gui);
-       GisWorld *world = aweather_gui_get_world(gui);
-       g_signal_connect(view,  "site-changed", G_CALLBACK(on_site_changed), self);
        g_signal_connect(view,  "time-changed", G_CALLBACK(on_time_changed), self);
-       g_signal_connect(world, "refresh",      G_CALLBACK(on_refresh),      self);
-
-       on_site_changed(view, gis_view_get_site(view), self);
 
        return self;
 }
 
-static void _aweather_radar_expose(AWeatherPlugin *_self)
+static GtkWidget *gis_plugin_radar_get_config(GisPlugin *_self)
+{
+       GisPluginRadar *self = GIS_PLUGIN_RADAR(_self);
+       return self->config_body;
+}
+
+static void gis_plugin_radar_expose(GisPlugin *_self)
 {
-       AWeatherRadar *self = AWEATHER_RADAR(_self);
-       g_debug("AWeatherRadar: expose");
+       GisPluginRadar *self = GIS_PLUGIN_RADAR(_self);
+       g_debug("GisPluginRadar: expose");
        if (self->cur_sweep == NULL)
                return;
        Sweep *sweep = self->cur_sweep;
index 2db7980..95367b4 100644 (file)
@@ -22,6 +22,8 @@
 #include <libsoup/soup.h>
 #include <rsl.h>
 
+#include <gis/gis.h>
+
 #include "marching.h"
 
 /* TODO: convert */
@@ -31,21 +33,24 @@ typedef struct {
 } colormap_t;
 extern colormap_t colormaps[];
 
-#define AWEATHER_TYPE_RADAR            (aweather_radar_get_type ())
-#define AWEATHER_RADAR(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),   AWEATHER_TYPE_RADAR, AWeatherRadar))
-#define AWEATHER_IS_RADAR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),   AWEATHER_TYPE_RADAR))
-#define AWEATHER_RADAR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST   ((klass), AWEATHER_TYPE_RADAR, AWeatherRadarClass))
-#define AWEATHER_IS_RADAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE   ((klass), AWEATHER_TYPE_RADAR))
-#define AWEATHER_RADAR_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),   AWEATHER_TYPE_RADAR, AWeatherRadarClass))
+#define GIS_TYPE_PLUGIN_RADAR            (gis_plugin_radar_get_type ())
+#define GIS_PLUGIN_RADAR(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),   GIS_TYPE_PLUGIN_RADAR, GisPluginRadar))
+#define GIS_IS_PLUGIN_RADAR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),   GIS_TYPE_PLUGIN_RADAR))
+#define GIS_PLUGIN_RADAR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST   ((klass), GIS_TYPE_PLUGIN_RADAR, GisPluginRadarClass))
+#define GIS_IS_PLUGIN_RADAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE   ((klass), GIS_TYPE_PLUGIN_RADAR))
+#define GIS_PLUGIN_RADAR_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),   GIS_TYPE_PLUGIN_RADAR, GisPluginRadarClass))
 
-typedef struct _AWeatherRadar        AWeatherRadar;
-typedef struct _AWeatherRadarClass   AWeatherRadarClass;
+typedef struct _GisPluginRadar        GisPluginRadar;
+typedef struct _GisPluginRadarClass   GisPluginRadarClass;
 
-struct _AWeatherRadar {
+struct _GisPluginRadar {
        GObject parent_instance;
 
        /* instance members */
-       AWeatherGui *gui;
+       GisWorld    *world;
+       GisView     *view;
+       GisOpenGL   *opengl;
+       GisPrefs    *prefs;
        GtkWidget   *config_body;
        GtkWidget   *progress_bar;
        GtkWidget   *progress_label;
@@ -60,13 +65,13 @@ struct _AWeatherRadar {
        guint        cur_num_triangles;
 };
 
-struct _AWeatherRadarClass {
+struct _GisPluginRadarClass {
        GObjectClass parent_class;
 };
 
-GType aweather_radar_get_type();
+GType gis_plugin_radar_get_type();
 
 /* Methods */
-AWeatherRadar *aweather_radar_new(AWeatherGui *gui);
+GisPluginRadar *gis_plugin_radar_new(GisWorld *world, GisView *view, GisOpenGL *opengl, GisPrefs *prefs);
 
 #endif
index 6f1e267..2250a69 100644 (file)
  */
 
 #include <config.h>
+#include <stdio.h>
 #include <gtk/gtk.h>
 #include <curl/curl.h>
 #include <GL/gl.h>
 
-#include <stdio.h>
+#include <gis/gis.h>
 
-#include "aweather-gui.h"
 #include "ridge.h"
-#include "data.h"
 
 /****************
  * 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_plugin_init(AWeatherPluginInterface *iface)
+static void gis_plugin_ridge_plugin_init(GisPluginInterface *iface);
+static void gis_plugin_ridge_expose(GisPlugin *_self);
+static GtkWidget *gis_plugin_ridge_get_config(GisPlugin *_self);
+G_DEFINE_TYPE_WITH_CODE(GisPluginRidge, gis_plugin_ridge, G_TYPE_OBJECT,
+               G_IMPLEMENT_INTERFACE(GIS_TYPE_PLUGIN,
+                       gis_plugin_ridge_plugin_init));
+static void gis_plugin_ridge_plugin_init(GisPluginInterface *iface)
 {
-       g_debug("AWeatherRidge: plugin_init");
+       g_debug("GisPluginRidge: plugin_init");
        /* Add methods to the interface */
-       iface->expose = aweather_ridge_expose;
+       iface->expose     = gis_plugin_ridge_expose;
+       iface->get_config = gis_plugin_ridge_get_config;
 }
 /* Class/Object init */
-static void aweather_ridge_init(AWeatherRidge *ridge)
+static void gis_plugin_ridge_init(GisPluginRidge *self)
 {
-       g_debug("AWeatherRidge: init");
+       g_debug("GisPluginRidge: init");
        /* Set defaults */
-       ridge->gui = NULL;
 }
-static void aweather_ridge_dispose(GObject *gobject)
+static void gis_plugin_ridge_dispose(GObject *gobject)
 {
-       g_debug("AWeatherRidge: dispose");
-       AWeatherRidge *self = AWEATHER_RIDGE(gobject);
+       g_debug("GisPluginRidge: dispose");
+       GisPluginRidge *self = GIS_PLUGIN_RIDGE(gobject);
        /* Drop references */
-       G_OBJECT_CLASS(aweather_ridge_parent_class)->dispose(gobject);
+       G_OBJECT_CLASS(gis_plugin_ridge_parent_class)->dispose(gobject);
 }
-static void aweather_ridge_finalize(GObject *gobject)
+static void gis_plugin_ridge_finalize(GObject *gobject)
 {
-       g_debug("AWeatherRidge: finalize");
-       AWeatherRidge *self = AWEATHER_RIDGE(gobject);
+       g_debug("GisPluginRidge: finalize");
+       GisPluginRidge *self = GIS_PLUGIN_RIDGE(gobject);
        /* Free data */
-       G_OBJECT_CLASS(aweather_ridge_parent_class)->finalize(gobject);
+       G_OBJECT_CLASS(gis_plugin_ridge_parent_class)->finalize(gobject);
 
 }
-static void aweather_ridge_class_init(AWeatherRidgeClass *klass)
+static void gis_plugin_ridge_class_init(GisPluginRidgeClass *klass)
 {
-       g_debug("AWeatherRidge: class_init");
+       g_debug("GisPluginRidge: class_init");
        GObjectClass *gobject_class = (GObjectClass*)klass;
-       gobject_class->dispose  = aweather_ridge_dispose;
-       gobject_class->finalize = aweather_ridge_finalize;
+       gobject_class->dispose  = gis_plugin_ridge_dispose;
+       gobject_class->finalize = gis_plugin_ridge_finalize;
 }
 
 /*********************
@@ -108,10 +108,9 @@ static layer_t layers[] = {
  * \param  filename  Path to the image file
  * \return The OpenGL identifier for the texture
  */
-void load_texture(AWeatherRidge *self, layer_t *layer, gchar *filename)
+void load_texture(GisPluginRidge *self, layer_t *layer, gchar *filename)
 {
-       GisOpenGL *opengl = aweather_gui_get_opengl(self->gui);
-       gis_opengl_begin(opengl);
+       gis_opengl_begin(self->opengl);
 
        /* Load image */
        GError *error = NULL;
@@ -137,18 +136,18 @@ void load_texture(AWeatherRidge *self, layer_t *layer, gchar *filename)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
        char *base = g_path_get_basename(filename);
-       g_debug("AWeatherRidge: load_texture - "
+       g_debug("GisPluginRidge: load_texture - "
                "w=%-3d  h=%-3d  fmt=%x  px=(%02x,%02x,%02x,%02x)  img=%s",
                width, height, format, pixels[0], pixels[1], pixels[2], pixels[3],
                base);
        g_free(base);
 
-       gis_opengl_end(opengl);
+       gis_opengl_end(self->opengl);
 
        g_object_unref(pixbuf);
 
        /* Redraw */
-       gis_opengl_redraw(opengl);
+       gis_opengl_redraw(self->opengl);
 }
 
 
@@ -156,7 +155,7 @@ void load_texture(AWeatherRidge *self, layer_t *layer, gchar *filename)
  * ASync helpers *
  *****************/
 typedef struct {
-       AWeatherRidge *self;
+       GisPluginRidge *self;
        layer_t *layer;
 } cached_t;
 void cached_cb(gchar *filename, gboolean updated, gpointer _udata)
@@ -169,9 +168,11 @@ void cached_cb(gchar *filename, gboolean updated, gpointer _udata)
 /*************
  * callbacks *
  *************/
-static void on_site_changed(GisView *view, gchar *site, AWeatherRidge *self)
+static void on_site_changed(GisView *view, gchar *site, GisPluginRidge *self)
 {
-       g_debug("AWeatherRidge: on_site_changed - site=%s", site);
+       g_debug("GisPluginRidge: on_site_changed - site=%s", site);
+       if (site == NULL || site[0] == '\0')
+               return;
        for (int i = 0; i < LAYER_COUNT; i++) {
                gchar *base = "http://radar.weather.gov/ridge/";
                gchar *path  = g_strdup_printf(layers[i].fmt, site+1);
@@ -184,28 +185,32 @@ static void on_site_changed(GisView *view, gchar *site, AWeatherRidge *self)
        }
 }
 
-void toggle_layer(GtkToggleButton *check, AWeatherRidge *self)
+void toggle_layer(GtkToggleButton *check, GisPluginRidge *self)
 {
        layer_t *layer = g_object_get_data(G_OBJECT(check), "layer");
        layer->enabled = gtk_toggle_button_get_active(check);
-       gis_opengl_redraw(aweather_gui_get_opengl(self->gui));
+       gis_opengl_redraw(self->opengl);
 }
 
 /***********
  * Methods *
  ***********/
-AWeatherRidge *aweather_ridge_new(AWeatherGui *gui)
+GisPluginRidge *gis_plugin_ridge_new(GisWorld *world, GisView *view, GisOpenGL *opengl)
 {
-       AWeatherRidge *self = g_object_new(AWEATHER_TYPE_RIDGE, NULL);
-       self->gui = gui;
+       GisPluginRidge *self = g_object_new(GIS_TYPE_PLUGIN_RIDGE, NULL);
+       self->world  = world;
+       self->view   = view;
+       self->opengl = opengl;
 
-       GisView   *view    = aweather_gui_get_view(gui);
-       GtkWidget *drawing = aweather_gui_get_widget(gui, "drawing");
-       GtkWidget *config  = aweather_gui_get_widget(gui, "tabs");
-       g_debug("config = %p", aweather_gui_get_widget(gui, "tabs"));
+       g_signal_connect(view, "site-changed", G_CALLBACK(on_site_changed), self);
+       on_site_changed(view, gis_view_get_site(view), self);
+
+       return self;
+}
 
-       /* Add configuration tab */
-       GtkWidget *tab  = gtk_label_new("Ridge");
+static GtkWidget *gis_plugin_ridge_get_config(GisPlugin *_self)
+{
+       GisPluginRidge *self = GIS_PLUGIN_RIDGE(_self);
        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++) {
@@ -216,19 +221,14 @@ AWeatherRidge *aweather_ridge_new(AWeatherGui *gui)
                g_signal_connect(check, "toggled", G_CALLBACK(toggle_layer), self);
        }
        gtk_container_add(GTK_CONTAINER(body), hbox);
-       gtk_notebook_append_page(GTK_NOTEBOOK(config), body, tab);
-
-       g_signal_connect(view, "site-changed", G_CALLBACK(on_site_changed), self);
-       on_site_changed(view, gis_view_get_site(view), self);
-
-       return self;
+       return body;
 }
 
-static void aweather_ridge_expose(AWeatherPlugin *_ridge)
+static void gis_plugin_ridge_expose(GisPlugin *_self)
 {
-       AWeatherRidge *ridge = AWEATHER_RIDGE(_ridge);
+       GisPluginRidge *self = GIS_PLUGIN_RIDGE(_self);
 
-       g_debug("AWeatherRidge: expose");
+       g_debug("GisPluginRidge: expose");
        glPushMatrix();
        glEnable(GL_TEXTURE_2D);
        glColor4f(1,1,1,1);
index 7c31ee6..72f460a 100644 (file)
 
 #include <glib-object.h>
 
-#define AWEATHER_TYPE_RIDGE            (aweather_ridge_get_type ())
-#define AWEATHER_RIDGE(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),   AWEATHER_TYPE_RIDGE, AWeatherRidge))
-#define AWEATHER_IS_RIDGE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),   AWEATHER_TYPE_RIDGE))
-#define AWEATHER_RIDGE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST   ((klass), AWEATHER_TYPE_RIDGE, AWeatherRidgeClass))
-#define AWEATHER_IS_RIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE   ((klass), AWEATHER_TYPE_RIDGE))
-#define AWEATHER_RIDGE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),   AWEATHER_TYPE_RIDGE, AWeatherRidgeClass))
+#include <gis/gis.h>
 
-typedef struct _AWeatherRidge      AWeatherRidge;
-typedef struct _AWeatherRidgeClass AWeatherRidgeClass;
+#define GIS_TYPE_PLUGIN_RIDGE            (gis_plugin_ridge_get_type ())
+#define GIS_PLUGIN_RIDGE(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),   GIS_TYPE_PLUGIN_RIDGE, GisPluginRidge))
+#define GIS_IS_PLUGIN_RIDGE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),   GIS_TYPE_PLUGIN_RIDGE))
+#define GIS_PLUGIN_RIDGE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST   ((klass), GIS_TYPE_PLUGIN_RIDGE, GisPluginRidgeClass))
+#define GIS_IS_PLUGIN_RIDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE   ((klass), GIS_TYPE_PLUGIN_RIDGE))
+#define GIS_PLUGIN_RIDGE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),   GIS_TYPE_PLUGIN_RIDGE, GisPluginRidgeClass))
 
-struct _AWeatherRidge {
+typedef struct _GisPluginRidge      GisPluginRidge;
+typedef struct _GisPluginRidgeClass GisPluginRidgeClass;
+
+struct _GisPluginRidge {
        GObject parent_instance;
 
        /* instance members */
-       AWeatherGui *gui;
+       GisWorld    *world;
+       GisView     *view;
+       GisOpenGL   *opengl;
 };
 
-struct _AWeatherRidgeClass {
+struct _GisPluginRidgeClass {
        GObjectClass parent_class;
 };
 
-GType aweather_ridge_get_type();
+GType gis_plugin_ridge_get_type();
 
 /* Methods */
-AWeatherRidge *aweather_ridge_new(AWeatherGui *gui);
+GisPluginRidge *gis_plugin_ridge_new(GisWorld *world, GisView *view, GisOpenGL *opengl);
 
 #endif