From f8fb15ac28c5472b5a8da6e74e559e84a25e20e9 Mon Sep 17 00:00:00 2001 From: "Gergely POLONKAI (W00d5t0ck)" Date: Sun, 1 Sep 2013 13:52:18 +0200 Subject: [PATCH] Added SWE-Glib sources, which currently wraps Swiss Ephemeris function calls --- .gitignore | 5 + Makefile.am | 2 +- configure.ac | 8 + docs/reference/swe-glib/Makefile.am | 105 +++++ src/Makefile.am | 2 +- swe-glib/src/Makefile.am | 24 ++ swe-glib/src/enumtypes.c.template | 38 ++ swe-glib/src/enumtypes.h.template | 25 ++ swe-glib/src/gswe-moment.c | 152 +++++++ swe-glib/src/gswe-moment.h | 68 ++++ swe-glib/src/gswe-timestamp.c | 597 ++++++++++++++++++++++++++++ swe-glib/src/gswe-timestamp.h | 69 ++++ swe-glib/src/gswe-types.h | 85 ++++ swe-glib/src/swe-glib-private.h | 10 + swe-glib/src/swe-glib.c | 74 ++++ swe-glib/src/swe-glib.h | 11 + 16 files changed, 1273 insertions(+), 2 deletions(-) create mode 100644 docs/reference/swe-glib/Makefile.am create mode 100644 swe-glib/src/Makefile.am create mode 100644 swe-glib/src/enumtypes.c.template create mode 100644 swe-glib/src/enumtypes.h.template create mode 100644 swe-glib/src/gswe-moment.c create mode 100644 swe-glib/src/gswe-moment.h create mode 100644 swe-glib/src/gswe-timestamp.c create mode 100644 swe-glib/src/gswe-timestamp.h create mode 100644 swe-glib/src/gswe-types.h create mode 100644 swe-glib/src/swe-glib-private.h create mode 100644 swe-glib/src/swe-glib.c create mode 100644 swe-glib/src/swe-glib.h diff --git a/.gitignore b/.gitignore index c7811a4..753b27d 100644 --- a/.gitignore +++ b/.gitignore @@ -45,6 +45,11 @@ Makefile.in /po/quot.sed /po/remove-potcdate.sin +# SWE-GLib related files, should be removed when SWE-GLib goes separate +/swe-glib/src/enumtypes.c +/swe-glib/src/enumtypes.h +/swe-glib/src/gswetest + #Documentation related files /docs/reference/*/*.args /docs/reference/*/*.hierarchy diff --git a/Makefile.am b/Makefile.am index 1fc842c..0b8875f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,5 @@ ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = swe/src src po docs/reference/astrognome +SUBDIRS = swe/src swe-glib/src src po docs/reference/swe-glib docs/reference/astrognome EXTRA_DIST = config.rpath m4/ChangeLog diff --git a/configure.ac b/configure.ac index ba3a022..69e8505 100644 --- a/configure.ac +++ b/configure.ac @@ -37,17 +37,25 @@ AC_CHECK_LIB([m], [sqrt]) AC_CHECK_LIB([m], [floor]) GTK_DOC_CHECK([1.19], [--flavour no-tmpl]) PKG_PROG_PKG_CONFIG +AC_PATH_PROG([GLIB_MKENUMS], [glib-mkenums]) +PKG_CHECK_MODULES([GLIB], [glib-2.0]) +PKG_CHECK_MODULES([GOBJECT], [gobject-2.0]) PKG_CHECK_MODULES([GTK], [gtk+-3.0]) AC_CONFIG_MACRO_DIR([m4]) LIBSWE_LIBS='$(top_builddir)/swe/src/libswe-1.75.la' AC_SUBST(LIBSWE_LIBS) +LIBSWE_GLIB_LIBS='$(top_builddir)/swe-glib/src/libswe-glib-0.1.la' +AC_SUBST(LIBSWE_GLIB_LIBS) + AC_CONFIG_FILES([ Makefile swe/src/Makefile + swe-glib/src/Makefile src/Makefile po/Makefile.in docs/reference/astrognome/Makefile + docs/reference/swe-glib/Makefile ]) AC_OUTPUT diff --git a/docs/reference/swe-glib/Makefile.am b/docs/reference/swe-glib/Makefile.am new file mode 100644 index 0000000..ae279ea --- /dev/null +++ b/docs/reference/swe-glib/Makefile.am @@ -0,0 +1,105 @@ +## Process this file with automake to produce Makefile.in + +# We require automake 1.6 at least. +AUTOMAKE_OPTIONS = 1.6 + +# This is a blank Makefile.am for using gtk-doc. +# Copy this to your project's API docs directory and modify the variables to +# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples +# of using the various options. + +# The name of the module, e.g. 'glib'. +DOC_MODULE=swe-glib + +# Uncomment for versioned docs and specify the version of the module, e.g. '2'. +DOC_MODULE_VERSION=0 + + +# The top-level XML file (SGML in the past). You can change this if you want to. +DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml + +# Directories containing the source code. +# gtk-doc will search all .c and .h files beneath these paths +# for inline comments documenting functions and macros. +# e.g. DOC_SOURCE_DIR=$(top_srcdir)/gtk $(top_srcdir)/gdk +DOC_SOURCE_DIR=$(top_srcdir)/swe-glib/src + +# Extra options to pass to gtkdoc-scangobj. Not normally needed. +SCANGOBJ_OPTIONS= + +# Extra options to supply to gtkdoc-scan. +# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" +SCAN_OPTIONS=--rebuild-sections --rebuild-types + +# Extra options to supply to gtkdoc-mkdb. +# e.g. MKDB_OPTIONS=--xml-mode --output-format=xml +MKDB_OPTIONS=--xml-mode --output-format=xml + +# Extra options to supply to gtkdoc-mktmpl +# e.g. MKTMPL_OPTIONS=--only-section-tmpl +MKTMPL_OPTIONS= + +# Extra options to supply to gtkdoc-mkhtml +MKHTML_OPTIONS= + +# Extra options to supply to gtkdoc-fixref. Not normally needed. +# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html +FIXXREF_OPTIONS= + +# Used for dependencies. The docs will be rebuilt if any of these change. +# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h +# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c +HFILE_GLOB=$(top_srcdir)/swe-glib/src/*.h +CFILE_GLOB=$(top_srcdir)/swe-glib/src/*.c + +# Extra header to include when scanning, which are not under DOC_SOURCE_DIR +# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h +EXTRA_HFILES= + +# Header files or dirs to ignore when scanning. Use base file/dir names +# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h private_code +IGNORE_HFILES= + +# Images to copy into HTML directory. +# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png +HTML_IMAGES= + +# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). +# e.g. content_files=running.sgml building.sgml changes-2.0.sgml +content_files= + +# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded +# These files must be listed here *and* in content_files +# e.g. expand_content_files=running.sgml +expand_content_files= + +# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. +# Only needed if you are using gtkdoc-scangobj to dynamically query widget +# signals and properties. +# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) +# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) +GTKDOC_CFLAGS= +GTKDOC_LIBS=$(LIBSWE_GLIB_LIBS) $(NULL) + +# This includes the standard gtk-doc make rules, copied by gtkdocize. +include $(top_srcdir)/gtk-doc.make + +# Other files to distribute +# e.g. EXTRA_DIST += version.xml.in +EXTRA_DIST += + +# Files not to distribute +# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types +# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt +#DISTCLEANFILES += + +# Comment this out if you want 'make check' to test you doc status +# and run some sanity checks +if ENABLE_GTK_DOC +TESTS_ENVIRONMENT = cd $(srcdir) && \ + DOC_MODULE=$(DOC_MODULE) DOC_MAIN_SGML_FILE=$(DOC_MAIN_SGML_FILE) \ + SRCDIR=$(abs_srcdir) BUILDDIR=$(abs_builddir) +#TESTS = $(GTKDOC_CHECK) +endif + +-include $(top_srcdir)/git.mk diff --git a/src/Makefile.am b/src/Makefile.am index 1fbeb25..f73eba9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ bin_PROGRAMS = astrognome astrognome_SOURCES = astrognome.c calculate.c -astrognome_LDADD = $(LIBSWE_LIBS) $(GTK_LIBS) +astrognome_LDADD = $(LIBSWE_LIBS) $(LIBSWE_GLIB_LIBS) $(GTK_LIBS) astrognome_LDFLAGS = -rdynamic astrognome_CFLAGS = $(CFLAGS) $(GTK_CFLAGS) -Wall diff --git a/swe-glib/src/Makefile.am b/swe-glib/src/Makefile.am new file mode 100644 index 0000000..86f3371 --- /dev/null +++ b/swe-glib/src/Makefile.am @@ -0,0 +1,24 @@ +AM_CPPFLAGS = -DG_LOG_DOMAIN=\"SWE-GLib\" -DLOCALEDIR=\"$(localedir)\" -D__SWE_GLIB_BUILDING__ + +lib_LTLIBRARIES = libswe-glib-0.1.la + +libswe_glib_sources = swe-glib.c gswe-moment.c gswe-timestamp.c enumtypes.c +gswe_headers = gswe-timestamp.h gswe-types.h + +libswe_glib_0_1_la_SOURCES = $(libswe_glib_sources) +libswe_glib_0_1_la_CFLAGS = $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) -Wall +libswe_glib_0_1_la_LIBADD = $(GLIB_LIBS) $(GOBJECT_LIBS) $(LIBSWE_LIBS) + +BUILT_SOURCES = enumtypes.c enumtypes.h + +CLEANFILES = $(BUILT_SOURCES) + +EXTRA_DIST = enumtypes.h.template enumtypes.c.template + +enumtypes.h: $(gswe_headers) enumtypes.h.template + $(GLIB_MKENUMS) --template $(filter %.template,$^) $(filter-out %.template,$^) > \ + enumtypes.h.tmp && mv enumtypes.h.tmp enumtypes.h + +enumtypes.c: $(gswe_headers) enumtypes.h enumtypes.c.template + $(GLIB_MKENUMS) --template $(filter %.template,$^) $(filter-out %.template,$^) > \ + enumtypes.c.tmp && mv enumtypes.c.tmp enumtypes.c diff --git a/swe-glib/src/enumtypes.c.template b/swe-glib/src/enumtypes.c.template new file mode 100644 index 0000000..2beff93 --- /dev/null +++ b/swe-glib/src/enumtypes.c.template @@ -0,0 +1,38 @@ +/*** BEGIN file-header ***/ +#include "enumtypes.h" +#include "@filename@" + +/*** END file-header ***/ + +/*** BEGIN file-production ***/ +/* enumerations from "@filename@" */ +/*** END file-production ***/ + +/*** BEGIN value-header ***/ +GType +@enum_name@_get_type(void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter(&g_define_type_id__volatile)) { + static const G@Type@Value values[] = { +/*** END value-header ***/ + +/*** BEGIN value-production ***/ + { @VALUENAME@, "@VALUENAME@", "@valuenick@" }, +/*** END value-production ***/ + +/*** BEGIN value-tail ***/ + { 0, NULL, NULL } + }; + + GType g_define_type_id = g_@type@_register_static(g_intern_static_string("@EnumName@"), values); + + g_once_init_leave(&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} + +/*** END value-tail ***/ + diff --git a/swe-glib/src/enumtypes.h.template b/swe-glib/src/enumtypes.h.template new file mode 100644 index 0000000..f12fea3 --- /dev/null +++ b/swe-glib/src/enumtypes.h.template @@ -0,0 +1,25 @@ +/*** BEGIN file-header ***/ +#ifndef __GSWE_ENUM_TYPES_H__ +#define __GSWE_ENUM_TYPES_H__ + +#include + +/*** END file-header ***/ + +/*** BEGIN file-production ***/ + +/* enumerations from "@filename@" */ + +#include "@filename@" +/*** END file-production ***/ + +/*** BEGIN value-header ***/ +GType @enum_name@_get_type(void); +#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type()) +/*** END value-header ***/ + +/*** BEGIN file-tail ***/ + +#endif /* __GSWE_ENUM_TYPES_H__ */ +/*** END file-tail ***/ + diff --git a/swe-glib/src/gswe-moment.c b/swe-glib/src/gswe-moment.c new file mode 100644 index 0000000..1393fae --- /dev/null +++ b/swe-glib/src/gswe-moment.c @@ -0,0 +1,152 @@ +#include +#include "gswe-moment.h" + +#define GSWE_MOMENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), GSWE_TYPE_MOMENT, GsweMomentPrivate)) + +struct _GsweMomentPrivate { + GDateTime *timestamp; + gdouble julian_timestamp; + GsweCoordinates coordinates; +}; + +enum { + SIGNAL_MOMENT_CHANGED, + SIGNAL_LAST +}; + +enum { + PROP_0, + PROP_TIMESTAMP +}; + +static guint gswe_moment_signals[SIGNAL_LAST] = {0}; + +static void gswe_moment_dispose(GObject *gobject); +static void gswe_moment_finalize(GObject *gobject); +static void gswe_moment_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); +static void gswe_moment_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); + +G_DEFINE_TYPE(GsweMoment, gswe_moment, G_TYPE_OBJECT); + +static void +gswe_moment_class_init(GsweMomentClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(GsweMomentPrivate)); + + gobject_class->dispose = gswe_moment_dispose; + gobject_class->finalize = gswe_moment_finalize; + gobject_class->set_property = gswe_moment_set_property; + gobject_class->get_property = gswe_moment_get_property; + + /** + * GsweMoment::moment-changed: + * @moment: the GsweMoment object that received the signal + * + * The ::moment-changed signal is emitted each time the time or coordinates are changed + */ + gswe_moment_signals[SIGNAL_MOMENT_CHANGED] = g_signal_new("moment-changed", G_OBJECT_CLASS_TYPE(gobject_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(GsweMomentClass, moment_changed), NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 0); + + /** + * GsweMoment:timestamp: + * + * The timestamp associated with this moment + */ + g_object_class_install_property(gobject_class, PROP_TIMESTAMP, g_param_spec_pointer("timestamp", "Timestamp", "Timestamp of this moment", G_PARAM_READWRITE)); +} + +static void +gswe_moment_emit_moment_changed(GsweMoment *moment) +{ + g_signal_emit(moment, gswe_moment_signals[SIGNAL_MOMENT_CHANGED], 0); +} + +void +gswe_moment_init(GsweMoment *self) +{ + self->priv = GSWE_MOMENT_GET_PRIVATE(self); + + //self->priv->an_object = g_object_new(MAMAN_TYPE_BAZ, NULL); + //self->priv->a_string = g_strdup("Maman"); +} + +static void +gswe_moment_dispose(GObject *gobject) +{ + //GsweMoment *self = GSWE_MOMENT(gobject); + + //g_clear_object(&self->priv->an_object); + + G_OBJECT_CLASS(gswe_moment_parent_class)->dispose(gobject); +} + +static void +gswe_moment_finalize(GObject *gobject) +{ + //GsweMoment *self = GSWE_MOMENT(gobject); + + //g_free(self->priv->a_string); + + G_OBJECT_CLASS(gswe_moment_parent_class)->finalize(gobject); +} + +static void +gswe_moment_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + GsweMoment *moment = GSWE_MOMENT(object); + + switch (prop_id) { + case PROP_TIMESTAMP: + gswe_moment_set_timestamp(moment, (g_value_get_object(value))); + + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + + break; + } +} + +static void +gswe_moment_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + GsweMoment *moment = GSWE_MOMENT(object); + GsweMomentPrivate *priv = moment->priv; + + switch (prop_id) { + case PROP_TIMESTAMP: + g_value_set_object(value, priv->timestamp); + + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + + break; + } +} + +void +gswe_moment_set_timestamp(GsweMoment *moment, GsweTimestamp *timestamp) +{ + GsweMomentPrivate *priv = moment->priv; + + /* Emit the moment-changed signal to notify registrants of the change */ + priv->timestamp = timestamp; + gswe_moment_emit_moment_changed(moment); +} + +GQuark +gswe_moment_error_quark(void) +{ + return g_quark_from_static_string("swe-glib-gswe-moment-error"); +} + +GsweMoment * +gswe_moment_new(void) +{ + return (GsweMoment *)g_object_new(GSWE_TYPE_MOMENT, NULL); +} + diff --git a/swe-glib/src/gswe-moment.h b/swe-glib/src/gswe-moment.h new file mode 100644 index 0000000..d56383a --- /dev/null +++ b/swe-glib/src/gswe-moment.h @@ -0,0 +1,68 @@ +#ifndef __GSWE_MOMENT_H__ +#define __GSWE_MOMENT_H__ + +#include + +#define GSWE_TYPE_MOMENT (gswe_moment_get_type()) +#define GSWE_MOMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GSWE_TYPE_MOMENT, GsweMoment)) +#define GSWE_IS_MOMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GSWE_TYPE_MOMENT)) +#define GSWE_MOMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GSWE_TYPE_MOMENT, GsweMomentClass)) +#define GSWE_IS_MOMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GSWE_TYPE_MOMENT)) +#define GSWE_MOMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GSWE_TYPE_MOMENT, GsweMomentClass)) + +typedef struct _GsweMoment GsweMoment; +typedef struct _GsweMomentClass GsweMomentClass; +typedef struct _GsweMomentPrivate GsweMomentPrivate; + +#define GSWE_MOMENT_ERROR gswe_moment_error_quark() +GQuark gswe_moment_error_quark(void); + +/* + * GsweMomentError: + * + * Error values for GsweTimestamp initialization + */ +//typedef enum { +//} GsweMomentError; + +/** + * GsweCoordinates: + * @longitude: longitude part of the coordinates + * @latitude: latitude part of the coordinates + * + * GsweCoordinates specifies an exact point on Earth's surface + */ +typedef struct _GsweCoordinates { + gdouble longitude; + gdouble latitude; +} GsweCoordinates; + +struct _GsweMoment { + /* Parent instance structure */ + GObject parent_instance; + + /* Instance members */ + + /*< private >*/ + GsweMomentPrivate *priv; +}; + +struct _GsweMomentClass { + /* Parent class structure */ + GObjectClass parent_class; + + /* Class members */ + + /*< private >*/ + void (*moment_changed)(GsweMoment *moment); +}; + +/* used by GSWE_TYPE_MOMENT */ +GType gswe_moment_get_type(void); + +/* Method definitions */ +GsweMoment *gswe_moment_new(void); +void gswe_moment_set_timestamp(GsweMoment *moment, GsweTimestamp *timestamp); + +#endif /* __GSWE_MOMENT_H__ */ + diff --git a/swe-glib/src/gswe-timestamp.c b/swe-glib/src/gswe-timestamp.c new file mode 100644 index 0000000..c383847 --- /dev/null +++ b/swe-glib/src/gswe-timestamp.c @@ -0,0 +1,597 @@ +#include +#include + +#include "../../swe/src/swephexp.h" +#include "swe-glib-private.h" +#include "gswe-timestamp.h" + +#define GSWE_TIMESTAMP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), GSWE_TYPE_TIMESTAMP, GsweTimestampPrivate)) + +typedef enum { + VALID_GREGORIAN = 1 << 0, + VALID_JULIAN_DAY = 1 << 1 +} TimestampValidity; + +struct _GsweTimestampPrivate { + gboolean instant_recalc; + TimestampValidity valid_dates; + + gint gregorian_year; + gint gregorian_month; + gint gregorian_day; + gint gregorian_hour; + gint gregorian_minute; + gint gregorian_second; + gint gregorian_microsecond; + GTimeZone *gregorian_timezone; + + gdouble julian_day; +}; + +enum { + SIGNAL_CHANGED, + SIGNAL_LAST +}; + +enum { + PROP_0, + PROP_INSTANT_RECALC, + PROP_GREGORIAN_VALID, + PROP_GREGORIAN_YEAR, + PROP_GREGORIAN_MONTH, + PROP_GREGORIAN_DAY, + PROP_GREGORIAN_HOUR, + PROP_GREGORIAN_MINUTE, + PROP_GREGORIAN_SECOND, + PROP_GREGORIAN_MICROSECOND, + PROP_JULIAN_DAY_VALID +}; + +static guint gswe_timestamp_signals[SIGNAL_LAST] = { 0 }; + +static void gswe_timestamp_dispose(GObject *gobject); +static void gswe_timestamp_finalize(GObject *gobject); +static void gswe_timestamp_set_property(GObject *gobject, guint prop_id, const GValue *value, GParamSpec *pspec); +static void gswe_timestamp_get_property(GObject *gobject, guint prop_id, GValue *value, GParamSpec *pspec); +static void gswe_timestamp_calculate_all(GsweTimestamp *timestamp); +static void gswe_timestamp_calculate_gregorian(GsweTimestamp *timestamp); +static void gswe_timestamp_calculate_julian(GsweTimestamp *timestamp); + +G_DEFINE_TYPE(GsweTimestamp, gswe_timestamp, G_TYPE_OBJECT); + +static void +gswe_timestamp_class_init(GsweTimestampClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + GDateTime *local_time = g_date_time_new_now_local(); + + g_type_class_add_private(klass, sizeof(GsweTimestampPrivate)); + + gobject_class->dispose = gswe_timestamp_dispose; + gobject_class->finalize = gswe_timestamp_finalize; + gobject_class->set_property = gswe_timestamp_set_property; + gobject_class->get_property = gswe_timestamp_get_property; + + /** + * GsweTimestamp::changed: + * @timestamp: the GsweTimestamp that receives the signal + * + * The ::changed signal is emitted each time the timestamp is changed + */ + gswe_timestamp_signals[SIGNAL_CHANGED] = g_signal_new("changed", G_OBJECT_CLASS_TYPE(gobject_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(GsweTimestampClass, changed), NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 0); + + /** + * GsweTimestamp:instant-recalc: + * + * If set to TRUE, recalculate timestamp values instantly, when changing a + * parameter (e.g. recalculate Julian date when changing Gregorian year). + * Otherwise, the values are recalculated only upon request (e.g. on + * calling #gswe_timestamp_get_julian_day()). + */ + g_object_class_install_property(gobject_class, PROP_INSTANT_RECALC, g_param_spec_boolean("instant-recalc", "Instant recalculation", "Instantly recalculate values upon parameter change", FALSE, G_PARAM_READWRITE)); + + /** + * GsweTimestamp:gregorian-valid + * + * If TRUE, the Gregorian value stored in the GsweTimestamp object is + * currently considered as valid, thus, no recalculation is needed. + * Otherwise, the Gregorian date components will be recalculated upon + * request. + */ + g_object_class_install_property(gobject_class, PROP_GREGORIAN_VALID, g_param_spec_boolean("gregorian-valid", "Gregorian date is valid", "TRUE if the Gregorian date components are considered as valid.", TRUE, G_PARAM_READABLE)); + + /** + * GsweTimestamp:gregorian-year: + * + * The Gregorian year of the timestamp + */ + g_object_class_install_property(gobject_class, PROP_GREGORIAN_YEAR, g_param_spec_int("gregorian-year", "Gregorian year", "The year according to the Gregorian calendar", G_MININT, G_MAXINT, g_date_time_get_year(local_time), G_PARAM_READWRITE)); + + /** + * GsweTimestamp:gregorian-month: + * + * The Gregorian month of the timestamp + */ + g_object_class_install_property(gobject_class, PROP_GREGORIAN_MONTH, g_param_spec_int("gregorian-month", "Gregorian month", "The month according to the Gregorian calendar", 1, 12, g_date_time_get_month(local_time), G_PARAM_READWRITE)); + + /** + * GsweTimestamp:gregorian-day: + * + * The Gregorian day of the timestamp + */ + g_object_class_install_property(gobject_class, PROP_GREGORIAN_DAY, g_param_spec_int("gregorian-day", "Gregorian day", "The day according to the Gregorian calendar", 1, 31, g_date_time_get_day_of_month(local_time), G_PARAM_READWRITE)); + + /** + * GsweTimestamp:gregorian-hour: + * + * The Gregorian hour of the timestamp + */ + g_object_class_install_property(gobject_class, PROP_GREGORIAN_HOUR, g_param_spec_int("gregorian-hour", "Gregorian hour", "The hour according to the Gregorian calendar", 0, 23, g_date_time_get_hour(local_time), G_PARAM_READWRITE)); + + /** + * GsweTimestamp:gregorian-minute: + * + * The Gregorian minute of the timestamp + */ + g_object_class_install_property(gobject_class, PROP_GREGORIAN_MINUTE, g_param_spec_int("gregorian-minute", "Gregorian minute", "The minute according to the Gregorian calendar", 0, 59, g_date_time_get_minute(local_time), G_PARAM_READWRITE)); + + /** + * GsweTimestamp:gregorian-second: + * + * The Gregorian second of the timestamp + */ + g_object_class_install_property(gobject_class, PROP_GREGORIAN_SECOND, g_param_spec_int("gregorian-second", "Gregorian second", "The second according to the Gregorian calendar", 0, 61, g_date_time_get_second(local_time), G_PARAM_READWRITE)); + + /** + * GsweTimestamp:gregorian-microsecond: + * + * The Gregorian microsecond of the timestamp + */ + g_object_class_install_property(gobject_class, PROP_GREGORIAN_MICROSECOND, g_param_spec_int("gregorian-microsecond", "Gregorian microsecond", "The microsecond according to the Gregorian calendar", 0, G_MAXINT, g_date_time_get_microsecond(local_time), G_PARAM_READWRITE)); + + /** + * GsweTimestamp:julian-day-valid + * + * If TRUE, the Julian day value stored in the GsweTimestamp object is + * currently considered as valid, thus, no recalculation is needed. + * Otherwise, the Julian day components will be recalculated upon request. + */ + g_object_class_install_property(gobject_class, PROP_JULIAN_DAY_VALID, g_param_spec_boolean("julian-day-valid", "Julian day is valid", "TRUE if the Julian day components are considered as valid.", TRUE, G_PARAM_READABLE)); + + g_date_time_unref(local_time); +} + +static void +gswe_timestamp_emit_changed(GsweTimestamp *timestamp) +{ + g_signal_emit(timestamp, gswe_timestamp_signals[SIGNAL_CHANGED], 0); +} + +void +gswe_timestamp_init(GsweTimestamp *self) +{ + self->priv = GSWE_TIMESTAMP_GET_PRIVATE(self); + + self->priv->gregorian_timezone = g_time_zone_new_local(); +} + +static void +gswe_timestamp_dispose(GObject *gobject) +{ + G_OBJECT_CLASS(gswe_timestamp_parent_class)->dispose(gobject); +} + +static void +gswe_timestamp_finalize(GObject *gobject) +{ + G_OBJECT_CLASS(gswe_timestamp_parent_class)->finalize(gobject); +} + +static void +gswe_timestamp_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + GsweTimestamp *timestamp = GSWE_TIMESTAMP(object); + + switch (prop_id) { + case PROP_INSTANT_RECALC: + gswe_timestamp_calculate_all(timestamp); + + break; + + case PROP_GREGORIAN_YEAR: + gswe_timestamp_set_gregorian_year(timestamp, g_value_get_int(value)); + + break; + + case PROP_GREGORIAN_MONTH: + gswe_timestamp_set_gregorian_month(timestamp, g_value_get_int(value)); + + break; + + case PROP_GREGORIAN_DAY: + gswe_timestamp_set_gregorian_day(timestamp, g_value_get_int(value)); + + break; + + case PROP_GREGORIAN_HOUR: + gswe_timestamp_set_gregorian_hour(timestamp, g_value_get_int(value)); + + break; + + case PROP_GREGORIAN_MINUTE: + gswe_timestamp_set_gregorian_minute(timestamp, g_value_get_int(value)); + + break; + + case PROP_GREGORIAN_SECOND: + gswe_timestamp_set_gregorian_second(timestamp, g_value_get_int(value)); + + break; + + case PROP_GREGORIAN_MICROSECOND: + gswe_timestamp_set_gregorian_microsecond(timestamp, g_value_get_int(value)); + + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + + break; + } +} + +static void +gswe_timestamp_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + GsweTimestamp *timestamp = GSWE_TIMESTAMP(object); + + switch (prop_id) { + case PROP_INSTANT_RECALC: + g_value_set_boolean(value, timestamp->priv->instant_recalc); + + break; + + case PROP_GREGORIAN_VALID: + g_value_set_boolean(value, ((timestamp->priv->valid_dates & VALID_GREGORIAN) == VALID_GREGORIAN)); + + break; + + case PROP_GREGORIAN_YEAR: + gswe_timestamp_calculate_gregorian(timestamp); + g_value_set_int(value, timestamp->priv->gregorian_year); + + break; + + case PROP_GREGORIAN_MONTH: + gswe_timestamp_calculate_gregorian(timestamp); + g_value_set_int(value, timestamp->priv->gregorian_month); + + break; + + case PROP_GREGORIAN_DAY: + gswe_timestamp_calculate_gregorian(timestamp); + g_value_set_int(value, timestamp->priv->gregorian_day); + + break; + + case PROP_GREGORIAN_HOUR: + gswe_timestamp_calculate_gregorian(timestamp); + g_value_set_int(value, timestamp->priv->gregorian_hour); + + break; + + case PROP_GREGORIAN_MINUTE: + gswe_timestamp_calculate_gregorian(timestamp); + g_value_set_int(value, timestamp->priv->gregorian_minute); + + break; + + case PROP_GREGORIAN_SECOND: + gswe_timestamp_calculate_gregorian(timestamp); + g_value_set_int(value, timestamp->priv->gregorian_second); + + break; + + case PROP_GREGORIAN_MICROSECOND: + gswe_timestamp_calculate_gregorian(timestamp); + g_value_set_int(value, timestamp->priv->gregorian_microsecond); + + break; + + case PROP_JULIAN_DAY_VALID: + g_value_set_boolean(value, ((timestamp->priv->valid_dates & VALID_JULIAN_DAY) == VALID_JULIAN_DAY)); + + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + + break; + } +} + +static void +gswe_timestamp_calculate_all(GsweTimestamp *timestamp) +{ + if ((timestamp->priv->valid_dates & VALID_JULIAN_DAY) != VALID_JULIAN_DAY) { + gswe_timestamp_calculate_julian(timestamp); + } + + if ((timestamp->priv->valid_dates & VALID_GREGORIAN) != VALID_GREGORIAN) { + gswe_timestamp_calculate_gregorian(timestamp); + } +} + +static void +gswe_timestamp_calculate_gregorian(GsweTimestamp *timestamp) +{ + if ((timestamp->priv->valid_dates & VALID_GREGORIAN) == VALID_GREGORIAN) { + return; + } + + if (timestamp->priv->valid_dates == 0) { + g_error("This timestamp object holds no valid values. This can't be good."); + } + + g_warning("This method is not implemented yet."); +} + +void +gswe_timestamp_set_instant_recalc(GsweTimestamp *timestamp, gboolean instant_recalc) +{ + timestamp->priv->instant_recalc = instant_recalc; + + if (instant_recalc == TRUE) { + gswe_timestamp_calculate_all(timestamp); + } +} + +gboolean +gswe_timestamp_get_instant_recalc(GsweTimestamp *timestamp) +{ + return timestamp->priv->instant_recalc; +} + +void +gswe_timestamp_set_gregorian_year(GsweTimestamp *timestamp, gint gregorian_year) +{ + timestamp->priv->gregorian_year = gregorian_year; + timestamp->priv->valid_dates = VALID_GREGORIAN; + + if (timestamp->priv->instant_recalc == TRUE) { + gswe_timestamp_calculate_all(timestamp); + } + + gswe_timestamp_emit_changed(timestamp); +} + +gint +gswe_timestamp_get_gregorian_year(GsweTimestamp *timestamp) +{ + gswe_timestamp_calculate_gregorian(timestamp); + + return timestamp->priv->gregorian_year; +} + +void +gswe_timestamp_set_gregorian_month(GsweTimestamp *timestamp, gint gregorian_month) +{ + timestamp->priv->gregorian_month = gregorian_month; + timestamp->priv->valid_dates = VALID_GREGORIAN; + + if (timestamp->priv->instant_recalc == TRUE) { + gswe_timestamp_calculate_all(timestamp); + } + + gswe_timestamp_emit_changed(timestamp); +} + +gint +gswe_timestamp_get_gregorian_month(GsweTimestamp *timestamp) +{ + gswe_timestamp_calculate_gregorian(timestamp); + + return timestamp->priv->gregorian_month; +} + +void +gswe_timestamp_set_gregorian_day(GsweTimestamp *timestamp, gint gregorian_day) +{ + timestamp->priv->gregorian_day = gregorian_day; + timestamp->priv->valid_dates = VALID_GREGORIAN; + + if (timestamp->priv->instant_recalc == TRUE) { + gswe_timestamp_calculate_all(timestamp); + } + + gswe_timestamp_emit_changed(timestamp); +} + +gint +gswe_timestamp_get_gregorian_day(GsweTimestamp *timestamp) +{ + gswe_timestamp_calculate_gregorian(timestamp); + + return timestamp->priv->gregorian_day; +} + +void +gswe_timestamp_set_gregorian_hour(GsweTimestamp *timestamp, gint gregorian_hour) +{ + timestamp->priv->gregorian_hour = gregorian_hour; + timestamp->priv->valid_dates = VALID_GREGORIAN; + + if (timestamp->priv->instant_recalc == TRUE) { + gswe_timestamp_calculate_all(timestamp); + } + + gswe_timestamp_emit_changed(timestamp); +} + +gint +gswe_timestamp_get_gregorian_hour(GsweTimestamp *timestamp) +{ + gswe_timestamp_calculate_gregorian(timestamp); + + return timestamp->priv->gregorian_hour; +} + +void +gswe_timestamp_set_gregorian_minute(GsweTimestamp *timestamp, gint gregorian_minute) +{ + timestamp->priv->gregorian_minute = gregorian_minute; + timestamp->priv->valid_dates = VALID_GREGORIAN; + + if (timestamp->priv->instant_recalc == TRUE) { + gswe_timestamp_calculate_all(timestamp); + } + + gswe_timestamp_emit_changed(timestamp); +} + +gint +gswe_timestamp_get_gregorian_minute(GsweTimestamp *timestamp) +{ + gswe_timestamp_calculate_gregorian(timestamp); + + return timestamp->priv->gregorian_minute; +} + +void +gswe_timestamp_set_gregorian_second(GsweTimestamp *timestamp, gint gregorian_second) +{ + timestamp->priv->gregorian_second = gregorian_second; + timestamp->priv->valid_dates = VALID_GREGORIAN; + + if (timestamp->priv->instant_recalc == TRUE) { + gswe_timestamp_calculate_all(timestamp); + } + + gswe_timestamp_emit_changed(timestamp); +} + +gint +gswe_timestamp_get_gregorian_second(GsweTimestamp *timestamp) +{ + gswe_timestamp_calculate_gregorian(timestamp); + + return timestamp->priv->gregorian_second; +} + +void +gswe_timestamp_set_gregorian_microsecond(GsweTimestamp *timestamp, gint gregorian_microsecond) +{ + timestamp->priv->gregorian_microsecond = gregorian_microsecond; + timestamp->priv->valid_dates = VALID_GREGORIAN; + + if (timestamp->priv->instant_recalc == TRUE) { + gswe_timestamp_calculate_all(timestamp); + } + + gswe_timestamp_emit_changed(timestamp); +} + +gint +gswe_timestamp_get_gregorian_microsecond(GsweTimestamp *timestamp) +{ + gswe_timestamp_calculate_gregorian(timestamp); + + return timestamp->priv->gregorian_microsecond; +} + +static void +gswe_timestamp_calculate_julian(GsweTimestamp *timestamp) +{ + gint utc_year, + utc_month, + utc_day, + utc_hour, + utc_minute, + retval; + gdouble utc_second, + dret[2]; + gchar serr[AS_MAXCH]; + + if ((timestamp->priv->valid_dates & VALID_JULIAN_DAY) == VALID_JULIAN_DAY) { + return; + } + + if (timestamp->priv->valid_dates == 0) { + g_error("This timestamp object holds no valid values. This can't be good."); + } + + swe_utc_time_zone(timestamp->priv->gregorian_year, timestamp->priv->gregorian_month, timestamp->priv->gregorian_day, timestamp->priv->gregorian_hour, timestamp->priv->gregorian_minute, timestamp->priv->gregorian_second + timestamp->priv->gregorian_microsecond / 1000.0, g_time_zone_get_offset(timestamp->priv->gregorian_timezone, 0) / 3600.0, &utc_year, &utc_month, &utc_day, &utc_hour, &utc_minute, &utc_second); + if ((retval = swe_utc_to_jd(utc_year, utc_month, utc_day, utc_hour, utc_minute, utc_second, SE_GREG_CAL, dret, serr)) == ERR) { + g_error("Swiss Ephemeris error: %s", serr); + } else { + timestamp->priv->julian_day = dret[0]; + timestamp->priv->valid_dates |= VALID_JULIAN_DAY; + } +} + +void +gswe_timestamp_set_julian_day(GsweTimestamp *timestamp, gdouble julian_day) +{ + timestamp->priv->julian_day = julian_day; + timestamp->priv->valid_dates = VALID_JULIAN_DAY; + + if (timestamp->priv->instant_recalc == TRUE) { + gswe_timestamp_calculate_all(timestamp); + } + + gswe_timestamp_emit_changed(timestamp); +} + +gdouble +gswe_timestamp_get_julian_day(GsweTimestamp *timestamp) +{ + gswe_timestamp_calculate_julian(timestamp); + + return timestamp->priv->julian_day; +} + +GQuark +gswe_timestamp_error_quark(void) +{ + return g_quark_from_static_string("swe-glib-gswe-timestamp-error"); +} + +GsweTimestamp * +gswe_timestamp_new(void) +{ + return GSWE_TIMESTAMP(g_object_new(GSWE_TYPE_TIMESTAMP, NULL)); +} + +GsweTimestamp * +gswe_timestamp_new_from_gregorian_full(gint year, gint month, gint day, gint hour, gint minute, gint second, gint microsecond, GTimeZone *time_zone) +{ + GsweTimestamp *timestamp = GSWE_TIMESTAMP(g_object_new(GSWE_TYPE_TIMESTAMP, + "gregorian-year", year, + "gregorian-month", month, + "gregorian-day", day, + "gregorian-hour", hour, + "gregorian-minute", minute, + "gregorian-second", second, + "gregorian-microsecond", microsecond, + NULL)); + + if (timestamp->priv->gregorian_timezone != NULL) { + g_time_zone_unref(timestamp->priv->gregorian_timezone); + } + + timestamp->priv->gregorian_timezone = g_time_zone_ref(time_zone); + timestamp->priv->valid_dates = VALID_GREGORIAN; + + return timestamp; +} + +GsweTimestamp * +gswe_timestamp_new_from_julian_day(gdouble julian_day) +{ + GsweTimestamp *timestamp = gswe_timestamp_new(); + + gswe_timestamp_set_julian_day(timestamp, julian_day); + + return timestamp; +} + diff --git a/swe-glib/src/gswe-timestamp.h b/swe-glib/src/gswe-timestamp.h new file mode 100644 index 0000000..4c7196d --- /dev/null +++ b/swe-glib/src/gswe-timestamp.h @@ -0,0 +1,69 @@ +#ifndef __SWE_GLIB_GSWE_TIMESTAMP_H__ +#define __SWE_GLIB_GSWE_TIMESTAMP_H__ + +#include + +#define GSWE_TYPE_TIMESTAMP (gswe_timestamp_get_type()) +#define GSWE_TIMESTAMP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GSWE_TYPE_TIMESTAMP, GsweTimestamp)) +#define GSWE_IS_TIMESTAMP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GSWE_TYPE_TIMESTAMP)) +#define GSWE_TIMESTAMP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GSWE_TYPE_TIMESTAMP, GsweTimestampClass)) +#define GSWE_IS_TIMESTAMP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GSWE_TYPE_TIMESTAMP)) +#define GSWE_TIMESTAMP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GSWE_TYPE_TIMESTAMP, GsweTimestampClass)) + +typedef struct _GsweTimestamp GsweTimestamp; +typedef struct _GsweTimestampClass GsweTimestampClass; +typedef struct _GsweTimestampPrivate GsweTimestampPrivate; + +#define GSWE_TIMESTAMP_ERROR (gswe_timestamp_error_quark()) +GQuark gswe_timestamp_error_quark(void); + +typedef enum { + GSWE_TIMESTAMP_ERROR_INVALID_DATE, + GSWE_TIMESTAMP_ERROR_INVALID_TIME +} GsweTimestampError; + +struct _GsweTimestamp { + /* Parent instance structure */ + GObject parent_instance; + + /* Instance members */ + + /*< private >*/ + GsweTimestampPrivate *priv; +}; + +struct _GsweTimestampClass { + /* Parent class */ + GObjectClass parent_class; + + /* Class members */ + void (*changed)(GsweTimestamp *self); +}; + +GType gswe_timestamp_get_type(void); + +/* Method definitions */ +GsweTimestamp *gswe_timestamp_new(void); +GsweTimestamp *gswe_timestamp_new_from_julian_day(gdouble julian_day); +GsweTimestamp * gswe_timestamp_new_from_gregorian_full(gint year, gint month, gint day, gint hour, gint minute, gint second, gint microsecond, GTimeZone *time_zone); +void gswe_timestamp_set_instant_recalc(GsweTimestamp *timestamp, gboolean instant_recalc); +gboolean gswe_timestamp_get_instant_recalc(GsweTimestamp *timestamp); +void gswe_timestamp_set_gregorian_year(GsweTimestamp *timestamp, gint gregorian_year); +gint gswe_timestamp_get_gregorian_year(GsweTimestamp *timestamp); +void gswe_timestamp_set_gregorian_month(GsweTimestamp *timestamp, gint gregorian_month); +gint gswe_timestamp_get_gregorian_month(GsweTimestamp *timestamp); +void gswe_timestamp_set_gregorian_day(GsweTimestamp *timestamp, gint gregorian_day); +gint gswe_timestamp_get_gregorian_day(GsweTimestamp *timestamp); +void gswe_timestamp_set_gregorian_hour(GsweTimestamp *timestamp, gint gregorian_hour); +gint gswe_timestamp_get_gregorian_hour(GsweTimestamp *timestamp); +void gswe_timestamp_set_gregorian_minute(GsweTimestamp *timestamp, gint gregorian_minute); +gint gswe_timestamp_get_gregorian_minute(GsweTimestamp *timestamp); +void gswe_timestamp_set_gregorian_second(GsweTimestamp *timestamp, gint gregorian_second); +gint gswe_timestamp_get_gregorian_second(GsweTimestamp *timestamp); +void gswe_timestamp_set_gregorian_microsecond(GsweTimestamp *timestamp, gint gregorian_microsecond); +gint gswe_timestamp_get_gregorian_microsecond(GsweTimestamp *timestamp); +void gswe_timestamp_set_julian_day(GsweTimestamp *timestamp, gdouble julian_day); +gdouble gswe_timestamp_get_julian_day(GsweTimestamp *timestamp); + +#endif /* __SWE_GLIB_GSWE_TIMESTAMP_H__ */ + diff --git a/swe-glib/src/gswe-types.h b/swe-glib/src/gswe-types.h new file mode 100644 index 0000000..70f3bfb --- /dev/null +++ b/swe-glib/src/gswe-types.h @@ -0,0 +1,85 @@ +#ifndef __SWE_GLIB_GSWE_PLANETS_H__ +#define __SWE_GLIB_GSWE_PLANETS_H__ + +typedef enum { + GSWE_PLANET_NONE, + GSWE_PLANET_SUN, + GSWE_PLANET_MOON, + GSWE_PLANET_MERCURY, + GSWE_PLANET_VENUS, + GSWE_PLANET_EARTH, + GSWE_PLANET_MARS, + GSWE_PLANET_JUPITER, + GSWE_PLANET_SATURN, + GSWE_PLANET_URANUS, + GSWE_PLANET_NEPTUNE, + GSWE_PLANET_PLUTO, + GSWE_PLANET_CHIRON, + GSWE_PLANET_CERES, + GSWE_PLANET_PALLAS, + GSWE_PLANET_JUNO, + GSWE_PLANET_VESTA, + GSWE_PLANET_MOON_NODE, + GSWE_PLANET_MOON_APOGEE, + GSWE_PLANET_ASCENDENT, + GSWE_PLANET_MC, + GSWE_PLANET_VERTEX +} GswePlanet; + +typedef enum { + GSWE_SIGN_NONE, + GSWE_SIGN_ARIES, + GSWE_SIGN_TAURUS, + GSWE_SIGN_GEMINI, + GSWE_SIGN_CANCER, + GSWE_SIGN_LEO, + GSWE_SIGN_VIRGO, + GSWE_SIGN_LIBRA, + GSWE_SIGN_SCORPIO, + GSWE_SIGN_SAGITTARIUS, + GSWE_SIGN_CAPRICORN, + GSWE_SIGN_AQUARIUS, + GSWE_SIGN_PISCES +} GsweZodiac; + +typedef enum { + GSWE_ELEMENT_NONE, + GSWE_ELEMENT_FIRE, + GSWE_ELEMENT_EARTH, + GSWE_ELEMENT_AIR, + GSWE_ELEMENT_WATER +} GsweElement; + +typedef enum { + GSWE_QUALITY_NONE, + GSWE_QUALITY_CARDINAL, + GSWE_QUALITY_FIX, + GSWE_QUALITY_MUTABLE +} GsweQuality; + +/** + * GswePlanetInfo: + * @planet: the planet ID + * @orb: the planet's “personal” orb + * @name: the planet's name + * @domicile_sign_1: the first sign in which the planet is domicile + * @domicile_sign_2: the second sign in which the planet is domicile + * @exile_sign_1: the first sign in which the planet is in exile + * @exile_sign_2: the second sign in which the planet is in exile + * @exalted_sign: the sign in which the planet is exalted + * @fall_sign: the sign in which the planet is in fall + */ +typedef struct { + GswePlanet planet; + gdouble orb; + gchar *name; + GsweZodiac domicile_sign_1; + GsweZodiac domicile_sign_2; + GsweZodiac exile_sign_1; + GsweZodiac exile_sign_2; + GsweZodiac exalted_sign; + GsweZodiac fall_sign; +} GswePlanetInfo; + +#endif /* __SWE_GLIB_GSWE_PLANETS_H__ */ + diff --git a/swe-glib/src/swe-glib-private.h b/swe-glib/src/swe-glib-private.h new file mode 100644 index 0000000..30ce07d --- /dev/null +++ b/swe-glib/src/swe-glib-private.h @@ -0,0 +1,10 @@ +#ifdef __SWE_GLIB_BUILDING__ +#ifndef __SWE_GLIB_PRIVATE_H__ + +extern gchar *gswe_ephe_path; + +#endif /* __SWE_GLIB_PRIVATE_H__ */ +#else /* not defined __SWE_GLIB_BUILDING__ */ +#error __FILE__ "Can not be included, unless building SWE-GLib" +#endif /* __SWE_GLIB_BUILDING__ */ + diff --git a/swe-glib/src/swe-glib.c b/swe-glib/src/swe-glib.c new file mode 100644 index 0000000..048ba99 --- /dev/null +++ b/swe-glib/src/swe-glib.c @@ -0,0 +1,74 @@ +#include +#define GETTEXT_PACKAGE "swe-glib" +#include + +#include "../../swe/src/swephexp.h" +#include "swe-glib.h" + +gboolean gswe_initialized = FALSE; +gchar *gswe_ephe_path = NULL; +GHashTable *gswe_planet_info_table; +GArray *gswe_morrison_stephenson_deltat = NULL; + +#define ADD_PLANET(ht, v, i, n, o, dom1, dom2, exi1, exi2, exa, fal) (v) = g_new0(GswePlanetInfo, 1); \ + (v)->planet = (i); \ + (v)->orb = (o); \ + (v)->name = g_strdup(n); \ + (v)->domicile_sign_1 = (dom1); \ + (v)->domicile_sign_2 = (dom2); \ + (v)->exile_sign_1 = (exi1); \ + (v)->exile_sign_2 = (exi2); \ + (v)->exalted_sign = (exa); \ + (v)->fall_sign = (fal); \ + g_hash_table_replace((ht), GINT_TO_POINTER(i), (v)); + +void +gswe_free_planet_info(gpointer planet_info) +{ + g_free(((GswePlanetInfo *)planet_info)->name); + g_free(planet_info); +} + +/** + * gswe_init: + * @sweph_path: the file system path to the Swiss Ephemeris data files + * + * Initializes the SWE-GLib library. It must be called before any calculations + * are made. + */ +void +gswe_init(gchar *sweph_path) +{ + GswePlanetInfo *planet_info; + + bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR); + bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); + + gswe_planet_info_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, gswe_free_planet_info); + + ADD_PLANET(gswe_planet_info_table, planet_info, GSWE_PLANET_SUN, _("Sun"), 13.0, GSWE_SIGN_LEO, GSWE_SIGN_NONE, GSWE_SIGN_AQUARIUS, GSWE_SIGN_NONE, GSWE_SIGN_ARIES, GSWE_SIGN_LIBRA); + ADD_PLANET(gswe_planet_info_table, planet_info, GSWE_PLANET_MOON, _("Moon"), 9.0, GSWE_SIGN_CANCER, GSWE_SIGN_NONE, GSWE_SIGN_CAPRICORN, GSWE_SIGN_NONE, GSWE_SIGN_TAURUS, GSWE_SIGN_SCORPIO); + ADD_PLANET(gswe_planet_info_table, planet_info, GSWE_PLANET_MERCURY, _("Mercury"), 7.0, GSWE_SIGN_GEMINI, GSWE_SIGN_VIRGO, GSWE_SIGN_SAGITTARIUS, GSWE_SIGN_PISCES, GSWE_SIGN_VIRGO, GSWE_SIGN_PISCES); + ADD_PLANET(gswe_planet_info_table, planet_info, GSWE_PLANET_VENUS, _("Venus"), 7.0, GSWE_SIGN_TAURUS, GSWE_SIGN_LIBRA, GSWE_SIGN_SCORPIO, GSWE_SIGN_ARIES, GSWE_SIGN_PISCES, GSWE_SIGN_VIRGO); + ADD_PLANET(gswe_planet_info_table, planet_info, GSWE_PLANET_MARS, _("Mars"), 7.0, GSWE_SIGN_ARIES, GSWE_SIGN_SCORPIO, GSWE_SIGN_LIBRA, GSWE_SIGN_TAURUS, GSWE_SIGN_CAPRICORN, GSWE_SIGN_CANCER); + ADD_PLANET(gswe_planet_info_table, planet_info, GSWE_PLANET_JUPITER, _("Jupiter"), 9.0, GSWE_SIGN_SAGITTARIUS, GSWE_SIGN_PISCES, GSWE_SIGN_GEMINI, GSWE_SIGN_VIRGO, GSWE_SIGN_CANCER, GSWE_SIGN_CAPRICORN); + ADD_PLANET(gswe_planet_info_table, planet_info, GSWE_PLANET_SATURN, _("Saturn"), 7.0, GSWE_SIGN_CAPRICORN, GSWE_SIGN_AQUARIUS, GSWE_SIGN_CANCER, GSWE_SIGN_LEO, GSWE_SIGN_LIBRA, GSWE_SIGN_ARIES); + ADD_PLANET(gswe_planet_info_table, planet_info, GSWE_PLANET_URANUS, _("Uranus"), 5.0, GSWE_SIGN_AQUARIUS, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE); + ADD_PLANET(gswe_planet_info_table, planet_info, GSWE_PLANET_NEPTUNE, _("Neptune"), 5.0, GSWE_SIGN_PISCES, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE); + ADD_PLANET(gswe_planet_info_table, planet_info, GSWE_PLANET_PLUTO, _("Pluto"), 3.0, GSWE_SIGN_SCORPIO, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE); + ADD_PLANET(gswe_planet_info_table, planet_info, GSWE_PLANET_CHIRON, _("Chiron"), 2.0, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE); + ADD_PLANET(gswe_planet_info_table, planet_info, GSWE_PLANET_CERES, _("Ceres"), 2.0, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE); + ADD_PLANET(gswe_planet_info_table, planet_info, GSWE_PLANET_PALLAS, _("Pallas"), 2.0, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE); + ADD_PLANET(gswe_planet_info_table, planet_info, GSWE_PLANET_JUNO, _("Juno"), 2.0, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE); + ADD_PLANET(gswe_planet_info_table, planet_info, GSWE_PLANET_VESTA, _("Vesta"), 2.0, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE); + ADD_PLANET(gswe_planet_info_table, planet_info, GSWE_PLANET_MOON_NODE, _("Ascending Moon Node"), 2.0, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE); + ADD_PLANET(gswe_planet_info_table, planet_info, GSWE_PLANET_MOON_APOGEE, _("Dark Moon"), 2.0, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE); + ADD_PLANET(gswe_planet_info_table, planet_info, GSWE_PLANET_ASCENDENT, _("Ascendent"), 9.0, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE); + ADD_PLANET(gswe_planet_info_table, planet_info, GSWE_PLANET_MC, _("Midheaven"), 5.0, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE); + ADD_PLANET(gswe_planet_info_table, planet_info, GSWE_PLANET_VERTEX, _("Vertex"), 2.0, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE, GSWE_SIGN_NONE); + + gswe_ephe_path = g_strdup(sweph_path); + swe_set_ephe_path(sweph_path); + gswe_initialized = TRUE; +} + diff --git a/swe-glib/src/swe-glib.h b/swe-glib/src/swe-glib.h new file mode 100644 index 0000000..8eb1372 --- /dev/null +++ b/swe-glib/src/swe-glib.h @@ -0,0 +1,11 @@ +#ifndef __SWE_GLIB_H__ +#define __SWE_GLIB_H__ + +#include +#include "gswe-types.h" +#include "gswe-timestamp.h" + +void gswe_init(gchar *sweph_path); + +#endif /* __SWE_GLIB_H__ */ +