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 latitude;
int duration;
bool manual_time;
time_t sunrise;
time_t sunset;
time_t duration;
};
enum state {
@ -167,10 +170,22 @@ static void recalc_stops(struct context *ctx, time_t now) {
time_t last_day = ctx->calc_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 tm tm = { 0 };
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) {
case NORMAL:
@ -211,6 +226,8 @@ static void recalc_stops(struct context *ctx, time_t now) {
default:
abort();
}
done:
ctx->condition = cond;
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) {
init_time();
// Initialize defaults
struct context ctx = {
.sun = { 0 },
.condition = SUN_CONDITION_LAST,
.longitude_time_offset = longitude_time_offset(cfg.longitude),
.state = STATE_INITIAL,
.config = cfg,
};
if (!cfg.manual_time) {
ctx.longitude_time_offset = longitude_time_offset(cfg.longitude);
}
wl_list_init(&ctx.outputs);
if (setup_timer(&ctx) == -1) {
@ -682,29 +701,43 @@ static int wlrun(struct config cfg) {
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"
" -h show this help message\n"
" -t <temp> set low temperature (default: 4000)\n"
" -T <temp> set high temperature (default: 6500)\n"
" -l <lat> set latitude (e.g. 39.9)\n"
" -L <long> set longitude (e.g. 116.3)\n"
" -g <gamma> set gamma (default: 1.0)\n";
" -h show this help message\n"
" -t <temp> set low temperature (default: 4000)\n"
" -T <temp> set high temperature (default: 6500)\n"
" -l <lat> set latitude (e.g. 39.9)\n"
" -L <long> set longitude (e.g. 116.3)\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[]) {
#ifdef SPEEDRUN
fprintf(stderr, "warning: speedrun mode enabled\n");
#endif
init_time();
struct config config = {
.latitude = 0,
.longitude = 0,
.latitude = NAN,
.longitude = NAN,
.high_temp = 6500,
.low_temp = 4000,
.gamma = 1.0,
};
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) {
case 't':
config.low_temp = strtol(optarg, NULL, 10);
@ -718,6 +751,23 @@ int main(int argc, char *argv[]) {
case 'L':
config.longitude = strtod(optarg, NULL);
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':
config.gamma = strtod(optarg, NULL);
break;
@ -731,20 +781,27 @@ int main(int argc, char *argv[]) {
if (config.high_temp <= config.low_temp) {
fprintf(stderr, "high temp (%d) must be higher than low (%d) temp\n",
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;
}
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;
if (config.manual_time) {
if (!isnan(config.latitude) || !isnan(config.longitude)) {
fprintf(stderr, "latitude and longitude are not valid in manual time mode\n");
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);
}

View File

@ -26,6 +26,17 @@ wlr-gamma-control-unstable-v1
*-L* <long>
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>
set gamma (default: 1.0)