commit - 6786d23fb9427663f0d9b1ef408e6772008f2e0b
commit + 27d0f5eda9e06b282956de36b2336519a1a32a61
blob - /dev/null
blob + 3092d3e4df7dcba413471fffcbd5fbc8f30a8c05 (mode 644)
--- /dev/null
+++ man/sct.1
+.\" $Id: sct.1 23 2020-01-28 23:31:17Z umaxx $
+.\" Copyright (c) 2017-2020 Joerg Jung <mail@umaxx.net>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, 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.
+.Dd 13 June 2026
+.Dt SCT 1
+.Os
+.Sh NAME
+.Nm sct
+.Nd set the color temperature of the screen
+.Sh SYNOPSIS
+.Nm sct
+.Op Ar temp
+.Sh DESCRIPTION
+.Nm
+sets the color temperature of the screen to
+.Ar temp
+or 6500K if not specified.
+.Ar temp
+must be between 1000 and 10000.
+.Sh EXIT STATUS
+.Ex -std
+.Sh EXAMPLES
+Shift the screen temperature to campfire style:
+.Bd -literal -offset indent
+sct 4500
+.Ed
+.Sh SEE ALSO
+.Xr Xorg 1 ,
+.Xr xrandr 1 ,
+.Xr X 7
+.Sh STANDARDS
+The
+.Nm
+utility follows and uses
+.Xr XStandards 7 .
+.Sh HISTORY
+The first version of the
+.Nm
+utility appeared back in November 2015 within the following blog article:
+.Lk http://www.tedunangst.com/flak/post/sct-set-color-temperature .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+utility was written by
+.An Ted Unangst Aq Mt tedu@openbsd.org
+and further improved by
+.An Joerg Jung Aq Mt mail@umaxx.net .
+.Sh CAVEATS
+.Nm
+samples the color ramp in interval steps of 500 with
+.Ar temp
+values between steps being interpolated.
blob - /dev/null
blob + b764bcfd950856f6e02432628fbe647feff77aa1 (mode 644)
--- /dev/null
+++ src/Makefile
+sct: sct.c
+ cc -I /usr/X11R6/include -L /usr/X11R6/lib -lX11 -lXrandr -o $@ $<
+
+clean:
+ rm -f sct
+
+.PHONY: clean
blob - /dev/null
blob + 6cf6bc12c5c4e84474070d6f534453351833d17b (mode 644)
--- /dev/null
+++ src/sct.c
+/*
+ * Copyright (c) 2015 Ted Unangst <tedu@openbsd.org>
+ * Copyright (c) 2016-2020 Joerg Jung <jung@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, 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.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <err.h>
+#include <errno.h>
+#include <limits.h>
+#include <unistd.h>
+#include <X11/Xlib.h>
+#include <X11/Xproto.h>
+#include <X11/Xatom.h>
+#include <X11/extensions/Xrandr.h>
+
+#define S_V "0.5"
+#define S_YR "2015-2020"
+
+enum { S_RED, S_GREEN, S_BLUE, S_MAX };
+
+static const float s_wp[][S_MAX] = { /* whitepoint values from redshift */
+ { 1.00000000, 0.18172716, 0.00000000 }, /* 1000K */
+ { 1.00000000, 0.42322816, 0.00000000 },
+ { 1.00000000, 0.54360078, 0.08679949 },
+ { 1.00000000, 0.64373109, 0.28819679 },
+ { 1.00000000, 0.71976951, 0.42860152 },
+ { 1.00000000, 0.77987699, 0.54642268 },
+ { 1.00000000, 0.82854786, 0.64816570 },
+ { 1.00000000, 0.86860704, 0.73688797 },
+ { 1.00000000, 0.90198230, 0.81465502 },
+ { 1.00000000, 0.93853986, 0.88130458 },
+ { 1.00000000, 0.97107439, 0.94305985 },
+ { 1.00000000, 1.00000000, 1.00000000 }, /* 6500K */
+ { 0.95160805, 0.96983355, 1.00000000 },
+ { 0.91194747, 0.94470005, 1.00000000 },
+ { 0.87906581, 0.92357340, 1.00000000 },
+ { 0.85139976, 0.90559011, 1.00000000 },
+ { 0.82782969, 0.89011714, 1.00000000 },
+ { 0.80753191, 0.87667891, 1.00000000 },
+ { 0.78988728, 0.86491137, 1.00000000 }, /* 10000K */
+ { 0.77442176, 0.85453121, 1.00000000 } };
+
+static double s_avg(int t, double r, int c) {
+ return s_wp[t / 500][c] * (1 - r) + s_wp[t / 500 + 1][c] * r;
+}
+
+static void s_run(const char *s) {
+ Display *d;
+ XRRScreenResources *sr = NULL;
+ XRRCrtcGamma *cg;
+ unsigned long t;
+ double r, g;
+ int i, j, sz;
+ char *e;
+
+ errno = 0, t = strtoul(s, &e, 10);
+ if (s[0] == '\0' || *e != '\0' || (errno == ERANGE && t == ULONG_MAX))
+ errx(1, "temp failed");
+ if (t < 1000 || t > 10000)
+ t = 6500, warnx("temp range");
+ t -= 1000, r = t % 500 / 500.0;
+ if (!(d = XOpenDisplay(NULL)) || !(sr = XRRGetScreenResourcesCurrent(d,
+ RootWindow(d, DefaultScreen(d)))))
+ err(1, "XOpenDisplay or XRRGetScreenResourcesCurrent failed");
+ for (i = 0; i < sr->ncrtc; i++) {
+ sz = XRRGetCrtcGammaSize(d, sr->crtcs[i]);
+ if (!(cg = XRRAllocGamma(sz)))
+ err(1, "XRRAllocGamma failed");
+ for (j = 0; j < sz; j++) {
+ g = 65535.0 * j / sz;
+ cg->red[j] = g * s_avg(t, r, S_RED);
+ cg->green[j] = g * s_avg(t, r, S_GREEN);
+ cg->blue[j] = g * s_avg(t, r, S_BLUE);
+ }
+ XRRSetCrtcGamma(d, sr->crtcs[i], cg);
+ XFree(cg);
+ }
+ printf("%luK\n", t + 1000);
+ XFree(sr), XCloseDisplay(d);
+}
+
+int main(int argc, char *argv[]) {
+ if (argc > 2)
+ errx(1, "usage: sct [<temp>]\n%12ssct version", "");
+ s_run((argc == 2) ? argv[1] : "6500");
+ return 0;
+}