aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJon Lund Steffensen <jonlst@gmail.com>2010-05-25 00:45:29 +0200
committerJon Lund Steffensen <jonlst@gmail.com>2010-05-25 00:45:29 +0200
commitcde909747c1a237f5a1495a92ff3ba7675c64c99 (patch)
tree4122364a96340e252882b987412c9fd8ca61f992 /src
parentUse the prefix 'gamma' for gamma adjustment source files. (diff)
downloadredshift-ng-cde909747c1a237f5a1495a92ff3ba7675c64c99.tar.gz
redshift-ng-cde909747c1a237f5a1495a92ff3ba7675c64c99.tar.bz2
redshift-ng-cde909747c1a237f5a1495a92ff3ba7675c64c99.tar.xz
Provide fundament for more advanced location providers.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am3
-rw-r--r--src/location-manual.c93
-rw-r--r--src/location-manual.h36
-rw-r--r--src/redshift.c142
-rw-r--r--src/redshift.h15
5 files changed, 266 insertions, 23 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 75a5261..e4f88de 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,7 +12,8 @@ redshift_SOURCES = \
redshift.c \
colorramp.c colorramp.h \
solar.c solar.h \
- systemtime.c systemtime.h
+ systemtime.c systemtime.h \
+ location-manual.c location-manual.h
EXTRA_redshift_SOURCES = \
gamma-randr.c gamma-randr.h \
diff --git a/src/location-manual.c b/src/location-manual.c
new file mode 100644
index 0000000..1eca22e
--- /dev/null
+++ b/src/location-manual.c
@@ -0,0 +1,93 @@
+/* location-manual.c -- Manual location provider source
+ This file is part of Redshift.
+
+ Redshift 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.
+
+ Redshift 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 Redshift. If not, see <http://www.gnu.org/licenses/>.
+
+ Copyright (c) 2010 Jon Lund Steffensen <jonlst@gmail.com>
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include <errno.h>
+
+#include "location-manual.h"
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# define _(s) gettext(s)
+#else
+# define _(s) s
+#endif
+
+
+int
+location_manual_init(location_manual_state_t *state, char *args)
+{
+ state->lat = NAN;
+ state->lon = NAN;
+
+ /* Parse arguments. */
+ int count = 0;
+ while (args != NULL) {
+ if (count > 1) {
+ fputs(_("Too many arguments.\n"), stderr);
+ return -1;
+ }
+
+ char *next_arg = strchr(args, ':');
+ if (next_arg != NULL) *(next_arg++) = '\0';
+
+ /* Parse float value */
+ char *end;
+ errno = 0;
+ float value = strtof(args, &end);
+ if (errno != 0 || *end != '\0') {
+ fputs(_("Malformed argument.\n"), stderr);
+ return -1;
+ }
+
+ switch (count) {
+ case 0: state->lat = value; break;
+ case 1: state->lon = value; break;
+ }
+
+ args = next_arg;
+ count += 1;
+ }
+
+ /* Latitude and longitude must be set */
+ if (isnan(state->lat) || isnan(state->lon)) {
+ fputs(_("Latitude and longitude must be set.\n"), stderr);
+ exit(EXIT_FAILURE);
+ }
+
+ return 0;
+}
+
+void
+location_manual_free(location_manual_state_t *state)
+{
+}
+
+int
+location_manual_get_location(location_manual_state_t *state, float *lat,
+ float *lon)
+{
+ *lat = state->lat;
+ *lon = state->lon;
+
+ return 0;
+}
diff --git a/src/location-manual.h b/src/location-manual.h
new file mode 100644
index 0000000..372cf33
--- /dev/null
+++ b/src/location-manual.h
@@ -0,0 +1,36 @@
+/* location-manual.h -- Manual location provider header
+ This file is part of Redshift.
+
+ Redshift 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.
+
+ Redshift 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 Redshift. If not, see <http://www.gnu.org/licenses/>.
+
+ Copyright (c) 2010 Jon Lund Steffensen <jonlst@gmail.com>
+*/
+
+#ifndef _REDSHIFT_LOCATION_MANUAL_H
+#define _REDSHIFT_LOCATION_MANUAL_H
+
+
+typedef struct {
+ float lat;
+ float lon;
+} location_manual_state_t;
+
+
+int location_manual_init(location_manual_state_t *state, char *args);
+void location_manual_free(location_manual_state_t *state);
+int location_manual_get_location(location_manual_state_t *state, float *lat,
+ float *lon);
+
+
+#endif /* ! _REDSHIFT_LOCATION_MANUAL_H */
diff --git a/src/redshift.c b/src/redshift.c
index 1364527..f297c3a 100644
--- a/src/redshift.c
+++ b/src/redshift.c
@@ -28,6 +28,7 @@
#include <time.h>
#include <math.h>
#include <locale.h>
+#include <errno.h>
#ifdef HAVE_SYS_SIGNAL_H
# include <sys/signal.h>
@@ -67,6 +68,9 @@
#endif
+#include "location-manual.h"
+
+
/* Union of state data for gamma adjustment methods */
typedef union {
#ifdef ENABLE_RANDR
@@ -114,6 +118,24 @@ static const gamma_method_t gamma_methods[] = {
};
+/* Union of state data for location providers */
+typedef union {
+ location_manual_state_t manual;
+} location_state_t;
+
+
+/* Location provider method structs */
+static const location_provider_t location_providers[] = {
+ {
+ "Manual",
+ (location_provider_init_func *)location_manual_init,
+ (location_provider_free_func *)location_manual_free,
+ (location_provider_get_location_func *)
+ location_manual_get_location
+ },
+ { NULL, NULL, NULL, NULL }
+};
+
/* Bounds for parameters. */
#define MIN_LAT -90.0
#define MAX_LAT 90.0
@@ -218,6 +240,9 @@ print_help(const char *program_name)
no-wrap */
fputs(_(" -g R:G:B\tAdditional gamma correction to apply\n"
" -l LAT:LON\tYour current location\n"
+ " -l PROVIDER\tSelect provider for automatic"
+ " location updates\n"
+ " \t\t(Type `list' to see available providers)\n"
" -m METHOD\tMethod to use to set color temperature\n"
" \t\t(Type `list' to see available methods)\n"
" -o\t\tOne shot mode (do not continously adjust"
@@ -250,6 +275,15 @@ print_method_list()
}
}
+static void
+print_provider_list()
+{
+ fputs(_("Available location providers:\n"), stdout);
+ for (int i = 0; location_providers[i].name != NULL; i++) {
+ printf(" %s\n", location_providers[i].name);
+ }
+}
+
int
main(int argc, char *argv[])
@@ -267,8 +301,6 @@ main(int argc, char *argv[])
#endif
/* Initialize to defaults */
- float lat = NAN;
- float lon = NAN;
int temp_day = DEFAULT_DAY_TEMP;
int temp_night = DEFAULT_NIGHT_TEMP;
float gamma[3] = { DEFAULT_GAMMA, DEFAULT_GAMMA, DEFAULT_GAMMA };
@@ -276,6 +308,9 @@ main(int argc, char *argv[])
const gamma_method_t *method = NULL;
char *method_args = NULL;
+ const location_provider_t *provider = NULL;
+ char *provider_args = NULL;
+
int transition = 1;
int one_shot = 0;
int verbose = 0;
@@ -315,17 +350,47 @@ main(int argc, char *argv[])
exit(EXIT_SUCCESS);
break;
case 'l':
- s = strchr(optarg, ':');
- if (s == NULL) {
- fputs(_("Malformed location argument.\n"),
- stderr);
- fputs(_("Try `-h' for more information.\n"),
- stderr);
+ /* Print list of providers if argument is `list' */
+ if (strcasecmp(optarg, "list") == 0) {
+ print_provider_list();
+ exit(EXIT_SUCCESS);
+ }
+
+ char *provider_name = NULL;
+
+ /* Try to parse provider name as float */
+ errno = 0;
+ char *end;
+ float lat = strtof(optarg, &end);
+ if (errno == 0 && *end == ':') {
+ provider_name = "Manual";
+ provider_args = optarg;
+ } else {
+ /* Split off provider arguments. */
+ s = strchr(optarg, ':');
+ if (s != NULL) {
+ *(s++) = '\0';
+ provider_args = s;
+ }
+
+ provider_name = optarg;
+ }
+
+ /* Lookup argument in location provider table */
+ for (int i = 0; location_providers[i].name != NULL;
+ i++) {
+ const location_provider_t *p =
+ &location_providers[i];
+ if (strcasecmp(provider_name, p->name) == 0) {
+ provider = p;
+ }
+ }
+
+ if (provider == NULL) {
+ fprintf(stderr, _("Unknown location provider"
+ " `%s'.\n"), provider_name);
exit(EXIT_FAILURE);
}
- *(s++) = '\0';
- lat = atof(optarg);
- lon = atof(s);
break;
case 'm':
/* Print list of methods if argument is `list' */
@@ -334,13 +399,6 @@ main(int argc, char *argv[])
exit(EXIT_SUCCESS);
}
- /* Split off method arguments. */
- s = strchr(optarg, ':');
- if (s != NULL) {
- *(s++) = '\0';
- method_args = s;
- }
-
/* Lookup argument in gamma methods table */
for (int i = 0; gamma_methods[i].name != NULL; i++) {
const gamma_method_t *m =
@@ -387,13 +445,53 @@ main(int argc, char *argv[])
}
}
- /* Latitude and longitude must be set */
- if (isnan(lat) || isnan(lon)) {
- fputs(_("Latitude and longitude must be set.\n"), stderr);
- fputs(_("Try `-h' for more information.\n"), stderr);
+ /* Initialize location provider. If provider is NULL
+ try all providers until one that works is found. */
+ location_state_t location_state;
+
+ if (provider != NULL) {
+ /* Use provider specified on command line. */
+ r = provider->init(&location_state, provider_args);
+ if (r < 0) {
+ fprintf(stderr, _("Initialization of %s failed.\n"),
+ provider->name);
+ exit(EXIT_FAILURE);
+ }
+ } else {
+ /* Try all providers, use the first that works. */
+ for (int i = 0; location_providers[i].name != NULL; i++) {
+ const location_provider_t *p = &location_providers[i];
+ r = p->init(&location_state, provider_args);
+ if (r < 0) {
+ fprintf(stderr, _("Initialization of %s"
+ " failed.\n"), p->name);
+ fputs(_("Trying other provider...\n"), stderr);
+ } else {
+ provider = p;
+ break;
+ }
+ }
+
+ /* Failure if no providers were successful at this point. */
+ if (provider == NULL) {
+ fputs(_("No more location providers to try.\n"),
+ stderr);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ float lat = NAN;
+ float lon = NAN;
+
+ /* Get current location. */
+ r = provider->get_location(&location_state, &lat, &lon);
+ if (r < 0) {
+ fputs(_("Unable to get location from provider.\n"), stderr);
exit(EXIT_FAILURE);
}
+ provider->free(&location_state);
+
if (verbose) {
/* TRANSLATORS: Append degree symbols if possible. */
printf(_("Location: %f, %f\n"), lat, lon);
diff --git a/src/redshift.h b/src/redshift.h
index 38e7f6b..1cb73f6 100644
--- a/src/redshift.h
+++ b/src/redshift.h
@@ -21,6 +21,7 @@
#define _REDSHIFT_REDSHIFT_H
+/* Gamma adjustment method */
typedef int gamma_method_init_func(void *state, char *args);
typedef void gamma_method_free_func(void *state);
typedef void gamma_method_restore_func(void *state);
@@ -36,4 +37,18 @@ typedef struct {
} gamma_method_t;
+/* Location provider */
+typedef int location_provider_init_func(void *state, char *args);
+typedef void location_provider_free_func(void *state);
+typedef int location_provider_get_location_func(void *state, float *lat,
+ float *lon);
+
+typedef struct {
+ char *name;
+ location_provider_init_func *init;
+ location_provider_free_func *free;
+ location_provider_get_location_func *get_location;
+} location_provider_t;
+
+
#endif /* ! _REDSHIFT_REDSHIFT_H */