summaryrefslogtreecommitdiff
path: root/x11-misc/redshift/files
diff options
context:
space:
mode:
Diffstat (limited to 'x11-misc/redshift/files')
-rw-r--r--x11-misc/redshift/files/redshift-wlroots-gamma.patch920
1 files changed, 0 insertions, 920 deletions
diff --git a/x11-misc/redshift/files/redshift-wlroots-gamma.patch b/x11-misc/redshift/files/redshift-wlroots-gamma.patch
deleted file mode 100644
index b1239c3..0000000
--- a/x11-misc/redshift/files/redshift-wlroots-gamma.patch
+++ /dev/null
@@ -1,920 +0,0 @@
-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, &registry_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