diff options
Diffstat (limited to 'x11-misc')
-rw-r--r-- | x11-misc/redshift/Manifest | 1 | ||||
-rw-r--r-- | x11-misc/redshift/files/redshift-wlroots-gamma.patch | 920 | ||||
-rw-r--r-- | x11-misc/redshift/metadata.xml | 10 | ||||
-rw-r--r-- | x11-misc/redshift/redshift-1.12-r4.ebuild | 91 |
4 files changed, 1022 insertions, 0 deletions
diff --git a/x11-misc/redshift/Manifest b/x11-misc/redshift/Manifest new file mode 100644 index 0000000..e439764 --- /dev/null +++ b/x11-misc/redshift/Manifest @@ -0,0 +1 @@ +DIST redshift-1.12.tar.gz 659019 BLAKE2B 09339a57fee192e3428ba4387cbea498f2f9f97eb75a418588cdda3289cfa7b7fada4cb299e983e9e6d2ffe3822c8235082e67bdfa542716b6dee9fc853a8dc1 SHA512 6763f6964b577fc146191af1c67a283a60df5bbdd3a74bfc94f66d5f9f3bef8835a479c6ec8a648b650b83a0e245928884a0f628606ace8c3f58d8319d35036f diff --git a/x11-misc/redshift/files/redshift-wlroots-gamma.patch b/x11-misc/redshift/files/redshift-wlroots-gamma.patch new file mode 100644 index 0000000..b1239c3 --- /dev/null +++ b/x11-misc/redshift/files/redshift-wlroots-gamma.patch @@ -0,0 +1,920 @@ +diff --git a/configure.ac b/configure.ac +index b4116262..8347dcc4 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -68,6 +68,10 @@ PKG_CHECK_MODULES([XCB], [xcb], [have_xcb=yes], [have_xcb=no]) + PKG_CHECK_MODULES([XCB_RANDR], [xcb-randr], + [have_xcb_randr=yes], [have_xcb_randr=no]) + ++PKG_CHECK_MODULES([WAYLAND], [wayland-client wayland-scanner >= 1.15.0], ++ [have_wayland=yes], [have_wayland=no]) ++PKG_CHECK_VAR(WAYLAND_SCANNER, wayland-scanner, wayland_scanner) ++ + PKG_CHECK_MODULES([GLIB], [glib-2.0 gobject-2.0], [have_glib=yes], [have_glib=no]) + PKG_CHECK_MODULES([GEOCLUE2], [glib-2.0 gio-2.0 >= 2.26], [have_geoclue2=yes], [have_geoclue2=no]) + +@@ -124,6 +128,30 @@ AS_IF([test "x$enable_drm" != xno], [ + ]) + AM_CONDITIONAL([ENABLE_DRM], [test "x$enable_drm" = xyes]) + ++# Check Wayland method ++AC_MSG_CHECKING([whether to enable Wayland method]) ++AC_ARG_ENABLE([wayland], [AC_HELP_STRING([--enable-wayland], ++ [enable Wayland method])], ++ [enable_wayland=$enableval],[enable_wayland=maybe]) ++AS_IF([test "x$enable_wayland" != xno], [ ++ AS_IF([test $have_wayland = yes], [ ++ AC_DEFINE([ENABLE_WAYLAND], 1, ++ [Define to 1 to enable Wayland method]) ++ AC_MSG_RESULT([yes]) ++ enable_wayland=yes ++ ], [ ++ AC_MSG_RESULT([missing dependencies]) ++ AS_IF([test "x$enable_wayland" = xyes], [ ++ AC_MSG_ERROR([missing dependencies for Wayland method]) ++ ]) ++ enable_wayland=no ++ ]) ++], [ ++ AC_MSG_RESULT([no]) ++ enable_wayland=no ++]) ++AM_CONDITIONAL([ENABLE_WAYLAND], [test "x$enable_wayland" = xyes]) ++ + # Check RANDR method + AC_MSG_CHECKING([whether to enable RANDR method]) + AC_ARG_ENABLE([randr], [AC_HELP_STRING([--enable-randr], +@@ -376,6 +404,7 @@ echo " + + Adjustment methods: + DRM: ${enable_drm} ++ Wayland: ${enable_wayland} + RANDR: ${enable_randr} + VidMode: ${enable_vidmode} + Quartz (macOS): ${enable_quartz} +diff --git a/po/POTFILES.in b/po/POTFILES.in +index 5ef8dacc..1d255600 100644 +--- a/po/POTFILES.in ++++ b/po/POTFILES.in +@@ -9,6 +9,7 @@ src/options.c + src/config-ini.c + + src/gamma-drm.c ++src/gamma-wl.c + src/gamma-randr.c + src/gamma-vidmode.c + src/gamma-quartz.c +diff --git a/src/Makefile.am b/src/Makefile.am +index 8aa96ead..4f1acf4f 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -23,6 +23,7 @@ redshift_SOURCES = \ + + EXTRA_redshift_SOURCES = \ + gamma-drm.c gamma-drm.h \ ++ gamma-wl.c gamma-wl.h \ + gamma-randr.c gamma-randr.h \ + gamma-vidmode.c gamma-vidmode.h \ + gamma-quartz.c gamma-quartz.h \ +@@ -43,6 +44,27 @@ redshift_LDADD += \ + $(DRM_LIBS) $(DRM_CFLAGS) + endif + ++if ENABLE_WAYLAND ++redshift_SOURCES += gamma-wl.c gamma-wl.h os-compatibility.c os-compatibility.h ++ ++AM_CFLAGS += $(WAYLAND_CFLAGS) ++ ++redshift_LDADD += \ ++ $(WAYLAND_LIBS) $(WAYLAND_CFLAGS) ++ ++nodist_redshift_SOURCES = \ ++ gamma-control-client-protocol.h \ ++ gamma-control-protocol.c \ ++ orbital-authorizer-protocol.c \ ++ orbital-authorizer-client-protocol.h ++ ++BUILT_SOURCES = \ ++ gamma-control-protocol.c \ ++ gamma-control-client-protocol.h \ ++ orbital-authorizer-protocol.c \ ++ orbital-authorizer-client-protocol.h ++endif ++ + if ENABLE_RANDR + redshift_SOURCES += gamma-randr.c gamma-randr.h + AM_CFLAGS += $(XCB_CFLAGS) $(XCB_RANDR_CFLAGS) +@@ -103,3 +125,11 @@ endif + + .rc.o: + $(AM_V_GEN)$(WINDRES) -I$(top_builddir) -i $< -o $@ ++ ++%-protocol.c : $(srcdir)/%.xml ++ $(AM_V_GEN)$(MKDIR_P) $(dir $@) && $(WAYLAND_SCANNER) private-code < $< > $@ ++ ++%-client-protocol.h : $(srcdir)/%.xml ++ $(AM_V_GEN)$(MKDIR_P) $(dir $@) && $(WAYLAND_SCANNER) client-header < $< > $@ ++ ++CLEANFILES = *-protocol.c *-client-protocol.h +diff --git a/src/gamma-control.xml b/src/gamma-control.xml +new file mode 100644 +index 00000000..ad71a15c +--- /dev/null ++++ b/src/gamma-control.xml +@@ -0,0 +1,126 @@ ++<?xml version="1.0" encoding="UTF-8"?> ++<protocol name="wlr_gamma_control_unstable_v1"> ++ <copyright> ++ Copyright © 2015 Giulio camuffo ++ Copyright © 2018 Simon Ser ++ ++ Permission to use, copy, modify, distribute, and sell this ++ software and its documentation for any purpose is hereby granted ++ without fee, provided that the above copyright notice appear in ++ all copies and that both that copyright notice and this permission ++ notice appear in supporting documentation, and that the name of ++ the copyright holders not be used in advertising or publicity ++ pertaining to distribution of the software without specific, ++ written prior permission. The copyright holders make no ++ representations about the suitability of this software for any ++ purpose. It is provided "as is" without express or implied ++ warranty. ++ ++ THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS ++ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND ++ FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY ++ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN ++ AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ++ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF ++ THIS SOFTWARE. ++ </copyright> ++ ++ <description summary="manage gamma tables of outputs"> ++ This protocol allows a privileged client to set the gamma tables for ++ outputs. ++ ++ 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="zwlr_gamma_control_manager_v1" version="1"> ++ <description summary="manager to create per-output gamma controls"> ++ This interface is a manager that allows creating per-output gamma ++ controls. ++ </description> ++ ++ <request name="get_gamma_control"> ++ <description summary="get a gamma control for an output"> ++ Create a gamma control that can be used to adjust gamma tables for the ++ provided output. ++ </description> ++ <arg name="id" type="new_id" interface="zwlr_gamma_control_v1"/> ++ <arg name="output" type="object" interface="wl_output"/> ++ </request> ++ ++ <request name="destroy" type="destructor"> ++ <description summary="destroy the manager"> ++ All objects created by the manager will still remain valid, until their ++ appropriate destroy request has been called. ++ </description> ++ </request> ++ </interface> ++ ++ <interface name="zwlr_gamma_control_v1" version="1"> ++ <description summary="adjust gamma tables for an output"> ++ This interface allows a client to adjust gamma tables for a particular ++ output. ++ ++ The client will receive the gamma size, and will then be able to set gamma ++ tables. At any time the compositor can send a failed event indicating that ++ this object is no longer valid. ++ ++ There must always be at most one gamma control object per output, which ++ has exclusive access to this particular output. When the gamma control ++ object is destroyed, the gamma table is restored to its original value. ++ </description> ++ ++ <event name="gamma_size"> ++ <description summary="size of gamma ramps"> ++ Advertise the size of each gamma ramp. ++ ++ This event is sent immediately when the gamma control object is created. ++ </description> ++ <arg name="size" type="uint"/> ++ </event> ++ ++ <enum name="error"> ++ <entry name="invalid_gamma" value="1" summary="invalid gamma tables"/> ++ </enum> ++ ++ <request name="set_gamma"> ++ <description summary="set the gamma table"> ++ Set the gamma table. The file descriptor can be memory-mapped to provide ++ the raw gamma table, which contains successive gamma ramps for the red, ++ green and blue channels. Each gamma ramp is an array of 16-byte unsigned ++ integers which has the same length as the gamma size. ++ ++ The file descriptor data must have the same length as three times the ++ gamma size. ++ </description> ++ <arg name="fd" type="fd" summary="gamma table file descriptor"/> ++ </request> ++ ++ <event name="failed"> ++ <description summary="object no longer valid"> ++ This event indicates that the gamma control is no longer valid. This ++ can happen for a number of reasons, including: ++ - The output doesn't support gamma tables ++ - Setting the gamma tables failed ++ - Another client already has exclusive gamma control for this output ++ - The compositor has transfered gamma control to another client ++ ++ Upon receiving this event, the client should destroy this object. ++ </description> ++ </event> ++ ++ <request name="destroy" type="destructor"> ++ <description summary="destroy this control"> ++ Destroys the gamma control object. If the object is still valid, this ++ restores the original gamma tables. ++ </description> ++ </request> ++ </interface> ++</protocol> +diff --git a/src/gamma-wl.c b/src/gamma-wl.c +new file mode 100644 +index 00000000..8efa1c2e +--- /dev/null ++++ b/src/gamma-wl.c +@@ -0,0 +1,365 @@ ++/* gamma-wl.c -- Wayland gamma adjustment header ++ This file is part of Redshift. ++ ++ Redshift is free software: you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation, either version 3 of the License, or ++ (at your option) any later version. ++ ++ Redshift is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with Redshift. If not, see <http://www.gnu.org/licenses/>. ++ ++ Copyright (c) 2015 Giulio Camuffo <giuliocamuffo@gmail.com> ++*/ ++ ++#include <stdio.h> ++#include <stdlib.h> ++#include <stdint.h> ++#include <string.h> ++#include <sys/mman.h> ++#include <sys/types.h> ++#include <sys/stat.h> ++#include <fcntl.h> ++#include <unistd.h> ++ ++#ifdef ENABLE_NLS ++# include <libintl.h> ++# define _(s) gettext(s) ++#else ++# define _(s) s ++#endif ++ ++#include "gamma-wl.h" ++#include "os-compatibility.h" ++#include "colorramp.h" ++ ++#include "gamma-control-client-protocol.h" ++#include "orbital-authorizer-client-protocol.h" ++ ++typedef struct { ++ struct wl_display *display; ++ struct wl_registry *registry; ++ struct wl_callback *callback; ++ uint32_t gamma_control_manager_id; ++ struct zwlr_gamma_control_manager_v1 *gamma_control_manager; ++ int num_outputs; ++ struct output *outputs; ++ int authorized; ++} wayland_state_t; ++ ++struct output { ++ uint32_t global_id; ++ struct wl_output *output; ++ struct zwlr_gamma_control_v1 *gamma_control; ++ uint32_t gamma_size; ++}; ++ ++static int ++wayland_init(wayland_state_t **state) ++{ ++ /* Initialize state. */ ++ *state = malloc(sizeof(**state)); ++ if (*state == NULL) return -1; ++ ++ memset(*state, 0, sizeof **state); ++ return 0; ++} ++ ++static void ++authorizer_feedback_granted(void *data, struct orbital_authorizer_feedback *feedback) ++{ ++ wayland_state_t *state = data; ++ state->authorized = 1; ++} ++ ++static void ++authorizer_feedback_denied(void *data, struct orbital_authorizer_feedback *feedback) ++{ ++ fprintf(stderr, _("Fatal: redshift was not authorized to bind the 'zwlr_gamma_control_manager_v1' interface.\n")); ++ exit(EXIT_FAILURE); ++} ++ ++static const struct orbital_authorizer_feedback_listener authorizer_feedback_listener = { ++ authorizer_feedback_granted, ++ authorizer_feedback_denied ++}; ++ ++static void ++registry_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version) ++{ ++ wayland_state_t *state = data; ++ ++ if (strcmp(interface, "zwlr_gamma_control_manager_v1") == 0) { ++ state->gamma_control_manager_id = id; ++ state->gamma_control_manager = wl_registry_bind(registry, id, &zwlr_gamma_control_manager_v1_interface, 1); ++ } else if (strcmp(interface, "wl_output") == 0) { ++ state->num_outputs++; ++ if (!(state->outputs = realloc(state->outputs, state->num_outputs * sizeof(struct output)))) { ++ fprintf(stderr, _("Failed to allcate memory\n")); ++ return; ++ } ++ ++ struct output *output = &state->outputs[state->num_outputs - 1]; ++ output->global_id = id; ++ output->output = wl_registry_bind(registry, id, &wl_output_interface, 1); ++ output->gamma_control = NULL; ++ } else if (strcmp(interface, "orbital_authorizer") == 0) { ++ struct wl_event_queue *queue = wl_display_create_queue(state->display); ++ ++ struct orbital_authorizer *auth = wl_registry_bind(registry, id, &orbital_authorizer_interface, 1u); ++ wl_proxy_set_queue((struct wl_proxy *)auth, queue); ++ ++ struct orbital_authorizer_feedback *feedback = orbital_authorizer_authorize(auth, "zwlr_gamma_control_manager_v1"); ++ orbital_authorizer_feedback_add_listener(feedback, &authorizer_feedback_listener, state); ++ ++ int ret = 0; ++ while (!state->authorized && ret >= 0) { ++ ret = wl_display_dispatch_queue(state->display, queue); ++ } ++ ++ orbital_authorizer_feedback_destroy(feedback); ++ orbital_authorizer_destroy(auth); ++ wl_event_queue_destroy(queue); ++ } ++} ++ ++static void ++registry_global_remove(void *data, struct wl_registry *registry, uint32_t id) ++{ ++ wayland_state_t *state = data; ++ ++ if (state->gamma_control_manager_id == id) { ++ fprintf(stderr, _("The zwlr_gamma_control_manager_v1 was removed\n")); ++ exit(EXIT_FAILURE); ++ } ++ ++ for (int i = 0; i < state->num_outputs; ++i) { ++ struct output *output = &state->outputs[i]; ++ if (output->global_id == id) { ++ if (output->gamma_control) { ++ zwlr_gamma_control_v1_destroy(output->gamma_control); ++ output->gamma_control = NULL; ++ } ++ wl_output_destroy(output->output); ++ ++ /* If the removed output is not the last one in the array move the last one ++ * in the now empty slot. Then shrink the array */ ++ if (i < --state->num_outputs) { ++ memcpy(output, &state->outputs[state->num_outputs], sizeof(struct output)); ++ } ++ state->outputs = realloc(state->outputs, state->num_outputs * sizeof(struct output)); ++ ++ return; ++ } ++ } ++} ++ ++static const struct wl_registry_listener registry_listener = { ++ registry_global, ++ registry_global_remove ++}; ++ ++static void ++gamma_control_gamma_size(void *data, struct zwlr_gamma_control_v1 *control, uint32_t size) ++{ ++ struct output *output = data; ++ output->gamma_size = size; ++} ++ ++static void ++gamma_control_failed(void *data, struct zwlr_gamma_control_v1 *control) ++{ ++} ++ ++ ++static const struct zwlr_gamma_control_v1_listener gamma_control_listener = { ++ gamma_control_gamma_size, ++ gamma_control_failed ++}; ++ ++static int ++wayland_start(wayland_state_t *state) ++{ ++ state->display = wl_display_connect(NULL); ++ if (!state->display) { ++ fputs(_("Could not connect to wayland display, exiting.\n"), stderr); ++ return -1; ++ } ++ state->registry = wl_display_get_registry(state->display); ++ ++ wl_registry_add_listener(state->registry, ®istry_listener, state); ++ ++ wl_display_roundtrip(state->display); ++ if (!state->gamma_control_manager) { ++ return -1; ++ } ++ if (state->num_outputs > 0 && !state->outputs) { ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static void ++wayland_restore(wayland_state_t *state) ++{ ++ for (int i = 0; i < state->num_outputs; ++i) { ++ struct output *output = &state->outputs[i]; ++ if (output->gamma_control) { ++ zwlr_gamma_control_v1_destroy(output->gamma_control); ++ output->gamma_control = NULL; ++ } ++ } ++ wl_display_flush(state->display); ++} ++ ++static void ++wayland_free(wayland_state_t *state) ++{ ++ int ret = 0; ++ /* Wait for the sync callback to destroy everything, otherwise ++ * we could destroy the gamma control before gamma has been set */ ++ while (state->callback && ret >= 0) { ++ ret = wl_display_dispatch(state->display); ++ } ++ if (state->callback) { ++ fprintf(stderr, _("Ignoring error on wayland connection while waiting to disconnect: %d\n"), ret); ++ wl_callback_destroy(state->callback); ++ } ++ ++ for (int i = 0; i < state->num_outputs; ++i) { ++ struct output *output = &state->outputs[i]; ++ if (output->gamma_control) { ++ zwlr_gamma_control_v1_destroy(output->gamma_control); ++ output->gamma_control = NULL; ++ } ++ wl_output_destroy(output->output); ++ } ++ ++ if (state->gamma_control_manager) { ++ zwlr_gamma_control_manager_v1_destroy(state->gamma_control_manager); ++ } ++ if (state->registry) { ++ wl_registry_destroy(state->registry); ++ } ++ if (state->display) { ++ wl_display_disconnect(state->display); ++ } ++ ++ free(state); ++} ++ ++static void ++wayland_print_help(FILE *f) ++{ ++ fputs(_("Adjust gamma ramps with a Wayland compositor.\n"), f); ++ fputs("\n", f); ++} ++ ++static int ++wayland_set_option(wayland_state_t *state, const char *key, const char *value) ++{ ++ return 0; ++} ++ ++static void ++callback_done(void *data, struct wl_callback *cb, uint32_t t) ++{ ++ wayland_state_t *state = data; ++ state->callback = NULL; ++ wl_callback_destroy(cb); ++} ++ ++static const struct wl_callback_listener callback_listener = { ++ callback_done ++}; ++ ++static int ++wayland_set_temperature(wayland_state_t *state, const color_setting_t *setting) ++{ ++ int ret = 0, roundtrip = 0; ++ ++ /* We wait for the sync callback to throttle a bit and not send more ++ * requests than the compositor can manage, otherwise we'd get disconnected. ++ * This also allows us to dispatch other incoming events such as ++ * wl_registry.global_remove. */ ++ while (state->callback && ret >= 0) { ++ ret = wl_display_dispatch(state->display); ++ } ++ if (ret < 0) { ++ fprintf(stderr, _("The Wayland connection experienced a fatal error: %d\n"), ret); ++ return ret; ++ } ++ ++ for (int i = 0; i < state->num_outputs; ++i) { ++ struct output *output = &state->outputs[i]; ++ if (!output->gamma_control) { ++ output->gamma_control = zwlr_gamma_control_manager_v1_get_gamma_control(state->gamma_control_manager, output->output); ++ zwlr_gamma_control_v1_add_listener(output->gamma_control, &gamma_control_listener, output); ++ roundtrip = 1; ++ } ++ } ++ if (roundtrip) { ++ wl_display_roundtrip(state->display); ++ } ++ ++ for (int i = 0; i < state->num_outputs; ++i) { ++ struct output *output = &state->outputs[i]; ++ int size = output->gamma_size; ++ size_t ramp_bytes = size * sizeof(uint16_t); ++ size_t total_bytes = ramp_bytes * 3; ++ ++ int fd = os_create_anonymous_file(total_bytes); ++ if (fd < 0) { ++ return -1; ++ } ++ ++ void *ptr = mmap(NULL, total_bytes, ++ PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); ++ if (ptr == MAP_FAILED) { ++ close(fd); ++ return -1; ++ } ++ ++ uint16_t *r_gamma = ptr; ++ uint16_t *g_gamma = ptr + ramp_bytes; ++ uint16_t *b_gamma = ptr + 2 * ramp_bytes; ++ ++ /* Initialize gamma ramps to pure state */ ++ for (int i = 0; i < size; i++) { ++ uint16_t value = (double)i / size * (UINT16_MAX+1); ++ r_gamma[i] = value; ++ g_gamma[i] = value; ++ b_gamma[i] = value; ++ } ++ ++ colorramp_fill(r_gamma, g_gamma, b_gamma, size, setting); ++ munmap(ptr, size); ++ ++ zwlr_gamma_control_v1_set_gamma(output->gamma_control, fd); ++ close(fd); ++ } ++ ++ state->callback = wl_display_sync(state->display); ++ wl_callback_add_listener(state->callback, &callback_listener, state); ++ wl_display_flush(state->display); ++ ++ return 0; ++} ++ ++const gamma_method_t wl_gamma_method = { ++ "wayland", ++ 1, ++ (gamma_method_init_func *) wayland_init, ++ (gamma_method_start_func *) wayland_start, ++ (gamma_method_free_func *) wayland_free, ++ (gamma_method_print_help_func *) wayland_print_help, ++ (gamma_method_set_option_func *) wayland_set_option, ++ (gamma_method_restore_func *) wayland_restore, ++ (gamma_method_set_temperature_func *) wayland_set_temperature, ++}; +diff --git a/src/gamma-wl.h b/src/gamma-wl.h +new file mode 100644 +index 00000000..333e99b2 +--- /dev/null ++++ b/src/gamma-wl.h +@@ -0,0 +1,32 @@ ++/* gamma-wl.h -- Wayland gamma adjustment header ++ This file is part of Redshift. ++ ++ Redshift is free software: you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation, either version 3 of the License, or ++ (at your option) any later version. ++ ++ Redshift is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with Redshift. If not, see <http://www.gnu.org/licenses/>. ++ ++ Copyright (c) 2015 Giulio Camuffo <giuliocamuffo@gmail.com> ++*/ ++ ++#ifndef REDSHIFT_GAMMA_WAYLAND_H ++#define REDSHIFT_GAMMA_WAYLAND_H ++ ++#include <stdint.h> ++ ++#include <wayland-client.h> ++ ++#include "redshift.h" ++ ++extern const gamma_method_t wl_gamma_method; ++ ++ ++#endif /* ! REDSHIFT_GAMMA_DRM_H */ +diff --git a/src/orbital-authorizer.xml b/src/orbital-authorizer.xml +new file mode 100644 +index 00000000..bccaa081 +--- /dev/null ++++ b/src/orbital-authorizer.xml +@@ -0,0 +1,61 @@ ++<protocol name="orbital_authorizer"> ++ ++ <interface name="orbital_authorizer" version="1"> ++ <description summary="authorize clients to use certain interfaces"> ++ The orbital_authorizer global interface allows clients to ++ ask the compositor the authorization to bind certain restricted ++ global interfaces. ++ Any client that aims to bind restricted interfaces should first ++ request the authorization by using this interface. Failing to do ++ so will result in the compositor sending a protocol error to the ++ client when it binds the restricted interface. ++ ++ The list of restricted interfaces is compositor dependant, but must ++ not include the core interfaces defined in wayland.xml. ++ </description> ++ ++ <request name="destroy" type="destructor"> ++ <description summary="destroy this orbital_authorizer object"/> ++ </request> ++ ++ <request name="authorize"> ++ <description summary="authorize a global interface"> ++ The authorize request allows the client to ask the compositor the ++ authorization to bind a restricted global interface. The newly ++ created orbital_authorizer_feedback will be invalid after the ++ compositor send either the granted or denied event so the client ++ must destroy it immediately after. ++ </description> ++ <arg name="id" type="new_id" interface="orbital_authorizer_feedback" summary="the new feedback object"/> ++ <arg name="global" type="string" summary="the global interface the client wants to bind"/> ++ </request> ++ </interface> ++ ++ <interface name="orbital_authorizer_feedback" version="1"> ++ <description summary="feedback for an authorization request"> ++ The orbital_authorizer_feedback interface is used by requesting ++ an authorization with the orbital_authorizer.authorize request. ++ The compositor will send either the granted or denied event based ++ on the system and user configuration. How the authorization process ++ works is compositor specific, but a compositor is allowed to ask ++ for user input, so the response for an authorization request may ++ come after some time. ++ </description> ++ ++ <event name="granted"> ++ <description summary="the authorization was granted"> ++ The authorization was granted. The client can now bind the restricted ++ interface. ++ </description> ++ </event> ++ ++ <event name="denied"> ++ <description summary="the authorization was denied"> ++ The authorization was denied. The client is not allowed to bind the ++ restricted interface and trying to do so will trigger a protocol ++ error killing the client. ++ </description> ++ </event> ++ </interface> ++ ++</protocol> +diff --git a/src/os-compatibility.c b/src/os-compatibility.c +new file mode 100644 +index 00000000..32a9109e +--- /dev/null ++++ b/src/os-compatibility.c +@@ -0,0 +1,148 @@ ++/* ++ * Copyright © 2012 Collabora, Ltd. ++ * ++ * 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. ++ */ ++ ++#define _POSIX_C_SOURCE 200809L ++#include <errno.h> ++#include <fcntl.h> ++#include <stdlib.h> ++#include <string.h> ++#include <sys/socket.h> ++#include <sys/stat.h> ++#include <sys/types.h> ++#include <unistd.h> ++#include "os-compatibility.h" ++ ++int os_fd_set_cloexec(int fd) { ++ if (fd == -1) { ++ return -1; ++ } ++ ++ long flags = fcntl(fd, F_GETFD); ++ if (flags == -1) { ++ return -1; ++ } ++ ++ if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) { ++ return -1; ++ } ++ ++ return 0; ++} ++ ++int set_cloexec_or_close(int fd) { ++ if (os_fd_set_cloexec(fd) != 0) { ++ close(fd); ++ return -1; ++ } ++ return fd; ++} ++ ++int create_tmpfile_cloexec(char *tmpname) { ++ int fd; ++ mode_t prev_umask = umask(0066); ++#ifdef HAVE_MKOSTEMP ++ fd = mkostemp(tmpname, O_CLOEXEC); ++ if (fd >= 0) { ++ unlink(tmpname); ++ } ++#else ++ fd = mkstemp(tmpname); ++ if (fd >= 0) { ++ fd = set_cloexec_or_close(fd); ++ unlink(tmpname); ++ } ++#endif ++ umask(prev_umask); ++ ++ return fd; ++} ++ ++/* ++ * Create a new, unique, anonymous file of the given size, and ++ * return the file descriptor for it. The file descriptor is set ++ * CLOEXEC. The file is immediately suitable for mmap()'ing ++ * the given size at offset zero. ++ * ++ * The file should not have a permanent backing store like a disk, ++ * but may have if XDG_RUNTIME_DIR is not properly implemented in OS. ++ * ++ * The file name is deleted from the file system. ++ * ++ * The file is suitable for buffer sharing between processes by ++ * transmitting the file descriptor over Unix sockets using the ++ * SCM_RIGHTS methods. ++ * ++ * If the C library implements posix_fallocate(), it is used to ++ * guarantee that disk space is available for the file at the ++ * given size. If disk space is insufficient, errno is set to ENOSPC. ++ * If posix_fallocate() is not supported, program may receive ++ * SIGBUS on accessing mmap()'ed file contents instead. ++ */ ++int os_create_anonymous_file(off_t size) { ++ static const char template[] = "/redshift-shared-XXXXXX"; ++ ++ const char *path = getenv("XDG_RUNTIME_DIR"); ++ if (!path) { ++ errno = ENOENT; ++ return -1; ++ } ++ ++ char *name = malloc(strlen(path) + sizeof(template)); ++ if (!name) { ++ return -1; ++ } ++ ++ strcpy(name, path); ++ strcat(name, template); ++ ++ int fd = create_tmpfile_cloexec(name); ++ free(name); ++ if (fd < 0) { ++ return -1; ++ } ++ ++#ifdef WLR_HAS_POSIX_FALLOCATE ++ int ret; ++ do { ++ ret = posix_fallocate(fd, 0, size); ++ } while (ret == EINTR); ++ if (ret != 0) { ++ close(fd); ++ errno = ret; ++ return -1; ++ } ++#else ++ int ret; ++ do { ++ ret = ftruncate(fd, size); ++ } while (ret < 0 && errno == EINTR); ++ if (ret < 0) { ++ close(fd); ++ return -1; ++ } ++#endif ++ ++ return fd; ++} +diff --git a/src/os-compatibility.h b/src/os-compatibility.h +new file mode 100644 +index 00000000..2038025e +--- /dev/null ++++ b/src/os-compatibility.h +@@ -0,0 +1,9 @@ ++#ifndef UTIL_OS_COMPATIBILITY_H ++#define UTIL_OS_COMPATIBILITY_H ++ ++int os_fd_set_cloexec(int fd); ++int set_cloexec_or_close(int fd); ++int create_tmpfile_cloexec(char *tmpname); ++int os_create_anonymous_file(off_t size); ++ ++#endif +diff --git a/src/redshift.c b/src/redshift.c +index e0221d5e..953d79e0 100644 +--- a/src/redshift.c ++++ b/src/redshift.c +@@ -94,6 +94,10 @@ int poll(struct pollfd *fds, int nfds, int timeout) { abort(); return -1; } + # include "gamma-w32gdi.h" + #endif + ++#ifdef ENABLE_WAYLAND ++# include "gamma-wl.h" ++#endif ++ + + #include "location-manual.h" + +@@ -902,6 +906,9 @@ main(int argc, char *argv[]) + + /* List of gamma methods. */ + const gamma_method_t gamma_methods[] = { ++#ifdef ENABLE_WAYLAND ++ wl_gamma_method, ++#endif + #ifdef ENABLE_DRM + drm_gamma_method, + #endif diff --git a/x11-misc/redshift/metadata.xml b/x11-misc/redshift/metadata.xml new file mode 100644 index 0000000..13acdda --- /dev/null +++ b/x11-misc/redshift/metadata.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd"> +<pkgmetadata> + <use> + <flag name="geoclue">Control dependency on <pkg>app-misc/geoclue</pkg></flag> + </use> + <upstream> + <remote-id type="github">jonls/redshift</remote-id> + </upstream> +</pkgmetadata> diff --git a/x11-misc/redshift/redshift-1.12-r4.ebuild b/x11-misc/redshift/redshift-1.12-r4.ebuild new file mode 100644 index 0000000..6e03f65 --- /dev/null +++ b/x11-misc/redshift/redshift-1.12-r4.ebuild @@ -0,0 +1,91 @@ +# Copyright 1999-2020 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=6 +PYTHON_COMPAT=( python3_{6,7} ) + +inherit systemd autotools eutils gnome2-utils python-r1 + +DESCRIPTION="A screen color temperature adjusting software" +HOMEPAGE="http://jonls.dk/redshift/" +SRC_URI="https://github.com/jonls/redshift/archive/v${PV}.tar.gz -> ${P}.tar.gz" + +LICENSE="GPL-3" +SLOT="0" +KEYWORDS="amd64 arm64 x86" +IUSE="appindicator geoclue gtk nls wayland" + +COMMON_DEPEND=">=x11-libs/libX11-1.4 + x11-libs/libXxf86vm + x11-libs/libxcb + x11-libs/libdrm + appindicator? ( dev-libs/libappindicator:3[introspection] ) + geoclue? ( app-misc/geoclue:2.0 dev-libs/glib:2 ) + gtk? ( ${PYTHON_DEPS} ) + wayland? ( dev-libs/wayland )" +RDEPEND="${COMMON_DEPEND} + gtk? ( dev-python/pygobject[${PYTHON_USEDEP}] + x11-libs/gtk+:3[introspection] + dev-python/pyxdg[${PYTHON_USEDEP}] )" +DEPEND="${COMMON_DEPEND} + >=dev-util/intltool-0.50 + nls? ( sys-devel/gettext ) +" +REQUIRED_USE="gtk? ( ${PYTHON_REQUIRED_USE} )" + +PATCHES+=( ${FILESDIR}/redshift-wlroots-gamma.patch ) + +src_prepare() { + default + eautoreconf +} + +src_configure() { + use gtk && python_setup + + econf \ + $(use_enable nls) \ + --enable-drm \ + --enable-randr \ + --enable-vidmode \ + --disable-wingdi \ + $(use_enable wayland) \ + \ + --disable-corelocation \ + $(use_enable geoclue geoclue2) \ + \ + $(use_enable gtk gui) \ + --with-systemduserunitdir="$(systemd_get_userunitdir)" \ + --enable-apparmor \ + --disable-quartz \ + --disable-ubuntu +} + +_impl_specific_src_install() { + emake DESTDIR="${D}" pythondir="$(python_get_sitedir)" \ + -C src/redshift-gtk install +} + +src_install() { + emake DESTDIR="${D}" UPDATE_ICON_CACHE=/bin/true install + + if use gtk; then + python_foreach_impl _impl_specific_src_install + python_replicate_script "${D}"/usr/bin/redshift-gtk + dosym redshift-gtk /usr/bin/gtk-redshift + + python_foreach_impl python_optimize + fi +} + +pkg_preinst() { + use gtk && gnome2_icon_savelist +} + +pkg_postinst() { + use gtk && gnome2_icon_cache_update +} + +pkg_postrm() { + use gtk && gnome2_icon_cache_update +} |