Add support for manual sunset/sunrise

The new -S/-s/-d flags allow for manually specifying the time of sunset,
ssunrise in the format of HH:MM, and the transitional animation duration
in seconds, respectively.

This is implemented by sidestepping the calc_sun call in manual mode.
The rest of wlsunset operates as usual.
master
Kenny Levinsen 2021-01-29 17:32:51 +01:00
parent 93d7d01bad
commit 111181106e
2 changed files with 92 additions and 24 deletions

105
main.c
View File

@ -88,7 +88,10 @@ struct config {
double longitude; double longitude;
double latitude; double latitude;
int duration; bool manual_time;
time_t sunrise;
time_t sunset;
time_t duration;
}; };
enum state { enum state {
@ -167,10 +170,22 @@ static void recalc_stops(struct context *ctx, time_t now) {
time_t last_day = ctx->calc_day; time_t last_day = ctx->calc_day;
ctx->calc_day = day; ctx->calc_day = day;
enum sun_condition cond = NORMAL;
if (ctx->config.manual_time) {
ctx->state = STATE_NORMAL;
ctx->sun.dawn = ctx->config.sunrise - ctx->config.duration + day;
ctx->sun.sunrise = ctx->config.sunrise + day;
ctx->sun.sunset = ctx->config.sunset + day;
ctx->sun.dusk = ctx->config.sunset + ctx->config.duration + day;
goto done;
}
struct sun sun; struct sun sun;
struct tm tm = { 0 }; struct tm tm = { 0 };
gmtime_r(&day, &tm); gmtime_r(&day, &tm);
enum sun_condition cond = calc_sun(&tm, ctx->config.latitude, &sun); cond = calc_sun(&tm, ctx->config.latitude, &sun);
switch (cond) { switch (cond) {
case NORMAL: case NORMAL:
@ -211,6 +226,8 @@ static void recalc_stops(struct context *ctx, time_t now) {
default: default:
abort(); abort();
} }
done:
ctx->condition = cond; ctx->condition = cond;
int temp_diff = ctx->config.high_temp - ctx->config.low_temp; int temp_diff = ctx->config.high_temp - ctx->config.low_temp;
@ -614,16 +631,18 @@ static int setup_timer(struct context *ctx) {
} }
static int wlrun(struct config cfg) { static int wlrun(struct config cfg) {
init_time();
// Initialize defaults // Initialize defaults
struct context ctx = { struct context ctx = {
.sun = { 0 }, .sun = { 0 },
.condition = SUN_CONDITION_LAST, .condition = SUN_CONDITION_LAST,
.longitude_time_offset = longitude_time_offset(cfg.longitude),
.state = STATE_INITIAL, .state = STATE_INITIAL,
.config = cfg, .config = cfg,
}; };
if (!cfg.manual_time) {
ctx.longitude_time_offset = longitude_time_offset(cfg.longitude);
}
wl_list_init(&ctx.outputs); wl_list_init(&ctx.outputs);
if (setup_timer(&ctx) == -1) { if (setup_timer(&ctx) == -1) {
@ -682,29 +701,43 @@ static int wlrun(struct config cfg) {
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
static int parse_time_of_day(const char *s, time_t *time) {
struct tm tm = { 0 };
if (strptime(s, "%H:%M", &tm) == NULL) {
return -1;
}
*time = tm.tm_hour * 3600 + tm.tm_min * 60 + timezone;
return 0;
}
static const char usage[] = "usage: %s [options]\n" static const char usage[] = "usage: %s [options]\n"
" -h show this help message\n" " -h show this help message\n"
" -t <temp> set low temperature (default: 4000)\n" " -t <temp> set low temperature (default: 4000)\n"
" -T <temp> set high temperature (default: 6500)\n" " -T <temp> set high temperature (default: 6500)\n"
" -l <lat> set latitude (e.g. 39.9)\n" " -l <lat> set latitude (e.g. 39.9)\n"
" -L <long> set longitude (e.g. 116.3)\n" " -L <long> set longitude (e.g. 116.3)\n"
" -g <gamma> set gamma (default: 1.0)\n"; " -S <sunrise> set manual sunrise (e.g. 06:30)\n"
" -s <sunset> set manual sunset (e.g. 18:30)\n"
" -d <duration> set manual duration in seconds (e.g. 1800)\n"
" -g <gamma> set gamma (default: 1.0)\n";
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
#ifdef SPEEDRUN #ifdef SPEEDRUN
fprintf(stderr, "warning: speedrun mode enabled\n"); fprintf(stderr, "warning: speedrun mode enabled\n");
#endif #endif
init_time();
struct config config = { struct config config = {
.latitude = 0, .latitude = NAN,
.longitude = 0, .longitude = NAN,
.high_temp = 6500, .high_temp = 6500,
.low_temp = 4000, .low_temp = 4000,
.gamma = 1.0, .gamma = 1.0,
}; };
int opt; int opt;
while ((opt = getopt(argc, argv, "ht:T:l:L:d:g:")) != -1) { while ((opt = getopt(argc, argv, "ht:T:l:L:S:s:d:g:")) != -1) {
switch (opt) { switch (opt) {
case 't': case 't':
config.low_temp = strtol(optarg, NULL, 10); config.low_temp = strtol(optarg, NULL, 10);
@ -718,6 +751,23 @@ int main(int argc, char *argv[]) {
case 'L': case 'L':
config.longitude = strtod(optarg, NULL); config.longitude = strtod(optarg, NULL);
break; break;
case 'S':
if (parse_time_of_day(optarg, &config.sunrise) != 0) {
fprintf(stderr, "invalid time, expected HH:MM, got %s\n", optarg);
return EXIT_FAILURE;
}
config.manual_time = true;
break;
case 's':
if (parse_time_of_day(optarg, &config.sunset) != 0) {
fprintf(stderr, "invalid time, expected HH:MM, got %s\n", optarg);
return EXIT_FAILURE;
}
config.manual_time = true;
break;
case 'd':
config.duration = strtol(optarg, NULL, 10);
break;
case 'g': case 'g':
config.gamma = strtod(optarg, NULL); config.gamma = strtod(optarg, NULL);
break; break;
@ -731,20 +781,27 @@ int main(int argc, char *argv[]) {
if (config.high_temp <= config.low_temp) { if (config.high_temp <= config.low_temp) {
fprintf(stderr, "high temp (%d) must be higher than low (%d) temp\n", fprintf(stderr, "high temp (%d) must be higher than low (%d) temp\n",
config.high_temp, config.low_temp); config.high_temp, config.low_temp);
return -1;
}
if (config.latitude > 90.0 || config.latitude < -90.0) {
fprintf(stderr, "latitude (%lf) must be in interval [-90,90]\n",
config.latitude);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
config.latitude = RADIANS(config.latitude); if (config.manual_time) {
if (config.longitude > 180.0 || config.longitude < -180.0) { if (!isnan(config.latitude) || !isnan(config.longitude)) {
fprintf(stderr, "longitude (%lf) must be in interval [-180,180]\n", fprintf(stderr, "latitude and longitude are not valid in manual time mode\n");
config.longitude); return EXIT_FAILURE;
return EXIT_FAILURE; }
} else {
if (config.latitude > 90.0 || config.latitude < -90.0) {
fprintf(stderr, "latitude (%lf) must be in interval [-90,90]\n",
config.latitude);
return EXIT_FAILURE;
}
config.latitude = RADIANS(config.latitude);
if (config.longitude > 180.0 || config.longitude < -180.0) {
fprintf(stderr, "longitude (%lf) must be in interval [-180,180]\n",
config.longitude);
return EXIT_FAILURE;
}
config.longitude = RADIANS(config.longitude);
} }
config.longitude = RADIANS(config.longitude);
return wlrun(config); return wlrun(config);
} }

View File

@ -26,6 +26,17 @@ wlr-gamma-control-unstable-v1
*-L* <long> *-L* <long>
set longitude (e.g. 116.3) set longitude (e.g. 116.3)
*-S* <sunrise>
Manual time for sunrise as HH:MM (e.g. 06:30)
*-s* <sunset>
Manual time for sunset as HH:MM (e.g. 18:30)
*-d* <duration>
Manual animation time in seconds (e.g. 1800)
Only applicable when using manual sunset/sunrise times.
*-g* <gamma> *-g* <gamma>
set gamma (default: 1.0) set gamma (default: 1.0)