2013-07-14 12:40:26 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <cairo.h>
|
|
|
|
#include <clutter/clutter.h>
|
|
|
|
|
|
|
|
#include "../swe/src/swephexp.h"
|
|
|
|
|
2013-07-14 12:37:53 +00:00
|
|
|
#define IMAGEDIR "/home/polesz/Projektek/c/gradix/images"
|
2013-07-14 12:38:47 +00:00
|
|
|
#define EPHEDIR "/home/polesz/Projektek/c/gradix/swe/data"
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 12:50:48 +00:00
|
|
|
#define SYNODIC 29.53058867
|
|
|
|
#define MSPERDAY 86400000
|
|
|
|
|
2013-07-14 12:40:26 +00:00
|
|
|
typedef enum {
|
2013-07-26 14:46:08 +00:00
|
|
|
SIGN_ARIES = 1,
|
|
|
|
SIGN_TAURUS,
|
|
|
|
SIGN_GEMINI,
|
|
|
|
SIGN_CANCER,
|
|
|
|
SIGN_LEO,
|
|
|
|
SIGN_VIRGO,
|
|
|
|
SIGN_LIBRA,
|
|
|
|
SIGN_SCORPIO,
|
|
|
|
SIGN_SAGGITARIUS,
|
|
|
|
SIGN_CAPRICORN,
|
|
|
|
SIGN_AQUARIUS,
|
|
|
|
SIGN_PISCES
|
2013-07-14 12:40:26 +00:00
|
|
|
} zodiacSign;
|
|
|
|
|
2013-07-26 14:53:08 +00:00
|
|
|
typedef enum {
|
|
|
|
TYPE_CARDINAL = 1,
|
|
|
|
TYPE_FIX,
|
|
|
|
TYPE_MUTABLE
|
|
|
|
} signType_t;
|
|
|
|
|
|
|
|
const char *signTypeName[] = {
|
|
|
|
NULL,
|
|
|
|
"Cardinal",
|
|
|
|
"Fix",
|
|
|
|
"Mutable"
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
ELEMENT_FIRE = 1,
|
|
|
|
ELEMENT_EARTH,
|
|
|
|
ELEMENT_AIR,
|
|
|
|
ELEMENT_WATER
|
|
|
|
} signElement_t;
|
|
|
|
|
|
|
|
const char *signElementName[] = {
|
|
|
|
NULL,
|
|
|
|
"Fire",
|
|
|
|
"Earth",
|
|
|
|
"Air",
|
|
|
|
"Water"
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
signType_t type;
|
|
|
|
signElement_t element;
|
|
|
|
int rulingPlanet;
|
|
|
|
} signTypePair_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
double position;
|
|
|
|
zodiacSign sign;
|
|
|
|
int house;
|
|
|
|
short int retrograde;
|
|
|
|
signType_t type;
|
|
|
|
signElement_t element;
|
|
|
|
} planetInfo_t;
|
|
|
|
|
2013-07-26 12:50:48 +00:00
|
|
|
typedef enum {
|
|
|
|
MOON_STATE_NEW,
|
|
|
|
MOON_STATE_WAXING_CRESCENT,
|
|
|
|
MOON_STATE_WAXING_HALF,
|
|
|
|
MOON_STATE_WAXING_GIBBOUS,
|
|
|
|
MOON_STATE_FULL,
|
|
|
|
MOON_STATE_WANING_GIBBOUS,
|
|
|
|
MOON_STATE_WANING_HALF,
|
|
|
|
MOON_STATE_WANING_CRESCENT,
|
|
|
|
MOON_STATE_DARK
|
|
|
|
} moonState;
|
|
|
|
|
2013-07-26 14:53:08 +00:00
|
|
|
const char *moonStateName[] = {
|
|
|
|
"New Moon",
|
|
|
|
"Waxing Crescent Moon",
|
|
|
|
"Waxing Half Moon",
|
|
|
|
"Waxing Gibbous Moon",
|
|
|
|
"Full Moon",
|
|
|
|
"Waning Gibbous Moon",
|
|
|
|
"Waning Half Moon",
|
|
|
|
"Waning Crescent Moon",
|
|
|
|
"Dark Moon"
|
|
|
|
};
|
|
|
|
|
2013-07-26 12:50:48 +00:00
|
|
|
typedef struct {
|
|
|
|
moonState phase;
|
2013-07-26 14:46:08 +00:00
|
|
|
double visiblePercentage;
|
2013-07-26 12:50:48 +00:00
|
|
|
} moonPhase;
|
|
|
|
|
2013-07-26 14:53:08 +00:00
|
|
|
const signTypePair_t signType[] = {
|
|
|
|
{ 0, 0, 0 },
|
|
|
|
{ TYPE_CARDINAL, ELEMENT_FIRE, SE_MARS }, // Aries
|
|
|
|
{ TYPE_FIX, ELEMENT_EARTH, SE_VENUS }, // Taurus
|
|
|
|
{ TYPE_MUTABLE, ELEMENT_AIR, SE_MERCURY }, // Gemini
|
|
|
|
{ TYPE_CARDINAL, ELEMENT_WATER, SE_MOON }, // Cancer
|
|
|
|
{ TYPE_FIX, ELEMENT_FIRE, SE_SUN }, // Leo
|
|
|
|
{ TYPE_MUTABLE, ELEMENT_EARTH, SE_MERCURY }, // Virgo
|
|
|
|
{ TYPE_CARDINAL, ELEMENT_AIR, SE_VENUS }, // Libra
|
|
|
|
{ TYPE_FIX, ELEMENT_WATER, SE_PLUTO }, // Scorpio
|
|
|
|
{ TYPE_MUTABLE, ELEMENT_FIRE, SE_JUPITER }, // Saggitarius
|
|
|
|
{ TYPE_CARDINAL, ELEMENT_EARTH, SE_SATURN }, // Capricorn
|
|
|
|
{ TYPE_FIX, ELEMENT_AIR, SE_URANUS }, // Aquarius
|
|
|
|
{ TYPE_MUTABLE, ELEMENT_WATER, SE_NEPTUNE }, // Pisces
|
|
|
|
};
|
|
|
|
|
|
|
|
const char *signName[] = {
|
|
|
|
NULL,
|
|
|
|
"Aries",
|
|
|
|
"Taurus",
|
|
|
|
"Gemini",
|
|
|
|
"Cancer",
|
|
|
|
"Leo",
|
|
|
|
"Virgo",
|
|
|
|
"Libra",
|
|
|
|
"Scorpio",
|
|
|
|
"Saggitarius",
|
|
|
|
"Capricorn",
|
|
|
|
"Aquarius",
|
|
|
|
"Pisces"
|
|
|
|
};
|
|
|
|
|
2013-07-14 12:40:26 +00:00
|
|
|
//RsvgHandle *svgHandle[SE_CHIRON + SIGN_PISCES + 1];
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
init_graphics(void)
|
|
|
|
{
|
2013-07-26 14:46:08 +00:00
|
|
|
GError *err = NULL;
|
|
|
|
char *svgFile[SE_CHIRON + SIGN_PISCES + 1];
|
|
|
|
int i;
|
|
|
|
|
|
|
|
memset(&svgFile, 0, sizeof(char *) * SE_CHIRON + SIGN_PISCES + 1);
|
|
|
|
|
|
|
|
svgFile[SE_SUN] = IMAGEDIR "/planet_sun.svg";
|
|
|
|
svgFile[SE_MERCURY] = IMAGEDIR "/planet_mercury.svg";
|
|
|
|
svgFile[SE_VENUS] = IMAGEDIR "/planet_venus.svg";
|
|
|
|
svgFile[SE_MOON] = IMAGEDIR "/planet_moon.svg";
|
|
|
|
svgFile[SE_MARS] = IMAGEDIR "/planet_mars.svg";
|
|
|
|
svgFile[SE_JUPITER] = IMAGEDIR "/planet_jupiter.svg";
|
|
|
|
svgFile[SE_SATURN] = IMAGEDIR "/planet_saturn.svg";
|
|
|
|
svgFile[SE_NEPTUNE] = IMAGEDIR "/planet_neptune.svg";
|
|
|
|
svgFile[SE_URANUS] = IMAGEDIR "/planet_uranus.svg";
|
|
|
|
svgFile[SE_PLUTO] = IMAGEDIR "/planet_pluto.svg";
|
|
|
|
// mean node is used for descending moon node
|
|
|
|
svgFile[SE_MEAN_NODE] = IMAGEDIR "/planet_desc_node.svg";
|
|
|
|
// true node is used for ascending moon node
|
|
|
|
svgFile[SE_TRUE_NODE] = IMAGEDIR "/planet_asc_node.svg";
|
|
|
|
svgFile[SE_CHIRON] = IMAGEDIR "/planet_chiron.svg";
|
|
|
|
|
|
|
|
svgFile[SE_CHIRON + SIGN_ARIES] = IMAGEDIR "/sign_aries.svg";
|
|
|
|
svgFile[SE_CHIRON + SIGN_TAURUS] = IMAGEDIR "/sign_taurus.svg";
|
|
|
|
svgFile[SE_CHIRON + SIGN_GEMINI] = IMAGEDIR "/sign_gemini.svg";
|
|
|
|
svgFile[SE_CHIRON + SIGN_CANCER] = IMAGEDIR "/sign_cancer.svg";
|
|
|
|
svgFile[SE_CHIRON + SIGN_LEO] = IMAGEDIR "/sign_leo.svg";
|
|
|
|
svgFile[SE_CHIRON + SIGN_VIRGO] = IMAGEDIR "/sign_virgo.svg";
|
|
|
|
svgFile[SE_CHIRON + SIGN_LIBRA] = IMAGEDIR "/sign_libra.svg";
|
|
|
|
svgFile[SE_CHIRON + SIGN_SCORPIO] = IMAGEDIR "/sign_scorpio.svg";
|
|
|
|
svgFile[SE_CHIRON + SIGN_SAGGITARIUS] = IMAGEDIR "/sign_saggitarius.svg";
|
|
|
|
svgFile[SE_CHIRON + SIGN_CAPRICORN] = IMAGEDIR "/sign_capricorn.svg";
|
|
|
|
svgFile[SE_CHIRON + SIGN_AQUARIUS] = IMAGEDIR "/sign_aquarius.svg";
|
|
|
|
svgFile[SE_CHIRON + SIGN_PISCES] = IMAGEDIR "/sign_pisces.svg";
|
|
|
|
|
|
|
|
for (i = SE_SUN; i <= SE_CHIRON + SIGN_PISCES; i++) {
|
|
|
|
if (svgFile[i] != NULL) {
|
|
|
|
g_clear_error(&err);
|
|
|
|
//if ((svgHandle[i] = rsvg_handle_new_from_file(svgFile[i], &err)) == NULL) {
|
|
|
|
// printf("Unable to load %s: %s\n", svgFile[i], err->message);
|
|
|
|
//}
|
|
|
|
}
|
|
|
|
}
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
return TRUE;
|
2013-07-14 12:40:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
double
|
|
|
|
get_planet_position(int32 planet_no, double date)
|
|
|
|
{
|
|
|
|
int32 iflgret,
|
|
|
|
iflag = SEFLG_SPEED | SEFLG_TOPOCTR;
|
|
|
|
double x2[6];
|
|
|
|
char serr[AS_MAXCH];
|
|
|
|
|
|
|
|
iflgret = swe_calc(date, planet_no, iflag, x2, serr);
|
|
|
|
|
|
|
|
if (iflgret < 0) {
|
|
|
|
printf("error: %s\n", serr);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
} else if (iflgret != iflag) {
|
|
|
|
printf("warning: iflgret != iflag. %s\n", serr);
|
|
|
|
}
|
|
|
|
|
|
|
|
return x2[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
set_location_and_time(double lon, double lat, double alt, int year, int month, int day, int hour, int min, double sec, double d_timezone, double *jd)
|
|
|
|
{
|
2013-07-26 14:57:47 +00:00
|
|
|
int utc_year,
|
|
|
|
utc_month,
|
|
|
|
utc_day,
|
|
|
|
utc_hour,
|
|
|
|
utc_min;
|
|
|
|
double utc_sec,
|
|
|
|
retval,
|
|
|
|
dret[2];
|
|
|
|
char serr[AS_MAXCH];
|
|
|
|
|
|
|
|
swe_set_topo(lon, lat, alt);
|
|
|
|
swe_utc_time_zone(year, month, day, hour, min, sec, d_timezone, &utc_year, &utc_month, &utc_day, &utc_hour, &utc_min, &utc_sec);
|
|
|
|
|
|
|
|
if ((retval = swe_utc_to_jd(utc_year, utc_month, utc_day, utc_hour, utc_min, utc_sec, SE_GREG_CAL, dret, serr)) == ERR) {
|
|
|
|
printf("error: %s\n", serr);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:57:47 +00:00
|
|
|
*jd = dret[0];
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:57:47 +00:00
|
|
|
return 1;
|
2013-07-14 12:40:26 +00:00
|
|
|
}
|
|
|
|
|
2013-07-26 15:01:52 +00:00
|
|
|
long int
|
|
|
|
get_sign(double pos)
|
|
|
|
{
|
|
|
|
return (int)ceilf(pos / 30.0);
|
|
|
|
}
|
|
|
|
|
2013-07-26 12:50:48 +00:00
|
|
|
moonPhase *
|
|
|
|
get_moon_phase(gint year, gint month, gint day, gint hour, gint min, gint sec)
|
|
|
|
{
|
2013-07-26 14:59:09 +00:00
|
|
|
GDateTime *baseDate,
|
2013-07-26 12:50:48 +00:00
|
|
|
*gds;
|
2013-07-26 14:59:09 +00:00
|
|
|
GTimeSpan diff;
|
|
|
|
gdouble phasePercent,
|
2013-07-26 12:50:48 +00:00
|
|
|
realPercent;
|
|
|
|
moonState state;
|
|
|
|
moonPhase *ret;
|
|
|
|
|
2013-07-26 14:59:09 +00:00
|
|
|
baseDate = g_date_time_new_utc(2005, 5, 8, 8, 48, 0);
|
|
|
|
// TODO: this should use the time zone used at the birth place
|
|
|
|
gds = g_date_time_new_local(year, month, day, 0, 0, 0);
|
|
|
|
diff = g_date_time_difference(gds, baseDate) / 1000;
|
2013-07-26 12:50:48 +00:00
|
|
|
|
2013-07-26 14:59:09 +00:00
|
|
|
g_date_time_unref(gds);
|
|
|
|
g_date_time_unref(baseDate);
|
2013-07-26 12:50:48 +00:00
|
|
|
|
2013-07-26 14:59:09 +00:00
|
|
|
// The current phase of the moon, between 0 and 100 (both 0 and 100 are new moon, 50 is full moon)
|
|
|
|
phasePercent = fmod((diff * 100) / (SYNODIC * MSPERDAY), 100);
|
2013-07-26 12:50:48 +00:00
|
|
|
|
2013-07-26 14:59:09 +00:00
|
|
|
if (phasePercent < 0) {
|
|
|
|
phasePercent += 100.0;
|
|
|
|
}
|
2013-07-26 12:50:48 +00:00
|
|
|
|
|
|
|
if ((phasePercent < 0) || (phasePercent > 100)) {
|
|
|
|
fprintf(stderr, "Error during moon phase calculation!\n");
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-07-26 14:59:09 +00:00
|
|
|
// The real percentage is a number around the illumination percentage of the moon
|
|
|
|
realPercent = (50.0 - fabs(phasePercent - 50.0)) * 2;
|
2013-07-26 12:50:48 +00:00
|
|
|
|
|
|
|
// Uuuugly!
|
|
|
|
if (phasePercent == 0) {
|
|
|
|
state = MOON_STATE_NEW;
|
|
|
|
} else if (phasePercent < 25) {
|
|
|
|
state = MOON_STATE_WAXING_CRESCENT;
|
|
|
|
} else if (phasePercent == 25) {
|
|
|
|
state = MOON_STATE_WAXING_HALF;
|
|
|
|
} else if (phasePercent < 50) {
|
|
|
|
state = MOON_STATE_WAXING_GIBBOUS;
|
|
|
|
} else if (phasePercent == 50) {
|
|
|
|
state = MOON_STATE_FULL;
|
|
|
|
} else if (phasePercent < 75) {
|
|
|
|
state = MOON_STATE_WANING_GIBBOUS;
|
|
|
|
} else if (phasePercent == 75) {
|
|
|
|
state = MOON_STATE_WANING_HALF;
|
|
|
|
} else if (phasePercent < 100) {
|
|
|
|
state = MOON_STATE_WANING_CRESCENT;
|
|
|
|
} else {
|
|
|
|
state = MOON_STATE_DARK;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = g_new0(moonPhase, 1);
|
|
|
|
ret->phase = state;
|
|
|
|
ret->visiblePercentage = realPercent;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-07-26 14:59:09 +00:00
|
|
|
int
|
2013-07-14 16:13:41 +00:00
|
|
|
main(int argc, char *argv[])
|
2013-07-14 12:40:26 +00:00
|
|
|
{
|
2013-07-26 15:04:02 +00:00
|
|
|
#if !CLUTTER_CHECK_VERSION(1, 3, 6)
|
|
|
|
#error "You need Clutter >= 1.3.6 to compile this software"
|
|
|
|
#endif
|
2013-07-26 15:01:09 +00:00
|
|
|
int year = 1981,
|
|
|
|
month = 3,
|
|
|
|
day = 11,
|
|
|
|
hour = 23,
|
|
|
|
min = 39,
|
|
|
|
sec = 45,
|
|
|
|
p;
|
|
|
|
double timezone = 1.0,
|
|
|
|
lon = 19.081599,
|
|
|
|
lat = 47.462485,
|
|
|
|
alt = 200,
|
|
|
|
te,
|
|
|
|
cusps[13],
|
|
|
|
ascmc[10];
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:47:44 +00:00
|
|
|
#if 1
|
|
|
|
year = 1983;
|
|
|
|
month = 3;
|
|
|
|
day = 7;
|
|
|
|
hour = 11;
|
|
|
|
min = 54;
|
|
|
|
#endif
|
|
|
|
|
2013-07-14 16:13:41 +00:00
|
|
|
pos,
|
2013-07-14 12:40:26 +00:00
|
|
|
|
|
|
|
|
2013-07-26 15:01:09 +00:00
|
|
|
swe_set_ephe_path(EPHEDIR);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 15:02:55 +00:00
|
|
|
if (set_location_and_time(lon, lat, alt, year, month, day, hour, min, sec, timezone, &te) == 0) {
|
|
|
|
return 1;
|
|
|
|
}
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 15:02:55 +00:00
|
|
|
printf("date: %02d.%02d.%d at %02d:%02d:%02d, at %f, %f\n", year, month, day, hour, min, sec, lon, lat);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 15:02:55 +00:00
|
|
|
swe_houses(te, lat, lon, 'P', cusps, ascmc);
|
|
|
|
|
|
|
|
for (p = 1; p < 13; p++) {
|
|
|
|
printf("House %2d..: %2.0f (%f)\n", p, ceilf(cusps[p] / 30.0), cusps[p]);
|
|
|
|
}
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 12:50:48 +00:00
|
|
|
get_moon_phase(year, month, day, hour, min, sec);
|
2013-07-14 16:13:41 +00:00
|
|
|
printf("Asc.......: %.0f\n", ceilf(ascmc[0] / 30.0));
|
|
|
|
printf("MC........: %.0f\n", ceilf(ascmc[1] / 30.0));
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-14 16:13:41 +00:00
|
|
|
pos = get_planet_position(SE_SUN, te);
|
|
|
|
printf("Sun.......: %2.0f (%f)\n", ceilf(pos / 30.0), pos);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-14 16:13:41 +00:00
|
|
|
pos = get_planet_position(SE_MOON, te);
|
|
|
|
printf("Moon......: %2.0f (%f)\n", ceilf(pos / 30.0), pos);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-14 16:13:41 +00:00
|
|
|
pos = get_planet_position(SE_MERCURY, te);
|
|
|
|
printf("Mercury...: %2.0f (%f)\n", ceilf(pos / 30.0), pos);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-14 16:13:41 +00:00
|
|
|
pos = get_planet_position(SE_VENUS, te);
|
|
|
|
printf("Venus.....: %2.0f (%f)\n", ceilf(pos / 30.0), pos);
|
|
|
|
|
|
|
|
pos = get_planet_position(SE_MARS, te);
|
|
|
|
printf("Mars......: %2.0f (%f)\n", ceilf(pos / 30.0), pos);
|
|
|
|
|
|
|
|
pos = get_planet_position(SE_JUPITER, te);
|
|
|
|
printf("Jupiter...: %2.0f (%f)\n", ceilf(pos / 30.0), pos);
|
|
|
|
|
|
|
|
pos = get_planet_position(SE_SATURN, te);
|
|
|
|
printf("Saturn....: %2.0f (%f)\n", ceilf(pos / 30.0), pos);
|
|
|
|
|
|
|
|
pos = get_planet_position(SE_URANUS, te);
|
|
|
|
printf("Uranus....: %2.0f (%f)\n", ceilf(pos / 30.0), pos);
|
|
|
|
|
|
|
|
pos = get_planet_position(SE_NEPTUNE, te);
|
|
|
|
printf("Neptune...: %2.0f (%f)\n", ceilf(pos / 30.0), pos);
|
|
|
|
|
|
|
|
pos = get_planet_position(SE_PLUTO, te);
|
|
|
|
printf("Pluto.....: %2.0f (%f)\n", ceilf(pos / 30.0), pos);
|
|
|
|
|
|
|
|
pos = get_planet_position(SE_CHIRON, te);
|
|
|
|
printf("Chiron....: %2.0f (%f)\n", ceilf(pos / 30.0), pos);
|
|
|
|
|
|
|
|
pos = get_planet_position(SE_MEAN_NODE, te);
|
|
|
|
printf("North Node: %2.0f (%f)\n", ceilf(pos / 30.0), pos);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
return OK;
|
2013-07-14 12:40:26 +00:00
|
|
|
}
|
|
|
|
|
2013-07-23 11:47:53 +00:00
|
|
|
/*
|
2013-07-14 12:40:26 +00:00
|
|
|
static gboolean
|
|
|
|
draw_clock (ClutterCanvas *canvas, cairo_t *cr, int width, int height)
|
|
|
|
{
|
2013-07-26 14:46:08 +00:00
|
|
|
GDateTime *now;
|
|
|
|
float hours, minutes, seconds;
|
|
|
|
ClutterColor color;
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
int smaller = (width < height) ? width : height;
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
// get the current time and compute the angles
|
|
|
|
now = g_date_time_new_now_local();
|
|
|
|
seconds = g_date_time_get_second(now) * G_PI / 30;
|
|
|
|
minutes = g_date_time_get_minute(now) * G_PI / 30;
|
|
|
|
hours = g_date_time_get_hour(now) * G_PI / 6;
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
cairo_save(cr);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
// clear the contents of the canvas, to avoid painting over the previous frame
|
|
|
|
cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
|
|
|
|
cairo_paint(cr);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
cairo_restore(cr);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
// scale the modelview to the size of the surface
|
|
|
|
cairo_scale(cr, smaller, smaller);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
|
|
|
|
cairo_set_line_width(cr, 0.01);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
// the black rail that holds the seconds indicator
|
|
|
|
clutter_cairo_set_source_color(cr, CLUTTER_COLOR_Black);
|
|
|
|
cairo_translate(cr, 0.5, 0.5);
|
|
|
|
cairo_arc(cr, 0, 0, 0.4, 0, G_PI * 2);
|
|
|
|
cairo_stroke(cr);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
// the seconds indicator
|
|
|
|
color = *CLUTTER_COLOR_White;
|
|
|
|
color.alpha = 128;
|
|
|
|
clutter_cairo_set_source_color(cr, &color);
|
|
|
|
cairo_move_to(cr, 0, 0);
|
|
|
|
cairo_arc(cr, sinf(seconds) * 0.4, - cosf(seconds) * 0.4, 0.02, 0, G_PI * 2);
|
|
|
|
cairo_fill(cr);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
// the minutes hand
|
|
|
|
color = *CLUTTER_COLOR_DarkChameleon;
|
|
|
|
color.alpha = 196;
|
|
|
|
clutter_cairo_set_source_color(cr, &color);
|
|
|
|
cairo_move_to(cr, 0, 0);
|
|
|
|
cairo_line_to(cr, sinf(minutes) * 0.4, - cosf(minutes) * 0.4);
|
|
|
|
cairo_stroke(cr);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
// the hours hand
|
|
|
|
cairo_move_to(cr, 0, 0);
|
|
|
|
cairo_line_to(cr, sinf(hours) * 0.2, - cosf(hours) * 0.2);
|
|
|
|
cairo_stroke(cr);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
g_date_time_unref(now);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
// we're done drawing
|
|
|
|
return TRUE;
|
2013-07-14 12:40:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static guint idle_resize_id;
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
idle_resize(gpointer data)
|
|
|
|
{
|
2013-07-26 14:46:08 +00:00
|
|
|
ClutterActor *actor = data;
|
|
|
|
float width, height;
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
// match the canvas size to the actor's
|
|
|
|
clutter_actor_get_size(actor, &width, &height);
|
|
|
|
clutter_canvas_set_size(CLUTTER_CANVAS(clutter_actor_get_content(actor)), ceilf(width), ceilf(height));
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
// unset the guard
|
|
|
|
idle_resize_id = 0;
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
// remove the timeout
|
|
|
|
return G_SOURCE_REMOVE;
|
2013-07-14 12:40:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_actor_resize(ClutterActor *actor, const ClutterActorBox *allocation, ClutterAllocationFlags flags, gpointer user_data)
|
|
|
|
{
|
2013-07-26 14:46:08 +00:00
|
|
|
// throttle multiple actor allocations to one canvas resize; we use a guard variable to avoid queueing multiple resize operations
|
|
|
|
if (idle_resize_id == 0) {
|
|
|
|
idle_resize_id = clutter_threads_add_timeout(1000, idle_resize, actor);
|
|
|
|
}
|
2013-07-14 12:40:26 +00:00
|
|
|
}
|
|
|
|
|
2013-07-08 23:32:34 +00:00
|
|
|
int
|
2013-07-14 16:13:41 +00:00
|
|
|
gradix_clutter_main(int argc, char *argv[])
|
2013-07-08 23:32:34 +00:00
|
|
|
{
|
2013-07-26 14:46:08 +00:00
|
|
|
ClutterActor *stage,
|
|
|
|
*sign_aries,
|
|
|
|
*sign_taurus,
|
|
|
|
*sign_gemini,
|
|
|
|
*sign_cancer,
|
|
|
|
*sign_leo,
|
|
|
|
*sign_virgo,
|
|
|
|
*sign_libra,
|
|
|
|
*sign_scorpio,
|
|
|
|
*sign_saggitarius,
|
|
|
|
*sign_capricorn,
|
|
|
|
*sign_aquarius,
|
|
|
|
*sign_pisces,
|
|
|
|
*actor;
|
|
|
|
ClutterContent *canvas;
|
|
|
|
GError *err = NULL;
|
|
|
|
|
|
|
|
init_graphics();
|
|
|
|
|
|
|
|
// initialize Clutter
|
|
|
|
if (clutter_init(&argc, &argv) != CLUTTER_INIT_SUCCESS) {
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
// create a resizable stage
|
|
|
|
stage = clutter_stage_new();
|
|
|
|
clutter_stage_set_title(CLUTTER_STAGE (stage), "GRadix");
|
|
|
|
clutter_stage_set_user_resizable(CLUTTER_STAGE (stage), TRUE);
|
|
|
|
clutter_actor_set_background_color(stage, CLUTTER_COLOR_LightSkyBlue);
|
|
|
|
clutter_actor_set_size(stage, 300, 300);
|
|
|
|
clutter_actor_show(stage);
|
|
|
|
|
|
|
|
g_clear_error(&err);
|
|
|
|
if ((sign_aries = clutter_texture_new_from_file(IMAGEDIR "/sign_aries.svg", &err)) == NULL) {
|
|
|
|
printf("%s\n", err->message);
|
|
|
|
} else {
|
|
|
|
clutter_actor_add_child(stage, sign_aries);
|
|
|
|
}
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
g_clear_error(&err);
|
|
|
|
if ((sign_taurus = clutter_texture_new_from_file(IMAGEDIR "/sign_taurus.svg", &err)) == NULL) {
|
|
|
|
printf("%s\n", err->message);
|
|
|
|
} else {
|
|
|
|
clutter_actor_add_child(stage, sign_taurus);
|
|
|
|
}
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
g_clear_error(&err);
|
|
|
|
if ((sign_gemini = clutter_texture_new_from_file(IMAGEDIR "/sign_gemini.svg", &err)) == NULL) {
|
|
|
|
printf("%s\n", err->message);
|
|
|
|
} else {
|
|
|
|
clutter_actor_add_child(stage, sign_gemini);
|
|
|
|
}
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
g_clear_error(&err);
|
|
|
|
if ((sign_cancer = clutter_texture_new_from_file(IMAGEDIR "/sign_cancer.svg", &err)) == NULL) {
|
|
|
|
printf("%s\n", err->message);
|
|
|
|
} else {
|
|
|
|
clutter_actor_add_child(stage, sign_cancer);
|
|
|
|
}
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
g_clear_error(&err);
|
|
|
|
if ((sign_leo = clutter_texture_new_from_file(IMAGEDIR "/sign_leo.svg", &err)) == NULL) {
|
|
|
|
printf("%s\n", err->message);
|
|
|
|
} else {
|
|
|
|
clutter_actor_add_child(stage, sign_leo);
|
|
|
|
}
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
g_clear_error(&err);
|
|
|
|
if ((sign_virgo = clutter_texture_new_from_file(IMAGEDIR "/sign_virgo.svg", &err)) == NULL) {
|
|
|
|
printf("%s\n", err->message);
|
|
|
|
} else {
|
|
|
|
clutter_actor_add_child(stage, sign_virgo);
|
|
|
|
}
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
g_clear_error(&err);
|
|
|
|
if ((sign_libra = clutter_texture_new_from_file(IMAGEDIR "/sign_libra.svg", &err)) == NULL) {
|
|
|
|
printf("%s\n", err->message);
|
|
|
|
} else {
|
|
|
|
clutter_actor_add_child(stage, sign_libra);
|
|
|
|
}
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
g_clear_error(&err);
|
|
|
|
if ((sign_scorpio = clutter_texture_new_from_file(IMAGEDIR "/sign_scorpio.svg", &err)) == NULL) {
|
|
|
|
printf("%s\n", err->message);
|
|
|
|
} else {
|
|
|
|
clutter_actor_add_child(stage, sign_scorpio);
|
|
|
|
}
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
g_clear_error(&err);
|
|
|
|
if ((sign_saggitarius = clutter_texture_new_from_file(IMAGEDIR "/sign_saggitarius.svg", &err)) == NULL) {
|
|
|
|
printf("%s\n", err->message);
|
|
|
|
} else {
|
|
|
|
clutter_actor_add_child(stage, sign_saggitarius);
|
|
|
|
}
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
g_clear_error(&err);
|
|
|
|
if ((sign_capricorn = clutter_texture_new_from_file(IMAGEDIR "/sign_capricorn.svg", &err)) == NULL) {
|
|
|
|
printf("%s\n", err->message);
|
|
|
|
} else {
|
|
|
|
clutter_actor_add_child(stage, sign_capricorn);
|
|
|
|
}
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
g_clear_error(&err);
|
|
|
|
if ((sign_aquarius = clutter_texture_new_from_file(IMAGEDIR "/sign_aquarius.svg", &err)) == NULL) {
|
|
|
|
printf("%s\n", err->message);
|
|
|
|
} else {
|
|
|
|
clutter_actor_add_child(stage, sign_aquarius);
|
|
|
|
}
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
g_clear_error(&err);
|
|
|
|
if ((sign_pisces = clutter_texture_new_from_file(IMAGEDIR "/sign_pisces.svg", &err)) == NULL) {
|
|
|
|
printf("%s\n", err->message);
|
|
|
|
} else {
|
|
|
|
clutter_actor_add_child(stage, sign_pisces);
|
|
|
|
}
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
// our 2D canvas, courtesy of Cairo
|
|
|
|
//canvas = clutter_canvas_new();
|
|
|
|
//clutter_canvas_set_size(CLUTTER_CANVAS (canvas), 300, 300);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
//actor = clutter_actor_new();
|
|
|
|
//clutter_actor_set_content(actor, canvas);
|
|
|
|
//clutter_actor_set_content_scaling_filters(actor, CLUTTER_SCALING_FILTER_TRILINEAR, CLUTTER_SCALING_FILTER_LINEAR);
|
|
|
|
//clutter_actor_add_child(stage, actor);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
// the actor now owns the canvas
|
|
|
|
//g_object_unref(canvas);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
// bind the size of the actor to that of the stage
|
|
|
|
//clutter_actor_add_constraint(actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_SIZE, 0));
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
// resize the canvas whenever the actor changes size
|
|
|
|
//g_signal_connect(actor, "allocation-changed", G_CALLBACK(on_actor_resize), NULL);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
// quit on destroy
|
|
|
|
g_signal_connect(stage, "destroy", G_CALLBACK(clutter_main_quit), NULL);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
// connect our drawing code
|
|
|
|
//g_signal_connect(canvas, "draw", G_CALLBACK(draw_clock), NULL);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
// invalidate the canvas, so that we can draw before the main loop starts
|
|
|
|
//clutter_content_invalidate(canvas);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
// set up a timer that invalidates the canvas every second
|
|
|
|
//clutter_threads_add_timeout(1000, invalidate_clock, canvas);
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
clutter_main();
|
2013-07-14 12:40:26 +00:00
|
|
|
|
2013-07-26 14:46:08 +00:00
|
|
|
return EXIT_SUCCESS;
|
2013-07-08 23:32:34 +00:00
|
|
|
}
|
2013-07-23 11:47:53 +00:00
|
|
|
*/
|