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, ®istry_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>
