diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/configuration.c | 77 | ||||
-rw-r--r-- | src/configuration.h | 14 | ||||
-rw-r--r-- | src/extString.c | 63 | ||||
-rw-r--r-- | src/extString.h | 3 | ||||
m--------- | src/iniparser | 0 | ||||
-rw-r--r-- | src/main.c | 192 | ||||
-rw-r--r-- | src/meson.build | 6 | ||||
-rw-r--r-- | src/sun.c | 65 | ||||
-rw-r--r-- | src/sun.h | 7 |
9 files changed, 339 insertions, 88 deletions
diff --git a/src/configuration.c b/src/configuration.c new file mode 100644 index 0000000..81a5bbb --- /dev/null +++ b/src/configuration.c @@ -0,0 +1,77 @@ +#include "configuration.h" + +#include "iniparser/src/iniparser.h" +#include "iniparser/src/dictionary.h" +#include "extString.h" +#include <string.h> +#include <glib.h> +#include <stdlib.h> +#include <unistd.h> + +dictionary * +load_config(void) +{ + char *xdg_config = getenv ("XDG_CONFIG_HOME"); + char *home = getenv ("HOME"); + if (home == NULL) + return NULL; + if (xdg_config == NULL) { + xdg_config = malloc (strlen(home)*sizeof(char)+strlen("/.config")*sizeof(char)+1); + sprintf (xdg_config, "%s/.config", home); + } + char *config_path = malloc(strlen(xdg_config)*sizeof(char)+strlen("/autodarkmode/config.ini")*sizeof(char)+1); + sprintf (config_path, "%s/autodarkmode/config.ini", xdg_config); + + free (xdg_config); + + if (access(config_path, F_OK) != 0) { + g_printerr ("Config file not found. Using default values.\n"); + free (config_path); + return NULL; + } + + g_print ("Loading config file %s\n", config_path); + + dictionary *dict = iniparser_load (config_path); + + free (config_path); + return dict; +} + +enum LocationType +config_get_location_type(dictionary *d) +{ + if (d == NULL) + return GCLUE; + + char *loctype = iniparser_getstring (d, "main:locationtype", "gclue"); + + if (strcmp(strlwr(loctype), "gclue") == 0) { + return GCLUE; + } else if (strcmp(strlwr(loctype), "manual") == 0) { + return MANUAL; + } else { + g_printerr("Invalid Location type %s. Defaulting to GeoClue\n", loctype); + return GCLUE; + } + return GCLUE; +} + +float +config_get_latitude (dictionary *d) +{ + if (d == NULL) + return 0; + + return iniparser_getdouble (d, "manual:latitude", 0); +} + +float +config_get_longitude (dictionary *d) +{ + if (d == NULL) + return 0; + + return iniparser_getdouble (d, "manual:longitude", 0); +} + diff --git a/src/configuration.h b/src/configuration.h new file mode 100644 index 0000000..ba1f393 --- /dev/null +++ b/src/configuration.h @@ -0,0 +1,14 @@ +#include "iniparser/src/iniparser.h" +#include "iniparser/src/dictionary.h" + +enum LocationType { + GCLUE, + MANUAL, +}; + +dictionary *load_config(void); + +enum LocationType config_get_location_type(dictionary *d); + +float config_get_latitude (dictionary *d); +float config_get_longitude (dictionary *d); diff --git a/src/extString.c b/src/extString.c new file mode 100644 index 0000000..6538dac --- /dev/null +++ b/src/extString.c @@ -0,0 +1,63 @@ +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +char *strlwr(char *s) +{ + unsigned char *p = (unsigned char *)s; + + while (*p) { + *p = tolower((unsigned char)*p); + p++; + } + + return s; +} + +char *trim(char *s) +{ + char *result = strdup(s); + char *end; + + while(isspace((unsigned char)*result)) result++; + + if(*result == 0) + return result; + + end = result + strlen(result) - 1; + while(end > result && isspace((unsigned char)*end)) end--; + + end[1] = '\0'; + + return result; +} + +char *replaceStr(char *s, char *old, char *replace) { + char* result; + int i, cnt = 0; + size_t newSize = strlen(replace); + size_t oldSize = strlen(old); + + for (i = 0; s[i] != '\0'; i++) { + if (strstr(&s[i], old) == &s[i]) { + cnt++; + i += oldSize - 1; + } + } + + result = (char*)malloc(i + cnt * (newSize - oldSize) + 1); + + i = 0; + while (*s) { + if (strstr(s, old) == s) { + strcpy(&result[i], replace); + i += newSize; + s += oldSize; + } + else + result[i++] = *s++; + } + + result[i] = '\0'; + return result; +}; diff --git a/src/extString.h b/src/extString.h new file mode 100644 index 0000000..66149f1 --- /dev/null +++ b/src/extString.h @@ -0,0 +1,3 @@ +char *strlwr(char *s); +char *trim(char *s); +char *replaceStr(char *s, char *old, char *replace); diff --git a/src/iniparser b/src/iniparser new file mode 160000 +Subproject 762715ca6cdba9dcf31a5af9297b444f3b5b8c0 @@ -18,106 +18,127 @@ */ #include "config.h" +#include "configuration.h" #include "sun.h" -#include<math.h> +#include <string.h> +#include <unistd.h> +#include <math.h> +#include <signal.h> #include <glib.h> #include <stdlib.h> #include <locale.h> #include <glib/gi18n.h> #include <geoclue.h> -static gint timeout = 30; /* seconds */ static GClueAccuracyLevel accuracy_level = GCLUE_ACCURACY_LEVEL_EXACT; -static gint time_threshold; + GClueSimple *simple = NULL; GClueClient *client = NULL; GMainLoop *main_loop; -static gboolean -on_location_timeout (gpointer user_data) -{ - g_clear_object (&client); - g_clear_object (&simple); - g_main_loop_quit (main_loop); - - return FALSE; -} +enum LocationType loctype = 0; +dictionary *dict = NULL; +bool quit = false; +float lat = 0; +float lng = 0; static void -print_location (GClueSimple *simple) +get_gclue_location (GClueSimple *simple) { GClueLocation *location; - - GDateTime *current_time = g_date_time_new_now_local(); - location = gclue_simple_get_location (simple); - g_print ("\nNew location:\n"); - g_print ("Latitude: %f°\nLongitude: %f°\nAccuracy: %f meters\n", - gclue_location_get_latitude (location), - gclue_location_get_longitude (location), - gclue_location_get_accuracy (location)); - - int year, month, day; - g_date_time_get_ymd (current_time, &year, &month, &day); - g_print ("%d - %d - %d\n", year, month, day); - - int utc_offset = g_date_time_get_utc_offset (current_time)*2.7778*pow(10.0, -10.0); + lat = gclue_location_get_latitude (location); + lng = gclue_location_get_longitude (location); - float localT = calculateSun(year, month, day, gclue_location_get_latitude (location), gclue_location_get_longitude (location), utc_offset, 0); - double hours; - float minutes = modf(localT,&hours)*60; - g_print("Sunrise: %.0f:%.0f\n",hours,minutes); - - float sunsetT = calculateSun(year, month, day, gclue_location_get_latitude (location), gclue_location_get_longitude (location), utc_offset, 1); - double sunHours; - float sunMinutes = modf(sunsetT,&sunHours)*60; - g_print("Sunset: %.0f:%.0f\n",sunHours,sunMinutes); - - g_free (current_time); + return; } -static void -on_client_active_notify (GClueClient *client, - GParamSpec *pspec, - gpointer user_data) +void +on_dark (void) { - if (gclue_client_get_active (client)) - return; + g_print ("on dark"); + char *home = getenv ("HOME"); + char *darklock; + if (home != NULL) { + darklock = malloc(strlen(home)*sizeof(char)+strlen("/.cache/darkmode")*sizeof(char)+1); + sprintf (darklock, "%s/.cache/darkmode", home); + if (access(darklock, F_OK) == 0) { + free (darklock); + return; + } + } - g_print ("Geolocation disabled. Quitting..\n"); - on_location_timeout (NULL); + const char *dark_command = iniparser_getstring (dict, "dark:cmd", ""); + if (sizeof (dark_command) == sizeof ("")) { + g_printerr ("No command for dark mode specified!"); + return; + } + int rtrn = system (dark_command); + if (rtrn != 0) { + g_printerr("Dark command failed with non-zero exit code!"); + free (darklock); + return; + } + FILE *dark = fopen (darklock, "w"); + fclose (dark); } -static void -on_simple_ready (GObject *source_object, - GAsyncResult *res, - gpointer user_data) +void +on_light (void) { - GError *error = NULL; + g_print ("on light\n"); + char *home = getenv ("HOME"); + char *darklock; + if (home != NULL) { + darklock = malloc(strlen(home)*sizeof(char)+strlen("/.cache/darkmode")*sizeof(char)+1); + sprintf (darklock, "%s/.cache/darkmode", home); + if (access(darklock, F_OK) != 0) { + free (darklock); + return; + } - simple = gclue_simple_new_with_thresholds_finish (res, &error); - if (error != NULL) { - g_critical ("Failed to connect to GeoClue2 service: %s", error->message); - exit (-1); } - client = gclue_simple_get_client (simple); - if (client) { - g_object_ref (client); - g_print ("Client object: %s\n", - g_dbus_proxy_get_object_path (G_DBUS_PROXY (client))); - - g_signal_connect (client, - "notify::active", - G_CALLBACK (on_client_active_notify), - NULL); + + const char *light_command = iniparser_getstring (dict, "light:cmd", ""); + if (sizeof (light_command) == sizeof ("")) { + g_printerr ("No command for light mode specified!"); + return; + } + int rtrn = system (light_command); + if (rtrn != 0) { + g_printerr("Light command failed with non-zero exit code!"); + free (darklock); + return; } - print_location (simple); - g_signal_connect (simple, - "notify::location", - G_CALLBACK (print_location), - NULL); + remove (darklock); + free (darklock); +} + +void +loop (void) +{ + float sunrise = getSunrise (lat, lng); + double hours; + float minutes = modf (sunrise, &hours)*60; + g_print ("Sunrise: %.0f:%.0f\n", hours, minutes); + + float sunset = getSunset (lat, lng); + minutes = modf (sunset, &hours)*60; + g_print ("Sunset: %.0f:%.0f\n", hours, minutes); + + if (isDark (sunrise, sunset)) + on_dark (); + else + on_light (); +} + +void +handleExit(int sig) { + quit = true; + signal(sig, SIG_IGN); + return; } gint @@ -147,18 +168,29 @@ main (gint argc, return EXIT_SUCCESS; } - g_timeout_add_seconds (timeout, on_location_timeout, NULL); + dict = load_config (); + loctype = config_get_location_type (dict); + g_print("%d\n", loctype); + + if (loctype == MANUAL) { + lat = config_get_latitude (dict); + lng = config_get_longitude (dict); + } else { + get_gclue_location (gclue_simple_new_sync ("autodarkmode", + accuracy_level, + NULL, + NULL)); + g_print ("lat: %f\n", lat); + g_print ("lng: %f\n", lng); + } - gclue_simple_new_with_thresholds ("autodarkmode", - accuracy_level, - time_threshold, - 0, - NULL, - on_simple_ready, - NULL); + signal(SIGINT, handleExit); + while (!quit) { + loop(); + sleep (60); + } - main_loop = g_main_loop_new (NULL, FALSE); - g_main_loop_run (main_loop); + iniparser_freedict (dict); return EXIT_SUCCESS; } diff --git a/src/meson.build b/src/meson.build index 7668291..6642e9d 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,6 +1,10 @@ autodarkmode_sources = [ 'main.c', - 'sun.c' + 'sun.c', + 'extString.c', + 'configuration.c', + 'iniparser/src/dictionary.c', + 'iniparser/src/iniparser.c', ] autodarkmode_deps = [ @@ -1,5 +1,6 @@ #include <math.h> #include <glib.h> +#include <stdbool.h> #include "sun.h" #define ZENITH -.83 @@ -14,10 +15,7 @@ float to_deg (float n) { // http://edwilliams.org/sunrise_sunset_algorithm.htm // if the sunset is desired, set sunset to >= 1 // returns -1 if the sun never rises/sets in the specified location -float calculateSun(int year, int month, int day, float lat, float lng, int localOffset, int sunset) { - - if (sunset > 1) - sunset = 1; +float calculateSun(int year, int month, int day, float lat, float lng, int localOffset, bool sunset) { float N1 = floor(275 * month / 9); float N2 = floor((month + 9) / 12); @@ -26,7 +24,7 @@ float calculateSun(int year, int month, int day, float lat, float lng, int local float lngHour = lng / 15.0; - float t = N + ((sunset == 0 ? 6 : 18 - lngHour) / 24); + float t = N + ((!sunset ? 6 : 18 - lngHour) / 24); float M = (0.9856 * t) - 3.289; @@ -49,7 +47,7 @@ float calculateSun(int year, int month, int day, float lat, float lng, int local else if (cosH < -1) return -1; - float H = sunset == 0 ? (360 - to_deg(acos(cosH))) : to_deg(acos(cosH)); + float H = !sunset ? (360 - to_deg(acos(cosH))) : to_deg(acos(cosH)); H = H / 15; float T = H + RA - (0.06571 * t) - 6.622; @@ -63,3 +61,58 @@ float calculateSun(int year, int month, int day, float lat, float lng, int local return UT + localOffset; } + +float getSunrise(float lat, float lang) { + int year, month, day; + GDateTime *current_time = g_date_time_new_now_local(); + g_date_time_get_ymd (current_time, &year, &month, &day); + + int utc_offset = g_date_time_get_utc_offset (current_time)*2.7778*pow(10.0, -10.0); + + free (current_time); + return calculateSun (year, month, day, lat, lang, utc_offset, false); +} + +float getSunset(float lat, float lang) { + int year, month, day; + GDateTime *current_time = g_date_time_new_now_local(); + g_date_time_get_ymd (current_time, &year, &month, &day); + + int utc_offset = g_date_time_get_utc_offset (current_time)*2.7778*pow(10.0, -10.0); + + free (current_time); + return calculateSun (year, month, day, lat, lang, utc_offset, true); +} + +bool isDark(float sunrise, float sunset) { + GDateTime *current_time = g_date_time_new_now_local(); + + double rise_hours; + float rise_minutes = modf (sunrise, &rise_hours)*60; + double set_hours; + float set_minutes = modf (sunset, &set_hours)*60; + + GDateTime *rise_time = g_date_time_new_local (g_date_time_get_year (current_time), + g_date_time_get_month (current_time), + g_date_time_get_day_of_month (current_time), + rise_hours, + rise_minutes, + 0); + GDateTime *set_time = g_date_time_new_local (g_date_time_get_year (current_time), + g_date_time_get_month (current_time), + g_date_time_get_day_of_month (current_time), + set_hours, + set_minutes, + 0); + + if (g_date_time_compare (current_time, rise_time) == 1 && g_date_time_compare (current_time, set_time) == -1) { + free (rise_time); + free (set_time); + free (current_time); + return false; + } + free (rise_time); + free (set_time); + free (current_time); + return true; +} @@ -1,5 +1,10 @@ +#include <stdbool.h> float to_rad (float n); float to_deg (float n); -float calculateSun(int year,int month,int day,float lat, float lng,int localOffset, int sunset); +float calculateSun(int year,int month,int day,float lat, float lng,int localOffset, bool sunset); +float getSunrise(float lat, float lang); +float getSunset(float lat, float lang); + +bool isDark (float sunrise, float sunset); |