Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package wlsunset for openSUSE:Factory 
checked in at 2023-06-05 18:08:22
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/wlsunset (Old)
 and      /work/SRC/openSUSE:Factory/.wlsunset.new.15902 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "wlsunset"

Mon Jun  5 18:08:22 2023 rev:2 rq:1090936 version:0.3.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/wlsunset/wlsunset.changes        2021-05-02 
18:39:05.800185750 +0200
+++ /work/SRC/openSUSE:Factory/.wlsunset.new.15902/wlsunset.changes     
2023-06-05 18:08:34.271829391 +0200
@@ -1,0 +2,19 @@
+Thu Jun  1 09:45:07 UTC 2023 - Soc Virnyl Estela <[email protected]>
+
+- Update to version 0.3.0:
+  This release includes the ability to run only on a specific output, and
+  contains improvements around Wayland server shutdown, manual time
+  handling, and FreeBSD support. Here are the changes:
+
+  * Support running only for specific outputs (displays)
+  * Refactor RGB & XYZ colors into structs
+  * meson: Copy seatd's scdoc handling
+  * Only set up xdg-output once
+  * Store enabled state on output
+  * Ensure step time is at least 1 second
+  * Move feature defines to C files
+  * Use timezone as time offset for manual time
+  * Negate longitude_time_offset
+  * display_dispatch: Terminate poll loop on EPIPE
+
+-------------------------------------------------------------------

Old:
----
  wlsunset-0.2.0.tar.gz

New:
----
  wlsunset-0.3.0.tar.gz

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

Other differences:
------------------
++++++ wlsunset.spec ++++++
--- /var/tmp/diff_new_pack.cEkwdT/_old  2023-06-05 18:08:34.847832793 +0200
+++ /var/tmp/diff_new_pack.cEkwdT/_new  2023-06-05 18:08:34.851832816 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package wlsunset
 #
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2023 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.2.0
+Version:        0.3.0
 Release:        0
 Summary:        Day/night gamma adjustments for Wayland compositors
 License:        MIT

++++++ wlsunset-0.2.0.tar.gz -> wlsunset-0.3.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlsunset-0.2.0/.builds/archlinux.yml 
new/wlsunset-0.3.0/.builds/archlinux.yml
--- old/wlsunset-0.2.0/.builds/archlinux.yml    1970-01-01 01:00:00.000000000 
+0100
+++ new/wlsunset-0.3.0/.builds/archlinux.yml    2023-05-24 16:47:43.000000000 
+0200
@@ -0,0 +1,12 @@
+image: archlinux
+packages:
+   - meson
+   - wayland
+   - wayland-protocols
+sources:
+   - https://git.sr.ht/~kennylevinsen/wlsunset
+tasks:
+   - build: |
+      meson build wlsunset
+      ninja -C build
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlsunset-0.2.0/.editorconfig 
new/wlsunset-0.3.0/.editorconfig
--- old/wlsunset-0.2.0/.editorconfig    1970-01-01 01:00:00.000000000 +0100
+++ new/wlsunset-0.3.0/.editorconfig    2023-05-24 16:47:43.000000000 +0200
@@ -0,0 +1,8 @@
+root = true
+
+[*]
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+indent_style = tab
+indent_size = 8
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlsunset-0.2.0/.gitignore 
new/wlsunset-0.3.0/.gitignore
--- old/wlsunset-0.2.0/.gitignore       1970-01-01 01:00:00.000000000 +0100
+++ new/wlsunset-0.3.0/.gitignore       2023-05-24 16:47:43.000000000 +0200
@@ -0,0 +1,2 @@
+build/
+.cache/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlsunset-0.2.0/README.md new/wlsunset-0.3.0/README.md
--- old/wlsunset-0.2.0/README.md        2021-04-25 22:56:30.000000000 +0200
+++ new/wlsunset-0.3.0/README.md        2023-05-24 16:47:43.000000000 +0200
@@ -1,6 +1,6 @@
 # wlsunset
 
-Day/night gamma adjustments for Wayland compositors supporting 
wlr-gamma-control-unstable-v1.
+Day/night gamma adjustments for Wayland compositors supporting 
`wlr-gamma-control-unstable-v1` & `xdg-output-unstable-v1`.
 
 # How to build and install
 
@@ -25,4 +25,4 @@
 
 # Help
 
-Go to #kennylevinsen @ chat.freenode.net to discuss, or use 
[~kennylevinsen/[email protected]](https://lists.sr.ht/~kennylevinsen/public-inbox)
+Go to #kennylevinsen @ irc.libera.chat to discuss, or use 
[~kennylevinsen/[email protected]](https://lists.sr.ht/~kennylevinsen/wlsunset-devel)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlsunset-0.2.0/color_math.c 
new/wlsunset-0.3.0/color_math.c
--- old/wlsunset-0.2.0/color_math.c     2021-04-25 22:56:30.000000000 +0200
+++ new/wlsunset-0.3.0/color_math.c     2023-05-24 16:47:43.000000000 +0200
@@ -1,3 +1,5 @@
+#define _USE_MATH_DEFINES
+#define _XOPEN_SOURCE 700
 #define _POSIX_C_SOURCE 200809L
 #include <math.h>
 #include <errno.h>
@@ -159,31 +161,32 @@
        }
 }
 
-static void xyz_to_srgb(double x, double y, double z, double *r, double *g, 
double *b) {
+static struct rgb xyz_to_srgb(const struct xyz *xyz) {
        // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
-       *r = srgb_gamma(clamp(3.2404542 * x - 1.5371385 * y - 0.4985314 * z), 
2.2);
-       *g = srgb_gamma(clamp(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z), 
2.2);
-       *b = srgb_gamma(clamp(0.0556434 * x - 0.2040259 * y + 1.0572252 * z), 
2.2);
+       return (struct rgb) {
+               .r = srgb_gamma(clamp(3.2404542 * xyz->x - 1.5371385 * xyz->y - 
0.4985314 * xyz->z), 2.2),
+               .g = srgb_gamma(clamp(-0.9692660 * xyz->x + 1.8760108 * xyz->y 
+ 0.0415560 * xyz->z), 2.2),
+               .b = srgb_gamma(clamp(0.0556434 * xyz->x - 0.2040259 * xyz->y + 
1.0572252 * xyz->z), 2.2)
+       };
 }
 
-static void srgb_normalize(double *r, double *g, double *b) {
-       double maxw = fmaxl(*r, fmaxl(*g, *b));
-       *r /= maxw;
-       *g /= maxw;
-       *b /= maxw;
+static void srgb_normalize(struct rgb *rgb) {
+       double maxw = fmax(rgb->r, fmax(rgb->g, rgb->b));
+       rgb->r /= maxw;
+       rgb->g /= maxw;
+       rgb->b /= maxw;
 }
 
-void calc_whitepoint(int temp, double *rw, double *gw, double *bw) {
+struct rgb calc_whitepoint(int temp) {
        if (temp == 6500) {
-               *rw = *gw = *bw = 1.0;
-               return;
+               return (struct rgb) {.r = 1.0, .g = 1.0, .b = 1.0};
        }
 
-       double x = 1.0, y = 1.0;
+       struct xyz wp;
        if (temp >= 25000) {
-               illuminant_d(25000, &x, &y);
+               illuminant_d(25000, &wp.x, &wp.y);
        } else if (temp >= 4000) {
-               illuminant_d(temp, &x, &y);
+               illuminant_d(temp, &wp.x, &wp.y);
        } else if (temp >= 2500) {
                double x1, y1, x2, y2;
                illuminant_d(temp, &x1, &y1);
@@ -191,16 +194,16 @@
 
                double factor = (4000 - temp) / 1500;
                double sinefactor = (cos(M_PI*factor) + 1.0) / 2.0;
-               x = x1 * sinefactor + x2 * (1.0 - sinefactor);
-               y = y1 * sinefactor + y2 * (1.0 - sinefactor);
-       } else if (temp >= 1667) {
-               planckian_locus(temp, &x, &y);
-       } else {
-               planckian_locus(1667, &x, &y);
+               wp.x = x1 * sinefactor + x2 * (1.0 - sinefactor);
+               wp.y = y1 * sinefactor + y2 * (1.0 - sinefactor);
+       } else  {
+               planckian_locus(temp >= 1667 ? temp : 1667, &wp.x, &wp.y);
        }
-       double z = 1.0 - x - y;
+       wp.z = 1.0 - wp.x - wp.y;
+
+       struct rgb wp_rgb = xyz_to_srgb(&wp);
+       srgb_normalize(&wp_rgb);
 
-       xyz_to_srgb(x, y, z, rw, gw, bw);
-       srgb_normalize(rw, gw, bw);
+       return wp_rgb;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlsunset-0.2.0/color_math.h 
new/wlsunset-0.3.0/color_math.h
--- old/wlsunset-0.2.0/color_math.h     2021-04-25 22:56:30.000000000 +0200
+++ new/wlsunset-0.3.0/color_math.h     2023-05-24 16:47:43.000000000 +0200
@@ -22,7 +22,15 @@
        time_t dusk;
 };
 
+struct rgb {
+  double r, g, b;
+};
+
+struct xyz {
+  double x, y, z;
+};
+
 enum sun_condition calc_sun(struct tm *tm, double latitude, struct sun *sun);
-void calc_whitepoint(int temp, double *rw, double *gw, double *bw);
+struct rgb calc_whitepoint(int temp);
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlsunset-0.2.0/main.c new/wlsunset-0.3.0/main.c
--- old/wlsunset-0.2.0/main.c   2021-04-25 22:56:30.000000000 +0200
+++ new/wlsunset-0.3.0/main.c   2023-05-24 16:47:43.000000000 +0200
@@ -1,3 +1,5 @@
+#define _DEFAULT_SOURCE
+#define _XOPEN_SOURCE 700
 #include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -14,8 +16,10 @@
 #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"
 
 #if defined(SPEEDRUN)
 static time_t start = 0, offset = 0, multiplier = 1000;
@@ -68,6 +72,13 @@
 }
 #endif
 
+static time_t get_timezone(void) {
+       struct tm tm;
+       time_t now = time(NULL);
+       localtime_r(&now, &tm);
+       return tm.tm_gmtoff;
+}
+
 static time_t round_day_offset(time_t now, time_t offset) {
        return now - ((now - offset) % 86400);
 }
@@ -77,7 +88,11 @@
 }
 
 static time_t longitude_time_offset(double longitude) {
-       return longitude * 43200 / M_PI;
+       return -longitude * 43200 / M_PI;
+}
+
+static int max(int a, int b) {
+       return a > b ? a : b;
 }
 
 struct config {
@@ -92,6 +107,8 @@
        time_t sunrise;
        time_t sunset;
        time_t duration;
+
+       struct str_vec output_names;
 };
 
 enum state {
@@ -105,7 +122,7 @@
        struct config config;
        struct sun sun;
 
-       double longitude_time_offset;
+       time_t longitude_time_offset;
 
        enum state state;
        enum sun_condition condition;
@@ -117,6 +134,9 @@
        bool new_output;
        struct wl_list outputs;
        timer_t timer;
+
+       struct zwlr_gamma_control_manager_v1 *gamma_control_manager;
+       struct zxdg_output_manager_v1 *xdg_output_manager;
 };
 
 struct output {
@@ -124,12 +144,15 @@
 
        struct context *context;
        struct wl_output *wl_output;
+       struct zxdg_output_v1 *xdg_output;
        struct zwlr_gamma_control_v1 *gamma_control;
 
        int table_fd;
        uint32_t id;
        uint32_t ramp_size;
        uint16_t *table;
+       bool enabled;
+       char *name;
 };
 
 static void print_trajectory(struct context *ctx) {
@@ -162,7 +185,7 @@
 static int anim_kelvin_step = 25;
 
 static void recalc_stops(struct context *ctx, time_t now) {
-       time_t day = round_day_offset(now, -ctx->longitude_time_offset);
+       time_t day = round_day_offset(now, ctx->longitude_time_offset);
        if (day == ctx->calc_day) {
                return;
        }
@@ -231,10 +254,10 @@
        ctx->condition = cond;
 
        int temp_diff = ctx->config.high_temp - ctx->config.low_temp;
-       ctx->dawn_step_time = (ctx->sun.sunrise - ctx->sun.dawn) *
-               anim_kelvin_step / temp_diff;
-       ctx->dusk_step_time = (ctx->sun.dusk - ctx->sun.sunset) *
-               anim_kelvin_step / temp_diff;
+       ctx->dawn_step_time = max(1, (ctx->sun.sunrise - ctx->sun.dawn) *
+               anim_kelvin_step / temp_diff);
+       ctx->dusk_step_time = max(1, (ctx->sun.dusk - ctx->sun.sunset) *
+               anim_kelvin_step / temp_diff);
 
        print_trajectory(ctx);
 }
@@ -308,7 +331,7 @@
        } else if (now < ctx->sun.dusk) {
                return now + ctx->dusk_step_time;
        } else {
-               return tomorrow(now, -ctx->longitude_time_offset);
+               return tomorrow(now, ctx->longitude_time_offset);
        }
 }
 
@@ -320,7 +343,7 @@
                }
                // fallthrough
        case POLAR_NIGHT:
-               return tomorrow(now, -ctx->longitude_time_offset);
+               return tomorrow(now, ctx->longitude_time_offset);
        default:
                abort();
        }
@@ -336,7 +359,7 @@
                deadline = get_deadline_transition(ctx, now);
                break;
        case STATE_STATIC:
-               deadline = tomorrow(now, -ctx->longitude_time_offset);
+               deadline = tomorrow(now, ctx->longitude_time_offset);
                break;
        default:
                abort();
@@ -354,7 +377,6 @@
        timer_settime(timer, TIMER_ABSTIME, &timerspec, NULL);
 }
 
-static struct zwlr_gamma_control_manager_v1 *gamma_control_manager = NULL;
 
 static int create_anonymous_file(off_t size) {
        char template[] = "/tmp/wlsunset-shared-XXXXXX";
@@ -433,17 +455,75 @@
        .failed = gamma_control_handle_failed,
 };
 
-static void setup_output(struct output *output) {
+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 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 xdg_output_handle_done(void *data,
+               struct zxdg_output_v1 *xdg_output) {
+       (void)data, (void)xdg_output;
+}
+
+static void xdg_output_handle_name(void *data,
+               struct zxdg_output_v1 *xdg_output, const char *name) {
+       (void)xdg_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) {
+                       fprintf(stderr, "enabling output %s by name\n", 
output->name);
+                       output->enabled = true;
+                       return;
+               }
+       }
+}
+
+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;
+       }
+       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 (gamma_control_manager == NULL) {
+       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(
-               gamma_control_manager, output->wl_output);
+               ctx->gamma_control_manager, output->wl_output);
        zwlr_gamma_control_v1_add_listener(output->gamma_control,
                &gamma_control_listener, output);
 }
@@ -459,12 +539,22 @@
                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);
-               setup_output(output);
+
+               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);
        } else if (strcmp(interface,
                                zwlr_gamma_control_manager_v1_interface.name) 
== 0) {
-               gamma_control_manager = wl_registry_bind(registry, name,
+               ctx->gamma_control_manager = wl_registry_bind(registry, name,
                                &zwlr_gamma_control_manager_v1_interface, 1);
        }
 }
@@ -478,6 +568,9 @@
                if (output->id == name) {
                        fprintf(stderr, "registry: removing output %d\n", 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);
                        }
@@ -508,21 +601,23 @@
        }
 }
 
-static void set_temperature(struct wl_list *outputs, int temp, double gamma) {
-       double rw, gw, bw;
-       calc_whitepoint(temp, &rw, &gw, &bw);
-       fprintf(stderr, "setting temperature to %d K\n", temp);
+static void output_set_whitepoint(struct output *output, struct rgb *wp, 
double gamma) {
+       if (!output->enabled || output->gamma_control == NULL || 
output->table_fd == -1) {
+               return;
+       }
+       fill_gamma_table(output->table, output->ramp_size, wp->r, wp->g, wp->b, 
gamma);
+       lseek(output->table_fd, 0, SEEK_SET);
+       zwlr_gamma_control_v1_set_gamma(output->gamma_control,
+                       output->table_fd);
+}
 
+static void set_temperature(struct wl_list *outputs, int temp, double gamma) {
+       struct rgb wp = calc_whitepoint(temp);
        struct output *output;
        wl_list_for_each(output, outputs, link) {
-               if (output->gamma_control == NULL || output->table_fd == -1) {
-                       continue;
-               }
-               fill_gamma_table(output->table, output->ramp_size,
-                               rw, gw, bw, gamma);
-               lseek(output->table_fd, 0, SEEK_SET);
-               zwlr_gamma_control_v1_set_gamma(output->gamma_control,
-                               output->table_fd);
+               fprintf(stderr, "setting temperature on output '%d' to %d K\n",
+                               output->id, temp);
+               output_set_whitepoint(output, &wp, gamma);
        }
 }
 
@@ -539,8 +634,10 @@
        pfd[1].fd = timer_signal_fds[0];
 
        pfd[0].events = POLLOUT;
-       while (wl_display_flush(display) == -1) {
-               if (errno != EAGAIN && errno != EPIPE) {
+       // If we hit EPIPE we might have hit a protocol error. Continue reading
+       // so that we can see what happened.
+       while (wl_display_flush(display) == -1 && errno != EPIPE) {
+               if (errno != EAGAIN) {
                        wl_display_cancel_read(display);
                        return -1;
                }
@@ -631,7 +728,6 @@
 }
 
 static int wlrun(struct config cfg) {
-
        // Initialize defaults
        struct context ctx = {
                .sun = { 0 },
@@ -639,8 +735,11 @@
                .state = STATE_INITIAL,
                .config = cfg,
        };
+
        if (!cfg.manual_time) {
                ctx.longitude_time_offset = 
longitude_time_offset(cfg.longitude);
+       } else {
+               ctx.longitude_time_offset = -get_timezone();
        }
 
        wl_list_init(&ctx.outputs);
@@ -659,14 +758,22 @@
        wl_registry_add_listener(registry, &registry_listener, &ctx);
        wl_display_roundtrip(display);
 
-       if (gamma_control_manager == NULL) {
+       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;
        }
 
        struct output *output;
        wl_list_for_each(output, &ctx.outputs, link) {
-               setup_output(output);
+               if (ctx.config.output_names.len > 0) {
+                       setup_xdg_output(&ctx, output);
+               }
+               setup_gamma_control(&ctx, output);
        }
        wl_display_roundtrip(display);
 
@@ -689,11 +796,11 @@
                        if ((temp = get_temperature(&ctx, now)) != old_temp) {
                                old_temp = temp;
                                ctx.new_output = false;
-                               set_temperature(&ctx.outputs, temp,
-                                               ctx.config.gamma);
+                               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);
                }
        }
@@ -707,13 +814,16 @@
        if (strptime(s, "%H:%M", &tm) == NULL) {
                return -1;
        }
-       *time = tm.tm_hour * 3600 + tm.tm_min * 60 + timezone;
+       *time = tm.tm_hour * 3600 + tm.tm_min * 60;
        return 0;
 }
 
 static const char usage[] = "usage: %s [options]\n"
 "  -h             show this help message\n"
 "  -v             show the version number\n"
+"  -o <output>    name of output (display) to use,\n"
+"                 by default all outputs are used\n"
+"                 can be specified multiple times\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"
@@ -736,10 +846,15 @@
                .low_temp = 4000,
                .gamma = 1.0,
        };
+       str_vec_init(&config.output_names);
 
+       int ret = EXIT_FAILURE;
        int opt;
-       while ((opt = getopt(argc, argv, "hvt:T:l:L:S:s:d:g:")) != -1) {
+       while ((opt = getopt(argc, argv, "hvo:t:T:l:L:S:s:d:g:")) != -1) {
                switch (opt) {
+                       case 'o':
+                               str_vec_push(&config.output_names, optarg);
+                               break;
                        case 't':
                                config.low_temp = strtol(optarg, NULL, 10);
                                break;
@@ -755,14 +870,14 @@
                        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;
+                                       goto end;
                                }
                                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;
+                                       goto end;
                                }
                                config.manual_time = true;
                                break;
@@ -774,38 +889,42 @@
                                break;
                        case 'v':
                                printf("wlsunset version %s\n", 
WLSUNSET_VERSION);
-                               return EXIT_SUCCESS;
+                               ret = EXIT_SUCCESS;
+                               goto end;
                        case 'h':
+                               ret = EXIT_SUCCESS;
                        default:
                                fprintf(stderr, usage, argv[0]);
-                               return opt == 'h' ? EXIT_SUCCESS : EXIT_FAILURE;
+                               goto end;
                }
        }
 
        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 EXIT_FAILURE;
+               goto end;
        }
        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;
+                       goto end;
                }
        } 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;
+                       goto end;
                }
                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;
+                       goto end;
                }
                config.longitude = RADIANS(config.longitude);
        }
-
-       return wlrun(config);
+       ret = wlrun(config);
+end:
+       str_vec_free(&config.output_names);
+       return ret;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlsunset-0.2.0/meson.build 
new/wlsunset-0.3.0/meson.build
--- old/wlsunset-0.2.0/meson.build      2021-04-25 22:56:30.000000000 +0200
+++ new/wlsunset-0.3.0/meson.build      2023-05-24 16:47:43.000000000 +0200
@@ -1,9 +1,9 @@
 project(
        'wlsunset',
        'c',
-       version: '0.2.0',
+       version: '0.3.0',
        license: 'MIT',
-       meson_version: '>=0.53.0',
+       meson_version: '>=0.56.0',
        default_options: [
                'c_std=c11',
                'warning_level=3',
@@ -26,8 +26,6 @@
                '-Wno-unused-command-line-argument',
                '-Wvla',
                '-Wl,--exclude-libs=ALL',
-               '-D_USE_MATH_DEFINES',
-               '-D_XOPEN_SOURCE=700',
                '-DWLSUNSET_VERSION="@0@"'.format(meson.project_version()),
        ],
        language: 'c',
@@ -37,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')]
-protocols_headers = 
[scanner_client_header.process('wlr-gamma-control-unstable-v1.xml')]
+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')]
 
 wl_client = dependency('wayland-client')
 wl_protocols = dependency('wayland-protocols')
@@ -51,21 +49,18 @@
 
 executable(
        'wlsunset',
-       ['main.c', 'color_math.c'],
+       ['main.c', 'color_math.c', 'str_vec.c'],
        dependencies: [wl_client, protocols_dep, m, rt],
        install: true,
 )
 
-scdoc = dependency('scdoc', required: get_option('man-pages'), version: '>= 
1.9.7')
+scdoc = dependency('scdoc', required: get_option('man-pages'), version: '>= 
1.9.7', native: true)
 
 if scdoc.found()
-       sh = find_program('sh')
-
-       man_pages = ['wlsunset.1.scd']
-
+       scdoc_prog = find_program(scdoc.get_variable(pkgconfig: 'scdoc'), 
native: true)
        mandir = get_option('mandir')
 
-       foreach src : man_pages
+       foreach src : ['wlsunset.1.scd']
                topic = src.split('.')[0]
                section = src.split('.')[1]
                output = '@0@.@1@'.format(topic, section)
@@ -75,7 +70,7 @@
                        input: src,
                        output: output,
                        command: [
-                               sh, '-c', '@0@ < @INPUT@ > 
@1@'.format(scdoc.get_pkgconfig_variable('scdoc'), output)
+                               'sh', '-c', '@0@ < @INPUT@ > 
@1@'.format(scdoc_prog.full_path(), output)
                        ],
                        install: true,
                        install_dir: '@0@/man@1@'.format(mandir, section)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlsunset-0.2.0/str_vec.c new/wlsunset-0.3.0/str_vec.c
--- old/wlsunset-0.2.0/str_vec.c        1970-01-01 01:00:00.000000000 +0100
+++ new/wlsunset-0.3.0/str_vec.c        2023-05-24 16:47:43.000000000 +0200
@@ -0,0 +1,30 @@
+#define _XOPEN_SOURCE 700
+#include <stdlib.h>
+#include <string.h>
+
+#include "str_vec.h"
+
+void str_vec_init(struct str_vec *vec) {
+       vec->data = NULL;
+       vec->len = 0;
+}
+
+void str_vec_push(struct str_vec *vec, const char *new_str) {
+       ++vec->len;
+       vec->data = realloc(vec->data, vec->len * sizeof(char*));
+       vec->data[vec->len - 1] = strdup(new_str);
+}
+
+void str_vec_free(struct str_vec *vec) {
+       if (vec == NULL) {
+               return;
+       }
+       for (size_t i = 0; i < vec->len; ++i) {
+               if (vec->data[i] != NULL) {
+                       free(vec->data[i]);
+               }
+       }
+       free(vec->data);
+       vec->data = NULL;
+       vec->len = 0;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlsunset-0.2.0/str_vec.h new/wlsunset-0.3.0/str_vec.h
--- old/wlsunset-0.2.0/str_vec.h        1970-01-01 01:00:00.000000000 +0100
+++ new/wlsunset-0.3.0/str_vec.h        2023-05-24 16:47:43.000000000 +0200
@@ -0,0 +1,15 @@
+#ifndef STR_VEC_H
+#define STR_VEC_H
+
+#include <stddef.h>
+
+struct str_vec {
+       char **data;
+       size_t len;
+};
+
+void str_vec_init(struct str_vec *vec);
+void str_vec_push(struct str_vec *vec, const char *new_str);
+void str_vec_free(struct str_vec *vec);
+
+#endif //STR_VEC_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wlsunset-0.2.0/xdg-output-unstable-v1.xml 
new/wlsunset-0.3.0/xdg-output-unstable-v1.xml
--- old/wlsunset-0.2.0/xdg-output-unstable-v1.xml       1970-01-01 
01:00:00.000000000 +0100
+++ new/wlsunset-0.3.0/xdg-output-unstable-v1.xml       2023-05-24 
16:47:43.000000000 +0200
@@ -0,0 +1,220 @@
+<?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