commit 27d0f5eda9e06b282956de36b2336519a1a32a61 from: Oliver Lowe date: Sat Jun 13 03:14:48 2026 UTC import ever-so-slightly trimmed sct commit - 6786d23fb9427663f0d9b1ef408e6772008f2e0b commit + 27d0f5eda9e06b282956de36b2336519a1a32a61 blob - /dev/null blob + 3092d3e4df7dcba413471fffcbd5fbc8f30a8c05 (mode 644) --- /dev/null +++ man/sct.1 @@ -0,0 +1,64 @@ +.\" $Id: sct.1 23 2020-01-28 23:31:17Z umaxx $ +.\" Copyright (c) 2017-2020 Joerg Jung +.\" +.\" 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 @@ -0,0 +1,7 @@ +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 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2015 Ted Unangst + * Copyright (c) 2016-2020 Joerg Jung + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 []\n%12ssct version", ""); + s_run((argc == 2) ? argv[1] : "6500"); + return 0; +}