From: Andy Spencer Date: Thu, 6 Aug 2009 00:40:17 +0000 (+0000) Subject: Splitting GIS into a shared library, and a lot more X-Git-Tag: v0.2~5 X-Git-Url: http://pileus.org/git/?p=grits;a=commitdiff_plain;h=ca898105ec4018b54ac2f6f1327200624169103e Splitting GIS into a shared library, and a lot more --- diff --git a/TODO b/TODO index 9f8711f..1ed0735 100644 --- 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? diff --git a/configure.ac b/configure.ac index 4433b5a..18311d7 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/docs/api/Makefile.am b/docs/api/Makefile.am index 6fdc850..ac63adc 100644 --- a/docs/api/Makefile.am +++ b/docs/api/Makefile.am @@ -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/ diff --git a/src/Makefile.am b/src/Makefile.am index 191dfab..18976bc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 diff --git a/src/aweather-gui.c b/src/aweather-gui.c index 64c11a7..2720a00 100644 --- a/src/aweather-gui.c +++ b/src/aweather-gui.c @@ -20,14 +20,15 @@ #include #include -#include "misc.h" +#include + #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); } diff --git a/src/aweather-gui.h b/src/aweather-gui.h index 476cab1..eb28a55 100644 --- a/src/aweather-gui.h +++ b/src/aweather-gui.h @@ -20,10 +20,8 @@ #include #include -#include "gis-opengl.h" -#include "gis-world.h" -#include "gis-view.h" -#include "aweather-plugin.h" + +#include /* 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 diff --git a/src/location.c b/src/aweather-location.c similarity index 99% rename from src/location.c rename to src/aweather-location.c index 7d8ebe5..b893f39 100644 --- a/src/location.c +++ b/src/aweather-location.c @@ -18,7 +18,7 @@ #include #include -#include "location.h" +#include "aweather-location.h" city_t cities[] = { {LOCATION_STATE, NULL, "Alabama", {0, 0, 0, 0, 0, 0, 0, 0}}, diff --git a/src/location.h b/src/aweather-location.h 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 index 7ef76cd..0000000 --- a/src/aweather-plugin.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2009 Andy Spencer - * - * 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 . - */ - -#ifndef __AWEATHER_PLUGIN_H__ -#define __AWEATHER_PLUGIN_H__ - -#include - -#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 index 0000000..dd2588a --- /dev/null +++ b/src/gis/Makefile.am @@ -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 $< > $@ diff --git a/src/data.c b/src/gis/gis-data.c similarity index 99% rename from src/data.c rename to src/gis/gis-data.c index 6186883..7c9f2c9 100644 --- a/src/data.c +++ b/src/gis/gis-data.c @@ -20,7 +20,7 @@ #include #include -#include "data.h" +#include "gis-data.h" typedef struct { gchar *uri; diff --git a/src/data.h b/src/gis/gis-data.h 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 index 0000000..23aa1db --- /dev/null +++ b/src/gis/gis-marshal.c @@ -0,0 +1,127 @@ + +#include + + +#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 index 0000000..ca695bf --- /dev/null +++ b/src/gis/gis-marshal.h @@ -0,0 +1,28 @@ + +#ifndef __gis_cclosure_marshal_MARSHAL_H__ +#define __gis_cclosure_marshal_MARSHAL_H__ + +#include + +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__ */ + diff --git a/src/marshal.list b/src/gis/gis-marshal.list similarity index 50% rename from src/marshal.list rename to src/gis/gis-marshal.list index 32d7404..f588897 100644 --- a/src/marshal.list +++ b/src/gis/gis-marshal.list @@ -1 +1,2 @@ VOID:DOUBLE,DOUBLE,DOUBLE +VOID:STRING,UINT,POINTER diff --git a/src/gis-opengl.c b/src/gis/gis-opengl.c similarity index 94% rename from src/gis-opengl.c rename to src/gis/gis-opengl.c index 46eae60..acf12eb 100644 --- a/src/gis-opengl.c +++ b/src/gis/gis-opengl.c @@ -23,10 +23,6 @@ #include #include -#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)); diff --git a/src/gis-opengl.h b/src/gis/gis-opengl.h similarity index 94% rename from src/gis-opengl.h rename to src/gis/gis-opengl.h index aca186f..e814969 100644 --- a/src/gis-opengl.h +++ b/src/gis/gis-opengl.h @@ -23,9 +23,6 @@ #include #include -#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)) @@ -37,14 +34,21 @@ 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 index 0000000..e15c53c --- /dev/null +++ b/src/gis/gis-plugin.c @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2009 Andy Spencer + * + * 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 . + */ + +#include +#include + +#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 index 0000000..a667fba --- /dev/null +++ b/src/gis/gis-plugin.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2009 Andy Spencer + * + * 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 . + */ + +#ifndef __GIS_PLUGIN_H__ +#define __GIS_PLUGIN_H__ + +#include +#include + +#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 index 0000000..2b3829a --- /dev/null +++ b/src/gis/gis-prefs.c @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2009 Andy Spencer + * + * 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 . + */ + +#include +#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 index 0000000..1645734 --- /dev/null +++ b/src/gis/gis-prefs.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2009 Andy Spencer + * + * 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 . + */ + +#ifndef __GIS_PREFS_H__ +#define __GIS_PREFS_H__ + +#include + +/* 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 diff --git a/src/gis-view.c b/src/gis/gis-view.c similarity index 97% rename from src/gis-view.c rename to src/gis/gis-view.c index e43aefb..409aa68 100644 --- a/src/gis-view.c +++ b/src/gis/gis-view.c @@ -17,7 +17,7 @@ #include -#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; } diff --git a/src/gis-view.h b/src/gis/gis-view.h similarity index 100% rename from src/gis-view.h rename to src/gis/gis-view.h diff --git a/src/gis-world.c b/src/gis/gis-world.c similarity index 99% rename from src/gis-world.c rename to src/gis/gis-world.c index 2987911..9d7ecb2 100644 --- a/src/gis-world.c +++ b/src/gis/gis-world.c @@ -17,7 +17,7 @@ #include -#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; } + + diff --git a/src/gis-world.h b/src/gis/gis-world.h similarity index 100% rename from src/gis-world.h rename to src/gis/gis-world.h diff --git a/src/aweather-plugin.c b/src/gis/gis.h similarity index 50% rename from src/aweather-plugin.c rename to src/gis/gis.h index 87cf35c..be6cbc3 100644 --- a/src/aweather-plugin.c +++ b/src/gis/gis.h @@ -15,36 +15,20 @@ * along with this program. If not, see . */ -#include +#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 diff --git a/src/main.c b/src/main.c index 6db1393..aa02ea9 100644 --- a/src/main.c +++ b/src/main.c @@ -19,10 +19,9 @@ #include #include +#include + #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); diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index 14a3bfc..7a0c4be 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -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 diff --git a/src/plugins/example.c b/src/plugins/example.c index dd9f905..3930fb5 100644 --- a/src/plugins/example.c +++ b/src/plugins/example.c @@ -20,54 +20,57 @@ #include #include -#include "aweather-gui.h" +#include + #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); diff --git a/src/plugins/example.h b/src/plugins/example.h index 4ffc78a..e9a2edd 100644 --- a/src/plugins/example.h +++ b/src/plugins/example.h @@ -20,32 +20,32 @@ #include -#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 diff --git a/src/misc.h b/src/plugins/radar-misc.h similarity index 91% rename from src/misc.h rename to src/plugins/radar-misc.h index ab17c74..7e260e8 100644 --- a/src/misc.h +++ b/src/plugins/radar-misc.h @@ -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++) { \ diff --git a/src/plugins/radar.c b/src/plugins/radar.c index ae51128..107ccf2 100644 --- a/src/plugins/radar.c +++ b/src/plugins/radar.c @@ -23,67 +23,66 @@ #include #include -#include "misc.h" -#include "aweather-gui.h" -#include "radar.h" -#include "data.h" -#include "marching.h" +#include -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; diff --git a/src/plugins/radar.h b/src/plugins/radar.h index 2db7980..95367b4 100644 --- a/src/plugins/radar.h +++ b/src/plugins/radar.h @@ -22,6 +22,8 @@ #include #include +#include + #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 diff --git a/src/plugins/ridge.c b/src/plugins/ridge.c index 6f1e267..2250a69 100644 --- a/src/plugins/ridge.c +++ b/src/plugins/ridge.c @@ -16,59 +16,59 @@ */ #include +#include #include #include #include -#include +#include -#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); diff --git a/src/plugins/ridge.h b/src/plugins/ridge.h index 7c31ee6..72f460a 100644 --- a/src/plugins/ridge.h +++ b/src/plugins/ridge.h @@ -20,30 +20,34 @@ #include -#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 -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