sct

set color temperature
git clone anongit@rnpnr.xyz:sct.git
Log | Files | Refs | Feed | README | LICENSE

Commit: 1eb485b505a79966f9ea21c8bf8cb072138a55b1
Parent: f2aa7c80a8bb2af9c5755aedbcc594a841af6713
Author: Randy Palamar
Date:   Sun,  2 Apr 2023 17:40:34 -0600

rename files to ssct.? and mv to top level

Diffstat:
D.gitignore | 1-
MMakefile | 4++--
Dsrc/xsct.c | 282-------------------------------------------------------------------------------
Rxsct.1 -> ssct.1 | 0
Assct.c | 282+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rsrc/xsct.h -> ssct.h | 0
6 files changed, 284 insertions(+), 285 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1 +0,0 @@ -xsct diff --git a/Makefile b/Makefile @@ -6,8 +6,8 @@ BIN ?= $(PREFIX)/bin MAN ?= $(PREFIX)/share/man/man1 INSTALL ?= install -PROG = xsct -SRCS = src/xsct.c +PROG = ssct +SRCS = ssct.c LIBS = -lX11 -lXrandr -lm diff --git a/src/xsct.c b/src/xsct.c @@ -1,282 +0,0 @@ -/* - * xsct - X11 set color temperature - * - * Public domain, do as you wish. - */ - -#include "xsct.h" - -static void usage(char * pname) -{ - printf("Xsct (%s)\n" - "Usage: %s [options] [temperature] [brightness]\n" - "\tIf the argument is 0, xsct resets the display to the default temperature (6500K)\n" - "\tIf no arguments are passed, xsct estimates the current display temperature and brightness\n" - "Options:\n" - "\t-h, --help \t xsct will display this usage information\n" - "\t-v, --verbose \t xsct will display debugging information\n" - "\t-d, --delta\t xsct will shift temperature by the temperature value\n" - "\t-s, --screen N\t xsct will only select screen specified by given zero-based index\n" - "\t-c, --crtc N\t xsct will only select CRTC specified by given zero-based index\n", XSCT_VERSION, pname); -} - -static double DoubleTrim(double x, double a, double b) -{ - double buff[3] = {a, x, b}; - return buff[ (int)(x > a) + (int)(x > b) ]; -} - -static struct temp_status get_sct_for_screen(Display *dpy, int screen, int icrtc, int fdebug) -{ - Window root = RootWindow(dpy, screen); - XRRScreenResources *res = XRRGetScreenResourcesCurrent(dpy, root); - - int n, c; - double t = 0.0; - double gammar = 0.0, gammag = 0.0, gammab = 0.0, gammad = 0.0; - struct temp_status temp; - temp.temp = 0; - temp.brightness = 1.0; - - n = res->ncrtc; - if ((icrtc >= 0) && (icrtc < n)) - n = 1; - else - icrtc = 0; - for (c = icrtc; c < (icrtc + n); c++) - { - RRCrtc crtcxid; - int size; - XRRCrtcGamma *crtc_gamma; - crtcxid = res->crtcs[c]; - crtc_gamma = XRRGetCrtcGamma(dpy, crtcxid); - size = crtc_gamma->size; - gammar += crtc_gamma->red[size - 1]; - gammag += crtc_gamma->green[size - 1]; - gammab += crtc_gamma->blue[size - 1]; - - XRRFreeGamma(crtc_gamma); - } - XFree(res); - temp.brightness = (gammar > gammag) ? gammar : gammag; - temp.brightness = (gammab > temp.brightness) ? gammab : temp.brightness; - if (temp.brightness > 0.0 && n > 0) - { - gammar /= temp.brightness; - gammag /= temp.brightness; - gammab /= temp.brightness; - temp.brightness /= n; - temp.brightness /= BRIGHTHESS_DIV; - temp.brightness = DoubleTrim(temp.brightness, 0.0, 1.0); - if (fdebug > 0) fprintf(stderr, "DEBUG: Gamma: %f, %f, %f, brightness: %f\n", gammar, gammag, gammab, temp.brightness); - gammad = gammab - gammar; - if (gammad < 0.0) - { - if (gammab > 0.0) - { - t = exp((gammag + 1.0 + gammad - (GAMMA_K0GR + GAMMA_K0BR)) / (GAMMA_K1GR + GAMMA_K1BR)) + TEMPERATURE_ZERO; - } - else - { - t = (gammag > 0.0) ? (exp((gammag - GAMMA_K0GR) / GAMMA_K1GR) + TEMPERATURE_ZERO) : TEMPERATURE_ZERO; - } - } - else - { - t = exp((gammag + 1.0 - gammad - (GAMMA_K0GB + GAMMA_K0RB)) / (GAMMA_K1GB + GAMMA_K1RB)) + (TEMPERATURE_NORM - TEMPERATURE_ZERO); - } - } - else - temp.brightness = DoubleTrim(temp.brightness, 0.0, 1.0); - - temp.temp = (int)(t + 0.5); - - return temp; -} - -static void sct_for_screen(Display *dpy, int screen, int icrtc, struct temp_status temp, int fdebug) -{ - double t = 0.0, b = 1.0, g = 0.0, gammar, gammag, gammab; - int n, c; - Window root = RootWindow(dpy, screen); - XRRScreenResources *res = XRRGetScreenResourcesCurrent(dpy, root); - - t = (double)temp.temp; - b = DoubleTrim(temp.brightness, 0.0, 1.0); - if (temp.temp < TEMPERATURE_NORM) - { - gammar = 1.0; - if (temp.temp > TEMPERATURE_ZERO) - { - g = log(t - TEMPERATURE_ZERO); - gammag = DoubleTrim(GAMMA_K0GR + GAMMA_K1GR * g, 0.0, 1.0); - gammab = DoubleTrim(GAMMA_K0BR + GAMMA_K1BR * g, 0.0, 1.0); - } - else - { - gammag = 0.0; - gammab = 0.0; - } - } - else - { - g = log(t - (TEMPERATURE_NORM - TEMPERATURE_ZERO)); - gammar = DoubleTrim(GAMMA_K0RB + GAMMA_K1RB * g, 0.0, 1.0); - gammag = DoubleTrim(GAMMA_K0GB + GAMMA_K1GB * g, 0.0, 1.0); - gammab = 1.0; - } - if (fdebug > 0) fprintf(stderr, "DEBUG: Gamma: %f, %f, %f, brightness: %f\n", gammar, gammag, gammab, b); - n = res->ncrtc; - if ((icrtc >= 0) && (icrtc < n)) - n = 1; - else - icrtc = 0; - for (c = icrtc; c < (icrtc + n); c++) - { - int size, i; - RRCrtc crtcxid; - XRRCrtcGamma *crtc_gamma; - crtcxid = res->crtcs[c]; - size = XRRGetCrtcGammaSize(dpy, crtcxid); - - crtc_gamma = XRRAllocGamma(size); - - for (i = 0; i < size; i++) - { - g = GAMMA_MULT * b * (double)i / (double)size; - crtc_gamma->red[i] = (unsigned short int)(g * gammar + 0.5); - crtc_gamma->green[i] = (unsigned short int)(g * gammag + 0.5); - crtc_gamma->blue[i] = (unsigned short int)(g * gammab + 0.5); - } - - XRRSetCrtcGamma(dpy, crtcxid, crtc_gamma); - XRRFreeGamma(crtc_gamma); - } - - XFree(res); -} - -int main(int argc, char **argv) -{ - int i, screen, screens; - int screen_specified, screen_first, screen_last, crtc_specified; - struct temp_status temp; - int fdebug = 0, fdelta = 0, fhelp = 0; - Display *dpy = XOpenDisplay(NULL); - - if (!dpy) - { - perror("XOpenDisplay(NULL) failed"); - fprintf(stderr, "ERROR! Ensure DISPLAY is set correctly!\n"); - return EXIT_FAILURE; - } - screens = XScreenCount(dpy); - screen_first = 0; - screen_last = screens - 1; - screen_specified = -1; - crtc_specified = -1; - temp.temp = DELTA_MIN; - temp.brightness = -1.0; - for (i = 1; i < argc; i++) - { - if ((strcmp(argv[i],"-h") == 0) || (strcmp(argv[i],"--help") == 0)) fhelp = 1; - else if ((strcmp(argv[i],"-v") == 0) || (strcmp(argv[i],"--verbose") == 0)) fdebug = 1; - else if ((strcmp(argv[i],"-d") == 0) || (strcmp(argv[i],"--delta") == 0)) fdelta = 1; - else if ((strcmp(argv[i],"-s") == 0) || (strcmp(argv[i],"--screen") == 0)) - { - i++; - if (i < argc) - { - screen_specified = atoi(argv[i]); - } else { - fprintf(stderr, "ERROR! Required value for screen not specified!\n"); - fhelp = 1; - } - } - else if ((strcmp(argv[i],"-c") == 0) || (strcmp(argv[i],"--crtc") == 0)) - { - i++; - if (i < argc) - { - crtc_specified = atoi(argv[i]); - } else { - fprintf(stderr, "ERROR! Required value for crtc not specified!\n"); - fhelp = 1; - } - } - else if (temp.temp == DELTA_MIN) temp.temp = atoi(argv[i]); - else if (temp.brightness < 0.0) temp.brightness = atof(argv[i]); - else - { - fprintf(stderr, "ERROR! Unknown parameter: %s\n!", argv[i]); - fhelp = 1; - } - } - - if (fhelp > 0) - { - usage(argv[0]); - } - else if (screen_specified >= screens) - { - fprintf(stderr, "ERROR! Invalid screen index: %d!\n", screen_specified); - } - else - { - if (temp.brightness < 0.0) temp.brightness = 1.0; - if (screen_specified >= 0) - { - screen_first = screen_specified; - screen_last = screen_specified; - } - if ((temp.temp < 0) && (fdelta == 0)) - { - // No arguments, so print estimated temperature for each screen - for (screen = screen_first; screen <= screen_last; screen++) - { - temp = get_sct_for_screen(dpy, screen, crtc_specified, fdebug); - printf("Screen %d: temperature ~ %d %f\n", screen, temp.temp, temp.brightness); - } - } - else - { - if (fdelta == 0) - { - // Set temperature to given value or default for a value of 0 - if (temp.temp == 0) - { - temp.temp = TEMPERATURE_NORM; - } - else if (temp.temp < TEMPERATURE_ZERO) - { - fprintf(stderr, "WARNING! Temperatures below %d cannot be displayed.\n", TEMPERATURE_ZERO); - temp.temp = TEMPERATURE_ZERO; - } - for (screen = screen_first; screen <= screen_last; screen++) - { - sct_for_screen(dpy, screen, crtc_specified, temp, fdebug); - } - } - else - { - // Delta mode: Shift temperature of each screen by given value - for (screen = screen_first; screen <= screen_last; screen++) - { - struct temp_status tempd = get_sct_for_screen(dpy, screen, crtc_specified, fdebug); - tempd.temp += temp.temp; - if (tempd.temp < TEMPERATURE_ZERO) - { - fprintf(stderr, "WARNING! Temperatures below %d cannot be displayed.\n", TEMPERATURE_ZERO); - tempd.temp = TEMPERATURE_ZERO; - } - sct_for_screen(dpy, screen, crtc_specified, tempd, fdebug); - } - } - } - } - - XCloseDisplay(dpy); - - return EXIT_SUCCESS; -} - diff --git a/xsct.1 b/ssct.1 diff --git a/ssct.c b/ssct.c @@ -0,0 +1,282 @@ +/* + * ssct - suckless set color temperature (X11) + * + * Public domain, do as you wish. + */ + +#include "ssct.h" + +static void usage(char * pname) +{ + printf("Xsct (%s)\n" + "Usage: %s [options] [temperature] [brightness]\n" + "\tIf the argument is 0, xsct resets the display to the default temperature (6500K)\n" + "\tIf no arguments are passed, xsct estimates the current display temperature and brightness\n" + "Options:\n" + "\t-h, --help \t xsct will display this usage information\n" + "\t-v, --verbose \t xsct will display debugging information\n" + "\t-d, --delta\t xsct will shift temperature by the temperature value\n" + "\t-s, --screen N\t xsct will only select screen specified by given zero-based index\n" + "\t-c, --crtc N\t xsct will only select CRTC specified by given zero-based index\n", XSCT_VERSION, pname); +} + +static double DoubleTrim(double x, double a, double b) +{ + double buff[3] = {a, x, b}; + return buff[ (int)(x > a) + (int)(x > b) ]; +} + +static struct temp_status get_sct_for_screen(Display *dpy, int screen, int icrtc, int fdebug) +{ + Window root = RootWindow(dpy, screen); + XRRScreenResources *res = XRRGetScreenResourcesCurrent(dpy, root); + + int n, c; + double t = 0.0; + double gammar = 0.0, gammag = 0.0, gammab = 0.0, gammad = 0.0; + struct temp_status temp; + temp.temp = 0; + temp.brightness = 1.0; + + n = res->ncrtc; + if ((icrtc >= 0) && (icrtc < n)) + n = 1; + else + icrtc = 0; + for (c = icrtc; c < (icrtc + n); c++) + { + RRCrtc crtcxid; + int size; + XRRCrtcGamma *crtc_gamma; + crtcxid = res->crtcs[c]; + crtc_gamma = XRRGetCrtcGamma(dpy, crtcxid); + size = crtc_gamma->size; + gammar += crtc_gamma->red[size - 1]; + gammag += crtc_gamma->green[size - 1]; + gammab += crtc_gamma->blue[size - 1]; + + XRRFreeGamma(crtc_gamma); + } + XFree(res); + temp.brightness = (gammar > gammag) ? gammar : gammag; + temp.brightness = (gammab > temp.brightness) ? gammab : temp.brightness; + if (temp.brightness > 0.0 && n > 0) + { + gammar /= temp.brightness; + gammag /= temp.brightness; + gammab /= temp.brightness; + temp.brightness /= n; + temp.brightness /= BRIGHTHESS_DIV; + temp.brightness = DoubleTrim(temp.brightness, 0.0, 1.0); + if (fdebug > 0) fprintf(stderr, "DEBUG: Gamma: %f, %f, %f, brightness: %f\n", gammar, gammag, gammab, temp.brightness); + gammad = gammab - gammar; + if (gammad < 0.0) + { + if (gammab > 0.0) + { + t = exp((gammag + 1.0 + gammad - (GAMMA_K0GR + GAMMA_K0BR)) / (GAMMA_K1GR + GAMMA_K1BR)) + TEMPERATURE_ZERO; + } + else + { + t = (gammag > 0.0) ? (exp((gammag - GAMMA_K0GR) / GAMMA_K1GR) + TEMPERATURE_ZERO) : TEMPERATURE_ZERO; + } + } + else + { + t = exp((gammag + 1.0 - gammad - (GAMMA_K0GB + GAMMA_K0RB)) / (GAMMA_K1GB + GAMMA_K1RB)) + (TEMPERATURE_NORM - TEMPERATURE_ZERO); + } + } + else + temp.brightness = DoubleTrim(temp.brightness, 0.0, 1.0); + + temp.temp = (int)(t + 0.5); + + return temp; +} + +static void sct_for_screen(Display *dpy, int screen, int icrtc, struct temp_status temp, int fdebug) +{ + double t = 0.0, b = 1.0, g = 0.0, gammar, gammag, gammab; + int n, c; + Window root = RootWindow(dpy, screen); + XRRScreenResources *res = XRRGetScreenResourcesCurrent(dpy, root); + + t = (double)temp.temp; + b = DoubleTrim(temp.brightness, 0.0, 1.0); + if (temp.temp < TEMPERATURE_NORM) + { + gammar = 1.0; + if (temp.temp > TEMPERATURE_ZERO) + { + g = log(t - TEMPERATURE_ZERO); + gammag = DoubleTrim(GAMMA_K0GR + GAMMA_K1GR * g, 0.0, 1.0); + gammab = DoubleTrim(GAMMA_K0BR + GAMMA_K1BR * g, 0.0, 1.0); + } + else + { + gammag = 0.0; + gammab = 0.0; + } + } + else + { + g = log(t - (TEMPERATURE_NORM - TEMPERATURE_ZERO)); + gammar = DoubleTrim(GAMMA_K0RB + GAMMA_K1RB * g, 0.0, 1.0); + gammag = DoubleTrim(GAMMA_K0GB + GAMMA_K1GB * g, 0.0, 1.0); + gammab = 1.0; + } + if (fdebug > 0) fprintf(stderr, "DEBUG: Gamma: %f, %f, %f, brightness: %f\n", gammar, gammag, gammab, b); + n = res->ncrtc; + if ((icrtc >= 0) && (icrtc < n)) + n = 1; + else + icrtc = 0; + for (c = icrtc; c < (icrtc + n); c++) + { + int size, i; + RRCrtc crtcxid; + XRRCrtcGamma *crtc_gamma; + crtcxid = res->crtcs[c]; + size = XRRGetCrtcGammaSize(dpy, crtcxid); + + crtc_gamma = XRRAllocGamma(size); + + for (i = 0; i < size; i++) + { + g = GAMMA_MULT * b * (double)i / (double)size; + crtc_gamma->red[i] = (unsigned short int)(g * gammar + 0.5); + crtc_gamma->green[i] = (unsigned short int)(g * gammag + 0.5); + crtc_gamma->blue[i] = (unsigned short int)(g * gammab + 0.5); + } + + XRRSetCrtcGamma(dpy, crtcxid, crtc_gamma); + XRRFreeGamma(crtc_gamma); + } + + XFree(res); +} + +int main(int argc, char **argv) +{ + int i, screen, screens; + int screen_specified, screen_first, screen_last, crtc_specified; + struct temp_status temp; + int fdebug = 0, fdelta = 0, fhelp = 0; + Display *dpy = XOpenDisplay(NULL); + + if (!dpy) + { + perror("XOpenDisplay(NULL) failed"); + fprintf(stderr, "ERROR! Ensure DISPLAY is set correctly!\n"); + return EXIT_FAILURE; + } + screens = XScreenCount(dpy); + screen_first = 0; + screen_last = screens - 1; + screen_specified = -1; + crtc_specified = -1; + temp.temp = DELTA_MIN; + temp.brightness = -1.0; + for (i = 1; i < argc; i++) + { + if ((strcmp(argv[i],"-h") == 0) || (strcmp(argv[i],"--help") == 0)) fhelp = 1; + else if ((strcmp(argv[i],"-v") == 0) || (strcmp(argv[i],"--verbose") == 0)) fdebug = 1; + else if ((strcmp(argv[i],"-d") == 0) || (strcmp(argv[i],"--delta") == 0)) fdelta = 1; + else if ((strcmp(argv[i],"-s") == 0) || (strcmp(argv[i],"--screen") == 0)) + { + i++; + if (i < argc) + { + screen_specified = atoi(argv[i]); + } else { + fprintf(stderr, "ERROR! Required value for screen not specified!\n"); + fhelp = 1; + } + } + else if ((strcmp(argv[i],"-c") == 0) || (strcmp(argv[i],"--crtc") == 0)) + { + i++; + if (i < argc) + { + crtc_specified = atoi(argv[i]); + } else { + fprintf(stderr, "ERROR! Required value for crtc not specified!\n"); + fhelp = 1; + } + } + else if (temp.temp == DELTA_MIN) temp.temp = atoi(argv[i]); + else if (temp.brightness < 0.0) temp.brightness = atof(argv[i]); + else + { + fprintf(stderr, "ERROR! Unknown parameter: %s\n!", argv[i]); + fhelp = 1; + } + } + + if (fhelp > 0) + { + usage(argv[0]); + } + else if (screen_specified >= screens) + { + fprintf(stderr, "ERROR! Invalid screen index: %d!\n", screen_specified); + } + else + { + if (temp.brightness < 0.0) temp.brightness = 1.0; + if (screen_specified >= 0) + { + screen_first = screen_specified; + screen_last = screen_specified; + } + if ((temp.temp < 0) && (fdelta == 0)) + { + // No arguments, so print estimated temperature for each screen + for (screen = screen_first; screen <= screen_last; screen++) + { + temp = get_sct_for_screen(dpy, screen, crtc_specified, fdebug); + printf("Screen %d: temperature ~ %d %f\n", screen, temp.temp, temp.brightness); + } + } + else + { + if (fdelta == 0) + { + // Set temperature to given value or default for a value of 0 + if (temp.temp == 0) + { + temp.temp = TEMPERATURE_NORM; + } + else if (temp.temp < TEMPERATURE_ZERO) + { + fprintf(stderr, "WARNING! Temperatures below %d cannot be displayed.\n", TEMPERATURE_ZERO); + temp.temp = TEMPERATURE_ZERO; + } + for (screen = screen_first; screen <= screen_last; screen++) + { + sct_for_screen(dpy, screen, crtc_specified, temp, fdebug); + } + } + else + { + // Delta mode: Shift temperature of each screen by given value + for (screen = screen_first; screen <= screen_last; screen++) + { + struct temp_status tempd = get_sct_for_screen(dpy, screen, crtc_specified, fdebug); + tempd.temp += temp.temp; + if (tempd.temp < TEMPERATURE_ZERO) + { + fprintf(stderr, "WARNING! Temperatures below %d cannot be displayed.\n", TEMPERATURE_ZERO); + tempd.temp = TEMPERATURE_ZERO; + } + sct_for_screen(dpy, screen, crtc_specified, tempd, fdebug); + } + } + } + } + + XCloseDisplay(dpy); + + return EXIT_SUCCESS; +} + diff --git a/src/xsct.h b/ssct.h