Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package wlsunset for openSUSE:Factory 
checked in at 2024-05-02 23:47:13
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/wlsunset (Old)
 and      /work/SRC/openSUSE:Factory/.wlsunset.new.1880 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "wlsunset"

Thu May  2 23:47:13 2024 rev:3 rq:1171155 version:0.4.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/wlsunset/wlsunset.changes        2023-06-05 
18:08:34.271829391 +0200
+++ /work/SRC/openSUSE:Factory/.wlsunset.new.1880/wlsunset.changes      
2024-05-03 10:49:24.415864180 +0200
@@ -1,0 +2,19 @@
+Tue Apr 23 02:19:03 UTC 2024 - Joshua Smith <[email protected]>
+
+- Update to version 0.4.0:
+  This release works around an issue where the compositor gives
+  a zero gamma size, and adds support for toggling forced modes
+  with SIGUSR1. Support for xdg_output is also removed, as newer
+  versions of wl_output contain the necessary output name.
+  * Force mode on SIGUSR1
+  * Change steps from 25K to 10K
+  * Calculate blend factor as double
+  * Remove xdg-output support
+  * Improve logging
+  * Free output name, skip storing description
+  * Explain the use of multiple locus better
+  * readme: Fix the list of forced modes
+  * Recreate controls on next set if gamma size is zero
+  * Fix typo in manpage
+
+-------------------------------------------------------------------

Old:
----
  wlsunset-0.3.0.tar.gz

New:
----
  wlsunset-0.4.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ wlsunset.spec ++++++
--- /var/tmp/diff_new_pack.W184It/_old  2024-05-03 10:49:25.099889084 +0200
+++ /var/tmp/diff_new_pack.W184It/_new  2024-05-03 10:49:25.099889084 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package wlsunset
 #
-# Copyright (c) 2023 SUSE LLC
+# Copyright (c) 2024 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           wlsunset
-Version:        0.3.0
+Version:        0.4.0
 Release:        0
 Summary:        Day/night gamma adjustments for Wayland compositors
 License:        MIT
@@ -35,11 +35,10 @@
 Day/night gamma adjustments for Wayland compositors supporting 
wlr-gamma-control-unstable-v1
 
 %prep
-%setup -q
+%autosetup
 
 %build
 %meson
-
 %meson_build
 
 %install

++++++ wlsunset-0.3.0.tar.gz -> wlsunset-0.4.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlsunset-0.3.0/README.md new/wlsunset-0.4.0/README.md
--- old/wlsunset-0.3.0/README.md        2023-05-24 16:47:43.000000000 +0200
+++ new/wlsunset-0.4.0/README.md        2024-04-20 14:26:44.000000000 +0200
@@ -1,6 +1,6 @@
 # wlsunset
 
-Day/night gamma adjustments for Wayland compositors supporting 
`wlr-gamma-control-unstable-v1` & `xdg-output-unstable-v1`.
+Day/night gamma adjustments for Wayland compositors supporting 
`wlr-gamma-control-unstable-v1`.
 
 # How to build and install
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlsunset-0.3.0/color_math.c 
new/wlsunset-0.4.0/color_math.c
--- old/wlsunset-0.3.0/color_math.c     2023-05-24 16:47:43.000000000 +0200
+++ new/wlsunset-0.4.0/color_math.c     2024-04-20 14:26:44.000000000 +0200
@@ -75,8 +75,13 @@
 
 /*
  * Illuminant D, or daylight locus, is is a "standard illuminant" used to
- * describe natural daylight. It is on this locus that D65, the whitepoint used
- * by most monitors and assumed by wlsunset, is defined.
+ * describe natural daylight as we perceive it, and as such is how we expect
+ * bright, cold white light sources to look. This is different from the
+ * planckian locus due to the effects of the atmosphere on sunlight travelling
+ * through it.
+ *
+ * It is on this locus that D65, the whitepoint used by most monitors and
+ * assumed by display servers, is defined.
  *
  * This approximation is strictly speaking only well-defined between 4000K and
  * 25000K, but we stretch it a bit further down for transition purposes.
@@ -103,9 +108,14 @@
 
 /*
  * Planckian locus, or black body locus, describes the color of a black body at
- * a certain temperatures. This is not entirely equivalent to daylight due to
- * atmospheric effects.
+ * a certain temperatures directly at its source, rather than observed through
+ * a thick atmosphere.
  *
+ * While we are used to bright light coming from afar and going through the
+ * atmosphere, we are used to seeing dim incandescent light sources from close
+ * enough for the atmosphere to not affect its perception, dictating how we
+ * expect dim, warm light sources to look.
+  *
  * This approximation is only valid from 1667K to 25000K.
  */
 static int planckian_locus(int temp, double *x, double *y) {
@@ -182,6 +192,16 @@
                return (struct rgb) {.r = 1.0, .g = 1.0, .b = 1.0};
        }
 
+       // We are not trying to calculate the accurate whitepoint, but rather
+       // an expected observed whitepoint. We generally expect dim and warm
+       // light sources to follow the planckian locus, while we expect bright
+       // and cold light sources to follow the daylight locus. There is no
+       // "correct" way to transition between these two curves, and so the
+       // goal is purely to be subjectively pleasant/non-jarring.
+       //
+       // A smooth transition between the two in the range between 2500K and
+       // 4000K seems to do the trick for now.
+
        struct xyz wp;
        if (temp >= 25000) {
                illuminant_d(25000, &wp.x, &wp.y);
@@ -192,7 +212,7 @@
                illuminant_d(temp, &x1, &y1);
                planckian_locus(temp, &x2, &y2);
 
-               double factor = (4000 - temp) / 1500;
+               double factor = (4000. - temp) / 1500.;
                double sinefactor = (cos(M_PI*factor) + 1.0) / 2.0;
                wp.x = x1 * sinefactor + x2 * (1.0 - sinefactor);
                wp.y = y1 * sinefactor + y2 * (1.0 - sinefactor);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlsunset-0.3.0/main.c new/wlsunset-0.4.0/main.c
--- old/wlsunset-0.3.0/main.c   2023-05-24 16:47:43.000000000 +0200
+++ new/wlsunset-0.4.0/main.c   2024-04-20 14:26:44.000000000 +0200
@@ -16,7 +16,6 @@
 #include <wayland-client-protocol.h>
 #include <wayland-client.h>
 
-#include "xdg-output-unstable-v1-client-protocol.h"
 #include "wlr-gamma-control-unstable-v1-client-protocol.h"
 #include "color_math.h"
 #include "str_vec.h"
@@ -116,6 +115,13 @@
        STATE_NORMAL,
        STATE_TRANSITION,
        STATE_STATIC,
+       STATE_FORCED,
+};
+
+enum force_state {
+       FORCE_OFF,
+       FORCE_HIGH,
+       FORCE_LOW,
 };
 
 struct context {
@@ -135,8 +141,9 @@
        struct wl_list outputs;
        timer_t timer;
 
+       enum force_state forced_state;
+
        struct zwlr_gamma_control_manager_v1 *gamma_control_manager;
-       struct zxdg_output_manager_v1 *xdg_output_manager;
 };
 
 struct output {
@@ -144,7 +151,6 @@
 
        struct context *context;
        struct wl_output *wl_output;
-       struct zxdg_output_v1 *xdg_output;
        struct zwlr_gamma_control_v1 *gamma_control;
 
        int table_fd;
@@ -182,7 +188,7 @@
        }
 }
 
-static int anim_kelvin_step = 25;
+static int anim_kelvin_step = 10;
 
 static void recalc_stops(struct context *ctx, time_t now) {
        time_t day = round_day_offset(now, ctx->longitude_time_offset);
@@ -190,6 +196,11 @@
                return;
        }
 
+       if (ctx->forced_state != FORCE_OFF) {
+               ctx->state = STATE_FORCED;
+               return;
+       }
+
        time_t last_day = ctx->calc_day;
        ctx->calc_day = day;
 
@@ -316,6 +327,15 @@
        case STATE_STATIC:
                return ctx->condition == MIDNIGHT_SUN ? ctx->config.high_temp :
                        ctx->config.low_temp;
+       case STATE_FORCED:
+               switch (ctx->forced_state) {
+               case FORCE_HIGH:
+                       return ctx->config.high_temp;
+               case FORCE_LOW:
+                       return ctx->config.low_temp;
+               default:
+                       abort();
+               }
        default:
                abort();
        }
@@ -359,6 +379,7 @@
                deadline = get_deadline_transition(ctx, now);
                break;
        case STATE_STATIC:
+       case STATE_FORCED:
                deadline = tomorrow(now, ctx->longitude_time_offset);
                break;
        default:
@@ -377,7 +398,6 @@
        timer_settime(timer, TIMER_ABSTIME, &timerspec, NULL);
 }
 
-
 static int create_anonymous_file(off_t size) {
        char template[] = "/tmp/wlsunset-shared-XXXXXX";
        int fd = mkstemp(template);
@@ -423,15 +443,23 @@
                struct zwlr_gamma_control_v1 *gamma_control, uint32_t 
ramp_size) {
        (void)gamma_control;
        struct output *output = data;
-       output->ramp_size = ramp_size;
        if (output->table_fd != -1) {
                close(output->table_fd);
+               output->table_fd = -1;
+       }
+       output->ramp_size = ramp_size;
+       if (ramp_size == 0) {
+               // Maybe the output does not currently have a CRTC to tell us
+               // the gamma size, let's clean up and retry on next set.
+               zwlr_gamma_control_v1_destroy(output->gamma_control);
+               output->gamma_control = NULL;
+               return;
        }
        output->table_fd = create_gamma_table(ramp_size, &output->table);
        output->context->new_output = true;
        if (output->table_fd < 0) {
-               fprintf(stderr, "could not create gamma table for output %d\n",
-                               output->id);
+               fprintf(stderr, "could not create gamma table for output %s 
(%d)\n",
+                               output->name, output->id);
                exit(EXIT_FAILURE);
        }
 }
@@ -440,8 +468,8 @@
                struct zwlr_gamma_control_v1 *gamma_control) {
        (void)gamma_control;
        struct output *output = data;
-       fprintf(stderr, "gamma control of output %d failed\n",
-                       output->id);
+       fprintf(stderr, "gamma control of output %s (%d) failed\n",
+                       output->name, output->id);
        zwlr_gamma_control_v1_destroy(output->gamma_control);
        output->gamma_control = NULL;
        if (output->table_fd != -1) {
@@ -455,27 +483,47 @@
        .failed = gamma_control_handle_failed,
 };
 
-static void xdg_output_handle_logical_position(void *data,
-               struct zxdg_output_v1 *xdg_output, int32_t x, int32_t y) {
-       (void)data, (void)xdg_output, (void)x, (void)y;
+static void setup_gamma_control(struct context *ctx, struct output *output) {
+       if (output->gamma_control != NULL) {
+               return;
+       }
+       if (ctx->gamma_control_manager == NULL) {
+               fprintf(stderr, "skipping setup of output %s (%d): 
gamma_control_manager missing\n",
+                               output->name, output->id);
+               return;
+       }
+       output->gamma_control = zwlr_gamma_control_manager_v1_get_gamma_control(
+               ctx->gamma_control_manager, output->wl_output);
+       zwlr_gamma_control_v1_add_listener(output->gamma_control,
+               &gamma_control_listener, output);
+}
+
+static void wl_output_handle_geometry(void *data, struct wl_output *output, 
int x, int y, int width,
+                                     int height, int subpixel, const char 
*make, const char *model,
+                                     int transform) {
+       (void)data, (void)output, (void)x, (void)y, (void)width, (void)height, 
(void)subpixel,
+               (void)make, (void)model, (void)transform;
 }
 
-static void xdg_output_handle_logical_size(void *data,
-               struct zxdg_output_v1 *xdg_output, int32_t width, int32_t 
height) {
-       (void)data, (void)xdg_output, (void)width, (void)height;
+static void wl_output_handle_mode(void *data, struct wl_output *output, 
uint32_t flags, int width,
+                                 int height, int refresh) {
+       (void)data, (void)output, (void)flags, (void)width, (void)height, 
(void)refresh;
 }
 
-static void xdg_output_handle_done(void *data,
-               struct zxdg_output_v1 *xdg_output) {
-       (void)data, (void)xdg_output;
+static void wl_output_handle_done(void *data, struct wl_output *wl_output) {
+       (void)wl_output;
+       struct output *output = data;
+       setup_gamma_control(output->context, output);
 }
 
-static void xdg_output_handle_name(void *data,
-               struct zxdg_output_v1 *xdg_output, const char *name) {
-       (void)xdg_output;
+static void wl_output_handle_scale(void *data, struct wl_output *output, int 
scale) {
+       (void)data, (void)output, (void)scale;
+}
+
+static void wl_output_handle_name(void *data, struct wl_output *wl_output, 
const char *name) {
+       (void)wl_output;
        struct output *output = data;
        output->name = strdup(name);
-
        struct config *cfg = &output->context->config;
        for (size_t idx = 0; idx < cfg->output_names.len; ++idx) {
                if (strcmp(output->name, cfg->output_names.data[idx]) == 0) {
@@ -486,47 +534,27 @@
        }
 }
 
-static void xdg_output_handle_description(void *data,
-               struct zxdg_output_v1 *xdg_output, const char *description) {
-       (void)data, (void)xdg_output, (void)description;
-}
-
-static const struct zxdg_output_v1_listener xdg_output_listener = {
-       .logical_position = xdg_output_handle_logical_position,
-       .logical_size = xdg_output_handle_logical_size,
-       .done = xdg_output_handle_done,
-       .name = xdg_output_handle_name,
-       .description = xdg_output_handle_description,
-};
-
-static void setup_xdg_output(struct context *ctx, struct output *output) {
-       if (output->xdg_output != NULL) {
-               return;
-       }
-       if (ctx->xdg_output_manager == NULL) {
-               fprintf(stderr, "skipping setup of output %d: 
xdg_output_manager is missing\n",
-                               output->id);
-               return;
+static void wl_output_handle_description(void *data, struct wl_output 
*wl_output, const char *description) {
+       (void)wl_output;
+       struct output *output = data;
+       struct config *cfg = &output->context->config;
+       for (size_t idx = 0; idx < cfg->output_names.len; ++idx) {
+               if (strcmp(description, cfg->output_names.data[idx]) == 0) {
+                       fprintf(stderr, "enabling output %s by description\n", 
description);
+                       output->enabled = true;
+                       return;
+               }
        }
-       output->xdg_output = zxdg_output_manager_v1_get_xdg_output(
-               ctx->xdg_output_manager, output->wl_output);
-       zxdg_output_v1_add_listener(output->xdg_output, &xdg_output_listener, 
output);
 }
 
-static void setup_gamma_control(struct context *ctx, struct output *output) {
-       if (output->gamma_control != NULL) {
-               return;
-       }
-       if (ctx->gamma_control_manager == NULL) {
-               fprintf(stderr, "skipping setup of output %d: 
gamma_control_manager missing\n",
-                               output->id);
-               return;
-       }
-       output->gamma_control = zwlr_gamma_control_manager_v1_get_gamma_control(
-               ctx->gamma_control_manager, output->wl_output);
-       zwlr_gamma_control_v1_add_listener(output->gamma_control,
-               &gamma_control_listener, output);
-}
+struct wl_output_listener wl_output_listener = {
+       .geometry = wl_output_handle_geometry,
+       .mode = wl_output_handle_mode,
+       .done = wl_output_handle_done,
+       .scale = wl_output_handle_scale,
+       .name = wl_output_handle_name,
+       .description = wl_output_handle_description,
+};
 
 static void registry_handle_global(void *data, struct wl_registry *registry,
                uint32_t name, const char *interface, uint32_t version) {
@@ -534,24 +562,27 @@
        struct context *ctx = (struct context *)data;
        if (strcmp(interface, wl_output_interface.name) == 0) {
                fprintf(stderr, "registry: adding output %d\n", name);
+
                struct output *output = calloc(1, sizeof(struct output));
                output->id = name;
-               output->wl_output = wl_registry_bind(registry, name,
-                               &wl_output_interface, 1);
                output->table_fd = -1;
-               output->enabled = true;
                output->context = ctx;
-               wl_list_insert(&ctx->outputs, &output->link);
 
-               if (ctx->config.output_names.len > 0) {
-                       setup_xdg_output(ctx, output);
-                       output->enabled = false;
-               }
-               setup_gamma_control(ctx, output);
-       } else if (ctx->config.output_names.len > 0 && strcmp(interface,
-                       zxdg_output_manager_v1_interface.name) == 0) {
-               ctx->xdg_output_manager = wl_registry_bind(registry, name,
-                               &zxdg_output_manager_v1_interface, version);
+               if (version >= WL_OUTPUT_NAME_SINCE_VERSION) {
+                       output->enabled = ctx->config.output_names.len == 0;
+                       output->wl_output = wl_registry_bind(registry, name,
+                                       &wl_output_interface, 
WL_OUTPUT_NAME_SINCE_VERSION);
+                       wl_output_add_listener(output->wl_output, 
&wl_output_listener, output);
+               } else {
+                       fprintf(stderr, "wl_output: old version (%d < %d), 
disabling name support\n",
+                                       version, WL_OUTPUT_NAME_SINCE_VERSION);
+                       output->enabled = true;
+                       output->wl_output = wl_registry_bind(registry, name,
+                                       &wl_output_interface, version);
+                       setup_gamma_control(ctx, output);
+               }
+
+               wl_list_insert(&ctx->outputs, &output->link);
        } else if (strcmp(interface,
                                zwlr_gamma_control_manager_v1_interface.name) 
== 0) {
                ctx->gamma_control_manager = wl_registry_bind(registry, name,
@@ -566,11 +597,9 @@
        struct output *output, *tmp;
        wl_list_for_each_safe(output, tmp, &ctx->outputs, link) {
                if (output->id == name) {
-                       fprintf(stderr, "registry: removing output %d\n", name);
+                       fprintf(stderr, "registry: removing output %s (%d)\n", 
output->name, name);
+                       free(output->name);
                        wl_list_remove(&output->link);
-                       if (output->xdg_output != NULL) {
-                               zxdg_output_v1_destroy(output->xdg_output);
-                       }
                        if (output->gamma_control != NULL) {
                                
zwlr_gamma_control_v1_destroy(output->gamma_control);
                        }
@@ -614,15 +643,20 @@
 static void set_temperature(struct wl_list *outputs, int temp, double gamma) {
        struct rgb wp = calc_whitepoint(temp);
        struct output *output;
+       fprintf(stderr, "setting temperature to %d K\n", temp);
+
        wl_list_for_each(output, outputs, link) {
-               fprintf(stderr, "setting temperature on output '%d' to %d K\n",
-                               output->id, temp);
+               if (output->gamma_control == NULL) {
+                       setup_gamma_control(output->context, output);
+                       continue;
+               }
                output_set_whitepoint(output, &wp, gamma);
        }
 }
 
 static int timer_fired = 0;
-static int timer_signal_fds[2];
+static int usr1_fired = 0;
+static int signal_fds[2];
 
 static int display_dispatch(struct wl_display *display, int timeout) {
        if (wl_display_prepare_read(display) == -1) {
@@ -631,7 +665,7 @@
 
        struct pollfd pfd[2];
        pfd[0].fd = wl_display_get_fd(display);
-       pfd[1].fd = timer_signal_fds[0];
+       pfd[1].fd = signal_fds[0];
 
        pfd[0].events = POLLOUT;
        // If we hit EPIPE we might have hit a protocol error. Continue reading
@@ -662,11 +696,26 @@
 
        if (pfd[1].revents & POLLIN) {
                // Empty signal fd
-               char garbage[8];
-               if (read(timer_signal_fds[0], &garbage, sizeof garbage) == -1
-                               && errno != EAGAIN) {
+               int signal;
+               int res = read(signal_fds[0], &signal, sizeof signal);
+               if (res == -1) {
+                       if (errno != EAGAIN) {
+                               return -1;
+                       }
+               } else if (res != 4) {
+                       fprintf(stderr, "could not read full signal ID\n");
                        return -1;
                }
+
+               switch (signal) {
+               case SIGALRM:
+                       timer_fired = true;
+                       break;
+               case SIGUSR1:
+                       // do something
+                       usr1_fired = true;
+                       break;
+               }
        }
 
        if ((pfd[0].revents & POLLIN) == 0) {
@@ -681,10 +730,8 @@
        return wl_display_dispatch_pending(display);
 }
 
-static void timer_signal(int signal) {
-       (void)signal;
-       timer_fired = true;
-       if (write(timer_signal_fds[1], "\0", 1) == -1 && errno != EAGAIN) {
+static void signal_handler(int signal) {
+       if (write(signal_fds[1], &signal, sizeof signal) == -1 && errno != 
EAGAIN) {
                // This is unfortunate.
        }
 }
@@ -698,24 +745,29 @@
        return 0;
 }
 
-static int setup_timer(struct context *ctx) {
-       struct sigaction timer_action = {
-               .sa_handler = timer_signal,
+static int setup_signals(struct context *ctx) {
+       struct sigaction signal_action = {
+               .sa_handler = signal_handler,
                .sa_flags = 0,
        };
-       if (pipe(timer_signal_fds) == -1) {
+       if (pipe(signal_fds) == -1) {
                fprintf(stderr, "could not create signal pipe: %s\n",
                                strerror(errno));
                return -1;
        }
-       if (set_nonblock(timer_signal_fds[0]) == -1 ||
-                       set_nonblock(timer_signal_fds[1]) == -1) {
+       if (set_nonblock(signal_fds[0]) == -1 ||
+                       set_nonblock(signal_fds[1]) == -1) {
                fprintf(stderr, "could not set nonblock on signal pipe: %s\n",
                                strerror(errno));
                return -1;
        }
-       if (sigaction(SIGALRM, &timer_action, NULL) == -1) {
-               fprintf(stderr, "could not configure alarm handler: %s\n",
+       if (sigaction(SIGALRM, &signal_action, NULL) == -1) {
+               fprintf(stderr, "could not configure SIGALRM handler: %s\n",
+                               strerror(errno));
+               return -1;
+       }
+       if (sigaction(SIGUSR1, &signal_action, NULL) == -1) {
+               fprintf(stderr, "could not configure SIGUSR1 handler: %s\n",
                                strerror(errno));
                return -1;
        }
@@ -744,7 +796,7 @@
 
        wl_list_init(&ctx.outputs);
 
-       if (setup_timer(&ctx) == -1) {
+       if (setup_signals(&ctx) == -1) {
                return EXIT_FAILURE;
        }
 
@@ -758,11 +810,6 @@
        wl_registry_add_listener(registry, &registry_listener, &ctx);
        wl_display_roundtrip(display);
 
-       if (ctx.config.output_names.len > 0 && ctx.xdg_output_manager == NULL) {
-               fprintf(stderr, "compositor doesn't support 
xdg-output-unstable-v1\n");
-               return EXIT_FAILURE;
-       }
-
        if (ctx.gamma_control_manager == NULL) {
                fprintf(stderr, "compositor doesn't support 
wlr-gamma-control-unstable-v1\n");
                return EXIT_FAILURE;
@@ -770,9 +817,6 @@
 
        struct output *output;
        wl_list_for_each(output, &ctx.outputs, link) {
-               if (ctx.config.output_names.len > 0) {
-                       setup_xdg_output(&ctx, output);
-               }
                setup_gamma_control(&ctx, output);
        }
        wl_display_roundtrip(display);
@@ -786,9 +830,40 @@
 
        int old_temp = temp;
        while (display_dispatch(display, -1) != -1) {
+               if (ctx.new_output) {
+                       ctx.new_output = false;
+
+                       // Force set_temperature
+                       old_temp = 0;
+                       timer_fired = true;
+               }
+
+               if (usr1_fired) {
+                       usr1_fired = false;
+                       switch (ctx.forced_state) {
+                       case FORCE_OFF:
+                               ctx.forced_state = FORCE_HIGH;
+                               fprintf(stderr, "forcing high temperature\n");
+                               break;
+                       case FORCE_HIGH:
+                               ctx.forced_state = FORCE_LOW;
+                               fprintf(stderr, "forcing low temperature\n");
+                               break;
+                       case FORCE_LOW:
+                               ctx.forced_state = FORCE_OFF;
+                               fprintf(stderr, "disabling forced 
temperature\n");
+                               break;
+                       default:
+                               abort();
+                       }
+
+                       // Force re-calculation
+                       ctx.calc_day = 0;
+                       timer_fired = true;
+               }
+
                if (timer_fired) {
                        timer_fired = false;
-
                        now = get_time_sec();
                        recalc_stops(&ctx, now);
                        update_timer(&ctx, ctx.timer, now);
@@ -798,10 +873,6 @@
                                ctx.new_output = false;
                                set_temperature(&ctx.outputs, temp, 
ctx.config.gamma);
                        }
-               } else if (ctx.new_output) {
-                       ctx.new_output = false;
-
-                       set_temperature(&ctx.outputs, temp, ctx.config.gamma);
                }
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlsunset-0.3.0/meson.build 
new/wlsunset-0.4.0/meson.build
--- old/wlsunset-0.3.0/meson.build      2023-05-24 16:47:43.000000000 +0200
+++ new/wlsunset-0.4.0/meson.build      2024-04-20 14:26:44.000000000 +0200
@@ -1,7 +1,7 @@
 project(
        'wlsunset',
        'c',
-       version: '0.3.0',
+       version: '0.4.0',
        license: 'MIT',
        meson_version: '>=0.56.0',
        default_options: [
@@ -35,8 +35,8 @@
 scanner_private_code = generator(scanner, output: '@[email protected]', 
arguments: ['private-code', '@INPUT@', '@OUTPUT@'])
 scanner_client_header = generator(scanner, output: 
'@[email protected]', arguments: ['client-header', '@INPUT@', 
'@OUTPUT@'])
 
-protocols_src = 
[scanner_private_code.process('wlr-gamma-control-unstable-v1.xml', 
'xdg-output-unstable-v1.xml')]
-protocols_headers = 
[scanner_client_header.process('wlr-gamma-control-unstable-v1.xml', 
'xdg-output-unstable-v1.xml')]
+protocols_src = 
[scanner_private_code.process('wlr-gamma-control-unstable-v1.xml')]
+protocols_headers = 
[scanner_client_header.process('wlr-gamma-control-unstable-v1.xml')]
 
 wl_client = dependency('wayland-client')
 wl_protocols = dependency('wayland-protocols')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlsunset-0.3.0/wlsunset.1.scd 
new/wlsunset-0.4.0/wlsunset.1.scd
--- old/wlsunset-0.3.0/wlsunset.1.scd   2023-05-24 16:47:43.000000000 +0200
+++ new/wlsunset-0.4.0/wlsunset.1.scd   2024-04-20 14:26:44.000000000 +0200
@@ -2,7 +2,7 @@
 
 # NAME
 
-wlsunet - Day/night gamma adjustments for Wayland compositors supporting
+wlsunset - day/night gamma adjustments for Wayland compositors supporting
 wlr-gamma-control-unstable-v1
 
 # SYNOPSIS
@@ -12,33 +12,43 @@
 # OPTIONS
 
 *-h*
-       show this help message
+       Show this help message.
 
 *-T* <temp>
-       set high temperature (default: 6500)
+       Set high temperature (default: 6500).
 
 *-t* <temp>
-       set low temperature (default: 4000)
+       Set low temperature (default: 4000).
 
 *-l* <lat>
-       set latitude (e.g. 39.9)
+       Set latitude (e.g. 39.9).
 
 *-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)
+       Manual time for sunrise as HH:MM (e.g. 06:30).
 
 *-s* <sunset>
-       Manual time for sunset as HH:MM (e.g. 18:30)
+       Manual time for sunset as HH:MM (e.g. 18:30).
 
 *-d* <duration>
-       Manual animation time in seconds (e.g. 1800)
+       Manual animation time in seconds (e.g. 1800).
 
        Only applicable when using manual sunset/sunrise times.
 
 *-g* <gamma>
-       set gamma (default: 1.0)
+       Set gamma (default: 1.0).
+
+# RUNTIME CONTROL
+
+Sending SIGUSR1 to wlsunset causes it to cycle through the following modes:
+
+1. Forced use of the high temperature.
+
+2. Forced use of the low temperature.
+
+3. Automatic temperature calculation, the default behavior.
 
 # EXAMPLE
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlsunset-0.3.0/xdg-output-unstable-v1.xml 
new/wlsunset-0.4.0/xdg-output-unstable-v1.xml
--- old/wlsunset-0.3.0/xdg-output-unstable-v1.xml       2023-05-24 
16:47:43.000000000 +0200
+++ new/wlsunset-0.4.0/xdg-output-unstable-v1.xml       1970-01-01 
01:00:00.000000000 +0100
@@ -1,220 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<protocol name="xdg_output_unstable_v1">
-
-  <copyright>
-    Copyright © 2017 Red Hat Inc.
-
-    Permission is hereby granted, free of charge, to any person obtaining a
-    copy of this software and associated documentation files (the "Software"),
-    to deal in the Software without restriction, including without limitation
-    the rights to use, copy, modify, merge, publish, distribute, sublicense,
-    and/or sell copies of the Software, and to permit persons to whom the
-    Software is furnished to do so, subject to the following conditions:
-
-    The above copyright notice and this permission notice (including the next
-    paragraph) shall be included in all copies or substantial portions of the
-    Software.
-
-    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-    DEALINGS IN THE SOFTWARE.
-  </copyright>
-
-  <description summary="Protocol to describe output regions">
-    This protocol aims at describing outputs in a way which is more in line
-    with the concept of an output on desktop oriented systems.
-
-    Some information are more specific to the concept of an output for
-    a desktop oriented system and may not make sense in other applications,
-    such as IVI systems for example.
-
-    Typically, the global compositor space on a desktop system is made of
-    a contiguous or overlapping set of rectangular regions.
-
-    Some of the information provided in this protocol might be identical
-    to their counterparts already available from wl_output, in which case
-    the information provided by this protocol should be preferred to their
-    equivalent in wl_output. The goal is to move the desktop specific
-    concepts (such as output location within the global compositor space,
-    the connector name and types, etc.) out of the core wl_output protocol.
-
-    Warning! The protocol described in this file is experimental and
-    backward incompatible changes may be made. Backward compatible
-    changes may be added together with the corresponding interface
-    version bump.
-    Backward incompatible changes are done by bumping the version
-    number in the protocol and interface names and resetting the
-    interface version. Once the protocol is to be declared stable,
-    the 'z' prefix and the version number in the protocol and
-    interface names are removed and the interface version number is
-    reset.
-  </description>
-
-  <interface name="zxdg_output_manager_v1" version="3">
-    <description summary="manage xdg_output objects">
-      A global factory interface for xdg_output objects.
-    </description>
-
-    <request name="destroy" type="destructor">
-      <description summary="destroy the xdg_output_manager object">
-       Using this request a client can tell the server that it is not
-       going to use the xdg_output_manager object anymore.
-
-       Any objects already created through this instance are not affected.
-      </description>
-    </request>
-
-    <request name="get_xdg_output">
-      <description summary="create an xdg output from a wl_output">
-       This creates a new xdg_output object for the given wl_output.
-      </description>
-      <arg name="id" type="new_id" interface="zxdg_output_v1"/>
-      <arg name="output" type="object" interface="wl_output"/>
-    </request>
-  </interface>
-
-  <interface name="zxdg_output_v1" version="3">
-    <description summary="compositor logical output region">
-      An xdg_output describes part of the compositor geometry.
-
-      This typically corresponds to a monitor that displays part of the
-      compositor space.
-
-      For objects version 3 onwards, after all xdg_output properties have been
-      sent (when the object is created and when properties are updated), a
-      wl_output.done event is sent. This allows changes to the output
-      properties to be seen as atomic, even if they happen via multiple events.
-    </description>
-
-    <request name="destroy" type="destructor">
-      <description summary="destroy the xdg_output object">
-       Using this request a client can tell the server that it is not
-       going to use the xdg_output object anymore.
-      </description>
-    </request>
-
-    <event name="logical_position">
-      <description summary="position of the output within the global 
compositor space">
-       The position event describes the location of the wl_output within
-       the global compositor space.
-
-       The logical_position event is sent after creating an xdg_output
-       (see xdg_output_manager.get_xdg_output) and whenever the location
-       of the output changes within the global compositor space.
-      </description>
-      <arg name="x" type="int"
-          summary="x position within the global compositor space"/>
-      <arg name="y" type="int"
-          summary="y position within the global compositor space"/>
-    </event>
-
-    <event name="logical_size">
-      <description summary="size of the output in the global compositor space">
-       The logical_size event describes the size of the output in the
-       global compositor space.
-
-       For example, a surface without any buffer scale, transformation
-       nor rotation set, with the size matching the logical_size will
-       have the same size as the corresponding output when displayed.
-
-       Most regular Wayland clients should not pay attention to the
-       logical size and would rather rely on xdg_shell interfaces.
-
-       Some clients such as Xwayland, however, need this to configure
-       their surfaces in the global compositor space as the compositor
-       may apply a different scale from what is advertised by the output
-       scaling property (to achieve fractional scaling, for example).
-
-       For example, for a wl_output mode 3840×2160 and a scale factor 2:
-
-       - A compositor not scaling the surface buffers will advertise a
-         logical size of 3840×2160,
-
-       - A compositor automatically scaling the surface buffers will
-         advertise a logical size of 1920×1080,
-
-       - A compositor using a fractional scale of 1.5 will advertise a
-         logical size of 2560×1440.
-
-       For example, for a wl_output mode 1920×1080 and a 90 degree rotation,
-       the compositor will advertise a logical size of 1080x1920.
-
-       The logical_size event is sent after creating an xdg_output
-       (see xdg_output_manager.get_xdg_output) and whenever the logical
-       size of the output changes, either as a result of a change in the
-       applied scale or because of a change in the corresponding output
-       mode(see wl_output.mode) or transform (see wl_output.transform).
-      </description>
-      <arg name="width" type="int"
-          summary="width in global compositor space"/>
-      <arg name="height" type="int"
-          summary="height in global compositor space"/>
-    </event>
-
-    <event name="done">
-      <description summary="all information about the output have been sent">
-       This event is sent after all other properties of an xdg_output
-       have been sent.
-
-       This allows changes to the xdg_output properties to be seen as
-       atomic, even if they happen via multiple events.
-
-       For objects version 3 onwards, this event is deprecated. Compositors
-       are not required to send it anymore and must send wl_output.done
-       instead.
-      </description>
-    </event>
-
-    <!-- Version 2 additions -->
-
-    <event name="name" since="2">
-      <description summary="name of this output">
-       Many compositors will assign names to their outputs, show them to the
-       user, allow them to be configured by name, etc. The client may wish to
-       know this name as well to offer the user similar behaviors.
-
-       The naming convention is compositor defined, but limited to
-       alphanumeric characters and dashes (-). Each name is unique among all
-       wl_output globals, but if a wl_output global is destroyed the same name
-       may be reused later. The names will also remain consistent across
-       sessions with the same hardware and software configuration.
-
-       Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. However, do
-       not assume that the name is a reflection of an underlying DRM
-       connector, X11 connection, etc.
-
-       The name event is sent after creating an xdg_output (see
-       xdg_output_manager.get_xdg_output). This event is only sent once per
-       xdg_output, and the name does not change over the lifetime of the
-       wl_output global.
-      </description>
-      <arg name="name" type="string" summary="output name"/>
-    </event>
-
-    <event name="description" since="2">
-      <description summary="human-readable description of this output">
-       Many compositors can produce human-readable descriptions of their
-       outputs.  The client may wish to know this description as well, to
-       communicate the user for various purposes.
-
-       The description is a UTF-8 string with no convention defined for its
-       contents. Examples might include 'Foocorp 11" Display' or 'Virtual X11
-       output via :1'.
-
-       The description event is sent after creating an xdg_output (see
-       xdg_output_manager.get_xdg_output) and whenever the description
-       changes. The description is optional, and may not be sent at all.
-
-       For objects of version 2 and lower, this event is only sent once per
-       xdg_output, and the description does not change over the lifetime of
-       the wl_output global.
-      </description>
-      <arg name="description" type="string" summary="output description"/>
-    </event>
-
-  </interface>
-</protocol>

Reply via email to