//usr/bin/env -S tcc -lm -lX11 -lXxf86vm -run "$0" "$@"; exit $? /* Not Tetris, but a harmless trap (both for the students and NFS) * $Id: ntetris.c,v 1.22 2024/04/04 12:09:01 oj14ozun Exp $ * https://wwwcip.cs.fau.de/~oj14ozun/src+etc/ntetris.c * Distributed under https://creativecommons.org/public-domain/cc0/ */ #include #include #include #include #include #include #include #include #include #include #include #define DELTA_T 1e-3 #define SLEEP 10000 #define MIN_CT 0.5 #define P_RE 71 #define P_GR 17 #define P_BL 97 #define SELF_NAME "tetris" static Display *dpy; static void cleanup(int sig) { static volatile bool caught = false; if (!caught) { /* see (libc) Termination in Handler */ XF86VidModeSetGamma(dpy, DefaultScreen(dpy), &(XF86VidModeGamma){ 1, 1, 1 }); XCloseDisplay(dpy); signal(sig, SIG_DFL); } raise(sig); } int main() { int size; char *displayname; unsigned short *rr, *gr, *br; unsigned short *rr0, *gr0, *br0; sigset_t block, prev; /* Daemonise into the background */ switch (fork()) { case -1: goto fail; case 0: /* child */ break; default: /* parent */ return EXIT_SUCCESS; } /* Initialise X11 connection */ displayname = getenv("DISPLAY"); if (!(displayname && displayname[0])) goto fail; dpy = XOpenDisplay(displayname); if (dpy == NULL) goto fail; XF86VidModeSetGamma(dpy, DefaultScreen(dpy), &(XF86VidModeGamma){ 1, 1, 1 }); /* Allocate storage for the gamma info */ XF86VidModeGetGammaRampSize(dpy, DefaultScreen(dpy), &size); rr = calloc(sizeof(unsigned short), size); if (NULL == rr) goto fail; gr = calloc(sizeof(unsigned short), size); if (NULL == gr) goto fail; br = calloc(sizeof(unsigned short), size); if (NULL == br) goto fail; XF86VidModeGetGammaRamp(dpy, DefaultScreen(dpy), size, rr, gr, br); rr0 = calloc(sizeof(unsigned short), size); if (NULL == rr0) goto fail; gr0 = calloc(sizeof(unsigned short), size); if (NULL == gr0) goto fail; br0 = calloc(sizeof(unsigned short), size); if (NULL == br0) goto fail; /* Μὴ μοῦ τοὺς κύκλους τάραττε. */ nice(19); setsid(); signal(SIGHUP, SIG_IGN); signal(SIGINT, cleanup); signal(SIGTERM, cleanup); sigemptyset(&block); sigaddset(&block, SIGINT); sigaddset(&block, SIGTERM); /* Rename process to make it easier to find */ prctl(PR_SET_NAME, (unsigned long)SELF_NAME, 0, 0, 0); /* Oh boy fellas, let's rock this joint! */ for (double t = 0;; t += DELTA_T) { double f = 0.5; for (int i = 0; i < size; i++) { rr0[i] = rr[i] * ((1-f) + f * (1 + cos(t * P_RE)) / 2); gr0[i] = gr[i] * ((1-f) + f * (1 + cos(t * P_GR)) / 2); br0[i] = br[i] * ((1-f) + f * (1 + cos(t * P_BL)) / 2); } sigprocmask(SIG_BLOCK, &block, &prev); XF86VidModeSetGammaRamp(dpy, DefaultScreen(dpy), size, rr0, gr0, br0); usleep(SLEEP); sigprocmask(SIG_SETMASK, &prev, NULL); } abort(); fail: /* Intentionally obfuscate the error message */ fprintf(stderr, "Something went wrong, try again\n"); return EXIT_FAILURE; } /* Local Variables: */ /* compile-command: "cc -o ntetris ntetris.c -lm -lX11 -lXxf86vm" */ /* mode: c */ /* indent-tabs-mode: nil */ /* End: */