sct.c (3617B)
1 /* 2 * Copyright (c) 2015 Ted Unangst <tedu@openbsd.org> 3 * Copyright (c) 2016-2020 Joerg Jung <jung@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <string.h> 20 #include <err.h> 21 #include <errno.h> 22 #include <limits.h> 23 #include <unistd.h> 24 #include <X11/Xlib.h> 25 #include <X11/Xproto.h> 26 #include <X11/Xatom.h> 27 #include <X11/extensions/Xrandr.h> 28 29 #define S_V "0.5" 30 #define S_YR "2015-2020" 31 32 enum { S_RED, S_GREEN, S_BLUE, S_MAX }; 33 34 static const float s_wp[][S_MAX] = { /* whitepoint values from redshift */ 35 { 1.00000000, 0.18172716, 0.00000000 }, /* 1000K */ 36 { 1.00000000, 0.42322816, 0.00000000 }, 37 { 1.00000000, 0.54360078, 0.08679949 }, 38 { 1.00000000, 0.64373109, 0.28819679 }, 39 { 1.00000000, 0.71976951, 0.42860152 }, 40 { 1.00000000, 0.77987699, 0.54642268 }, 41 { 1.00000000, 0.82854786, 0.64816570 }, 42 { 1.00000000, 0.86860704, 0.73688797 }, 43 { 1.00000000, 0.90198230, 0.81465502 }, 44 { 1.00000000, 0.93853986, 0.88130458 }, 45 { 1.00000000, 0.97107439, 0.94305985 }, 46 { 1.00000000, 1.00000000, 1.00000000 }, /* 6500K */ 47 { 0.95160805, 0.96983355, 1.00000000 }, 48 { 0.91194747, 0.94470005, 1.00000000 }, 49 { 0.87906581, 0.92357340, 1.00000000 }, 50 { 0.85139976, 0.90559011, 1.00000000 }, 51 { 0.82782969, 0.89011714, 1.00000000 }, 52 { 0.80753191, 0.87667891, 1.00000000 }, 53 { 0.78988728, 0.86491137, 1.00000000 }, /* 10000K */ 54 { 0.77442176, 0.85453121, 1.00000000 } }; 55 56 static double s_avg(int t, double r, int c) { 57 return s_wp[t / 500][c] * (1 - r) + s_wp[t / 500 + 1][c] * r; 58 } 59 60 static void s_run(const char *s) { 61 Display *d; 62 XRRScreenResources *sr = NULL; 63 XRRCrtcGamma *cg; 64 unsigned long t; 65 double r, g; 66 int i, j, sz; 67 char *e; 68 69 errno = 0, t = strtoul(s, &e, 10); 70 if (s[0] == '\0' || *e != '\0' || (errno == ERANGE && t == ULONG_MAX)) 71 errx(1, "temp failed"); 72 if (t < 1000 || t > 10000) 73 t = 6500, warnx("temp range"); 74 t -= 1000, r = t % 500 / 500.0; 75 if (!(d = XOpenDisplay(NULL)) || !(sr = XRRGetScreenResourcesCurrent(d, 76 RootWindow(d, DefaultScreen(d))))) 77 err(1, "XOpenDisplay or XRRGetScreenResourcesCurrent failed"); 78 for (i = 0; i < sr->ncrtc; i++) { 79 sz = XRRGetCrtcGammaSize(d, sr->crtcs[i]); 80 if (!(cg = XRRAllocGamma(sz))) 81 err(1, "XRRAllocGamma failed"); 82 for (j = 0; j < sz; j++) { 83 g = 65535.0 * j / sz; 84 cg->red[j] = g * s_avg(t, r, S_RED); 85 cg->green[j] = g * s_avg(t, r, S_GREEN); 86 cg->blue[j] = g * s_avg(t, r, S_BLUE); 87 } 88 XRRSetCrtcGamma(d, sr->crtcs[i], cg); 89 XFree(cg); 90 } 91 printf("%luK\n", t + 1000); 92 XFree(sr), XCloseDisplay(d); 93 } 94 95 int main(int argc, char *argv[]) { 96 if (argc > 2) 97 errx(1, "usage: sct [<temp>]\n%12ssct version", ""); 98 s_run((argc == 2) ? argv[1] : "6500"); 99 return 0; 100 }