diff options
Diffstat (limited to 'src/unstickpixels.c')
-rw-r--r-- | src/unstickpixels.c | 491 |
1 files changed, 0 insertions, 491 deletions
diff --git a/src/unstickpixels.c b/src/unstickpixels.c deleted file mode 100644 index 9a59aa3..0000000 --- a/src/unstickpixels.c +++ /dev/null @@ -1,491 +0,0 @@ -/** - * unstickpixels – screen loop to try to unstick stuck pixels - * - * Copyright © 2013, 2015 Mattias Andrée (maandree@member.fsf.org) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -#define _XOPEN_SOURCE 700 -#define _DEFAULT_SOURCE -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <signal.h> -#include <string.h> -#include <assert.h> -#include <time.h> -#include <errno.h> -#include <ctype.h> -#include <signal.h> -#include <sys/wait.h> - -#include <libgamma.h> - - - -#define t(...) do { if (__VA_ARGS__) goto fail; } while (0) - - -#define WELCOME_MESSAGE \ - "\033[H\033[01;31mWARNING: Do not use this if you have epilepsia.\033[00m\n" \ - "\n" \ - "It is recommended to massage the defective dots, whilst\n" \ - "running this program.\n" \ - "\n" \ - "Press C-c to quit, and Enter to start (C-c will quit).\n" \ - "\n" \ - "\n" \ - "You should not have to run this program. If the manufacture or\n" \ - "reseller of your monitor refuse to replace or repair the monitor\n" \ - "that was broken, because of manufacturing error, when it was\n" \ - "chiped to you, please consider yelling at the support, threaten\n" \ - "to report the personally because of involvement in organised\n" \ - "crime (not replacing hardware that was chipped broken when you\n" \ - "selled it is a crime, and they do this in an organised fashion\n" \ - "to make money), call their executive director persistently at\n" \ - "inconvenient times, report them applicable board for consumer\n" \ - "disputes/complaints or equivalent agency. If this program does\n" \ - "not help, and the manufacture is Packard Bell, or its\n" \ - "supersidiary Acer, tell them that you have tried a program\n" \ - "that was prompted by the complete suckness and incapability\n" \ - "to repair defects that they have agreed to repair. They suck!\n" \ - "\n" \ - "\n" \ - "\n" \ - "Copyright © 2013, 2015 Mattias Andrée (maandree@member.fsf.org)\n" \ - "\n" \ - "This program is free software: you can redistribute it and/or modify\n" \ - "it under the terms of the GNU General Public License as published by\n" \ - "the Free Software Foundation, either version 3 of the License, or\n" \ - "(at your option) any later version.\n" \ - "\n" \ - "This program is distributed in the hope that it will be useful,\n" \ - "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" \ - "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" \ - "GNU General Public License for more details.\n" \ - "\n" \ - "You should have received a copy of the GNU General Public License\n" \ - "along with this program. If not, see <http://www.gnu.org/licenses/>." - - -/** - * The name of the process. - */ -const char* argv0; - -/** - * Should we exit? - */ -static volatile sig_atomic_t please_exit = 0; - -/** - * The name of the site. - */ -static char* sitename = NULL; - -/** - * The site. - */ -static libgamma_site_state_t site; - -/** - * The partitions. - */ -static libgamma_partition_state_t* restrict* restrict parts = NULL; - -/** - * The CRTC:s. - */ -static libgamma_crtc_state_t* restrict* restrict crtcs = NULL; - -/** - * The ramps to use when displaying red. - */ -static libgamma_gamma_ramps16_t* restrict* restrict ramps_red = NULL; - -/** - * The ramps to use when displaying green. - */ -static libgamma_gamma_ramps16_t* restrict* restrict ramps_green = NULL; - -/** - * The ramps to use when displaying blue. - */ -static libgamma_gamma_ramps16_t* restrict* restrict ramps_blue = NULL; - -/** - * The original ramps. - */ -static libgamma_gamma_ramps16_t* restrict* restrict ramps_saved = NULL; - -/** - * 2: `site` initialised and all ramps saved. - * 1: `site` initialised. - * 0: nothing done. - */ -static int clut_state = 0; - - - -/** - * Parse interval argument. - * - * @param argv The interval argument. - * @param interval Output parameter for the interval. - * @param nonzero With be set to zero if the interval is zero, - * otherwise it is set to a non-zero value (1). - * @return 0 on success, -1 on error. - */ -static int get_interval(const char* restrict arg, struct timespec* restrict interval, int* restrict nonzero) -{ - char* end; - *nonzero = 1; - errno = EINVAL; - t (!isdigit(*arg)); - interval->tv_sec = (time_t)(errno = 0, strtol)(arg, &end, 10); - t (errno || (errno = EINVAL, *end)); - interval->tv_nsec = interval->tv_sec % 1000; - interval->tv_sec /= 1000; - interval->tv_nsec *= 1000000L; - if (interval->tv_sec == 0) - if (interval->tv_nsec == 0) - *nonzero = 0; - return 0; - fail: - return -1; -} - - -/** - * Wrapper for fork(3) that clocks all signals in the parent. - * - * @return See fork(3). - */ -static pid_t xfork(void) -{ - sigset_t set; - pid_t pid; - sigfillset(&set); - sigprocmask(SIG_BLOCK, &set, 0); - pid = fork(); - if (pid != -1) - sigprocmask(SIG_UNBLOCK, &set, 0); - return pid; -} - - -/** - * Print usage information and exit. - */ -static void usage(void) -{ - exit(fprintf(stderr, "Usage: %s [-v] [--] [SLEEP_INTERVAL_MS]\n", - strrchr(argv0, '/') ? (strrchr(argv0, '/') + 1) : argv0 - ) < 0 ? 1 : 2); -} - - -/** - * Uninitialise the CLUT backend. - * - * @return 0 on success, -1 on error. - */ -static void term_clut() -{ - size_t i, j; - if (clut_state == 2) - for (j = 0; j < 2; j++, usleep(1000000L / 10L)) - for (i = 0; crtcs && crtcs[i]; i++, usleep(1000000L / 100L)) - libgamma_crtc_set_gamma_ramps16(crtcs[i], *(ramps_saved[i])); - for (i = 0; crtcs && crtcs[i]; i++) - { - libgamma_crtc_free(crtcs[i]); - libgamma_gamma_ramps16_free(ramps_red[i]); - libgamma_gamma_ramps16_free(ramps_green[i]); - libgamma_gamma_ramps16_free(ramps_blue[i]); - libgamma_gamma_ramps16_free(ramps_saved[i]); - } - free((void*)crtcs); - free((void*)ramps_red); - free((void*)ramps_green); - free((void*)ramps_blue); - free((void*)ramps_saved); - for (i = 0; parts && parts[i]; i++) - libgamma_partition_free(parts[i]); - free((void*)parts); - free((void*)sitename); - if (clut_state) - libgamma_site_destroy(&site); - sitename = NULL; - parts = NULL; - crtcs = NULL; - ramps_red = ramps_green = ramps_blue = ramps_saved = NULL; - clut_state = 0; -} - - -/** - * Initialise the CLUT backend. - * - * @return 0 on success, -1 on error. - */ -static int init_clut() -{ - int method, error = 0; - size_t i, j, k, n = 0; - libgamma_crtc_information_t info; - - if (libgamma_list_methods(&method, 1, 0) < 1) - { - fprintf(stderr, "%s: could not get adjustment method, try '%s -v'.\n", argv0, argv0); - return -1; - } - - sitename = libgamma_method_default_site(method); - if (sitename) - { - sitename = strdup(sitename); - t (sitename == NULL); - } - t ((error = libgamma_site_initialise(&site, method, sitename))); - sitename = NULL; - - clut_state++; - - if (site.partitions_available == 0) - { - fprintf(stderr, "%s: could find any graphics card/screen, try '%s -v'.\n", argv0, argv0); - errno = 0; - goto fail; - } - - t (!(parts = calloc(site.partitions_available + 1, sizeof(*parts)))); - for (i = 0; i < site.partitions_available; i++) - { - t (!(parts[i] = calloc(1, sizeof(**parts)))); - t ((errno = libgamma_partition_initialise(parts[i], &site, i))); - n += parts[i]->crtcs_available; - } - - if (n == 0) - { - fprintf(stderr, "%s: could find any CRTC, try '%s -v'.\n", argv0, argv0); - errno = 0; - goto fail; - } - - t (!(crtcs = calloc(n + 1, sizeof(*crtcs)))); - t (!(ramps_red = calloc(n + 1, sizeof(*ramps_red)))); - t (!(ramps_green = calloc(n + 1, sizeof(*ramps_green)))); - t (!(ramps_blue = calloc(n + 1, sizeof(*ramps_blue)))); - t (!(ramps_saved = calloc(n + 1, sizeof(*ramps_saved)))); - for (i = k = 0; i < site.partitions_available; i++) - for (j = 0; j < parts[i]->crtcs_available; j++, k++) - { - t (!(crtcs[k] = calloc(1, sizeof(**crtcs)))); - t (!(ramps_red[k] = calloc(1, sizeof(**ramps_red)))); - t (!(ramps_green[k] = calloc(1, sizeof(**ramps_green)))); - t (!(ramps_blue[k] = calloc(1, sizeof(**ramps_blue)))); - t (!(ramps_saved[k] = calloc(1, sizeof(**ramps_saved)))); - t ((error = libgamma_crtc_initialise(crtcs[k], parts[i], j))); - if (libgamma_get_crtc_information(&info, crtcs[k], LIBGAMMA_CRTC_INFO_GAMMA_SIZE)) - t ((error = info.gamma_size_error)); - ramps_red[k]->red_size = info.red_gamma_size; - ramps_red[k]->green_size = info.green_gamma_size; - ramps_red[k]->blue_size = info.blue_gamma_size; - *(ramps_saved[k]) = *(ramps_blue[k]) = *(ramps_green[k]) = *(ramps_red[k]); - t (libgamma_gamma_ramps16_initialise(ramps_red[k])); - t (libgamma_gamma_ramps16_initialise(ramps_green[k])); - t (libgamma_gamma_ramps16_initialise(ramps_blue[k])); - t (libgamma_gamma_ramps16_initialise(ramps_saved[k])); - memset(ramps_red[k]->red, ~0, ramps_red[k]->red_size * sizeof(*(ramps_red[k]->red))); - memset(ramps_red[k]->green, 0, ramps_red[k]->green_size * sizeof(*(ramps_red[k]->green))); - memset(ramps_red[k]->blue, 0, ramps_red[k]->blue_size * sizeof(*(ramps_red[k]->blue))); - memset(ramps_green[k]->red, 0, ramps_green[k]->red_size * sizeof(*(ramps_green[k]->red))); - memset(ramps_green[k]->green, ~0, ramps_green[k]->green_size * sizeof(*(ramps_green[k]->green))); - memset(ramps_green[k]->blue, 0, ramps_green[k]->blue_size * sizeof(*(ramps_green[k]->blue))); - memset(ramps_blue[k]->red, 0, ramps_blue[k]->red_size * sizeof(*(ramps_blue[k]->red))); - memset(ramps_blue[k]->green, 0, ramps_blue[k]->green_size * sizeof(*(ramps_blue[k]->green))); - memset(ramps_blue[k]->blue, ~0, ramps_blue[k]->blue_size * sizeof(*(ramps_blue[k]->blue))); - t ((error = libgamma_crtc_get_gamma_ramps16(crtcs[k], ramps_saved[k]))); - } - - clut_state++; - - return 0; - fail: - if (error) - libgamma_perror(argv0, error); - else if (errno) - perror(argv0); - term_clut(); - errno = 0; - return -1; -} - - -/** - * The loop, using the graphic cards' colour lookup tables. - * - * @param interval The sleep interval, `NULL` for no sleep. - */ -static void loop_clut(const struct timespec* restrict interval) -{ - size_t i; - int error; - - while (!please_exit) - { - for (i = 0; crtcs[i]; i++) - t ((error = libgamma_crtc_set_gamma_ramps16(crtcs[i], *(ramps_red[i])))); - if (interval) - t ((errno = clock_nanosleep(CLOCK_MONOTONIC, 0, interval, NULL))); - - for (i = 0; crtcs[i]; i++) - t ((error = libgamma_crtc_set_gamma_ramps16(crtcs[i], *(ramps_green[i])))); - if (interval) - t ((errno = clock_nanosleep(CLOCK_MONOTONIC, 0, interval, NULL))); - - for (i = 0; crtcs[i]; i++) - t ((error = libgamma_crtc_set_gamma_ramps16(crtcs[i], *(ramps_blue[i])))); - if (interval) - t ((errno = clock_nanosleep(CLOCK_MONOTONIC, 0, interval, NULL))); - } - return; - fail: - if (error) - libgamma_perror(argv0, error), errno = 0; -} - - -/** - * The loop, using Linux VT. - * - * @param interval The sleep interval, `NULL` for no sleep. - */ -static void loop_vt(const struct timespec* restrict interval) -{ - while (!please_exit) - { - t (printf("\033]P0FF0000\033[2J") == -1); - t (fflush(stdout)); - if (interval) - t ((errno = clock_nanosleep(CLOCK_MONOTONIC, 0, interval, NULL))); - - t (printf("\033]P000FF00\033[2J") == -1); - t (fflush(stdout)); - if (interval) - t ((errno = clock_nanosleep(CLOCK_MONOTONIC, 0, interval, NULL))); - - t (printf("\033]P00000FF\033[2J") == -1); - t (fflush(stdout)); - if (interval) - t ((errno = clock_nanosleep(CLOCK_MONOTONIC, 0, interval, NULL))); - } - return; - fail: - return; -} - - -/** - * Signal handler for signals that exit the program. - * - * @param signo The caught signal. - */ -static void sigexit(int signo) -{ - signal(signo, sigexit); - please_exit = 1; -} - - -int main(int argc, char* argv[]) -{ - int started = 0; - int with_sleep = 0; - struct timespec interval; - int status, vt = 0, c = 0; - pid_t pid = -1; - int saved_errno; - - for (argv0 = (argc ? "unstickpixels" : *argv); c != -1;) - switch ((c = getopt(argc, argv, "v"))) - { - case 'v': vt = 1; - case -1: break; - case '?': usage(); - default: assert(0), abort(); - } - if (optind < argc) - t (get_interval(argv[optind++], &interval, &with_sleep)); - if (optind < argc) - usage(); - - printf("\033[?25l\033[H\033[2J"); - printf(WELCOME_MESSAGE); - fflush(stdout); - - siginterrupt(SIGHUP, 1); - siginterrupt(SIGTERM, 1); - siginterrupt(SIGINT, 1); - siginterrupt(SIGQUIT, 1); - signal(SIGHUP, sigexit); - signal(SIGTERM, sigexit); - signal(SIGINT, sigexit); - signal(SIGQUIT, sigexit); - - if (read(STDIN_FILENO, &started, 1) < 0) - goto done; - started = 1; - - if (vt) - t (printf("\033[H") == -1); - else - t (printf("\033[H\033[2JIf you can read this, try '%s -v'.\n", argv0) == -1); - t (fflush(stdout)); - - t (vt ? 0 : init_clut()); - - t (pid = xfork(), pid == -1); - if (pid) - goto parent; - - (vt ? loop_vt : loop_clut)(with_sleep ? &interval : NULL); - - fail: - saved_errno = errno; - printf("%s\033[?25h\033[H\033[2J", (started && vt) ? "\033]P0000000" : ""); - fflush(stdout); - if (!vt) - term_clut(); - errno = saved_errno; - if (pid == -1) - { - if (errno == EINVAL) - usage(); - return (errno && (errno != EINTR)) ? (perror(argv0), 1) : 1; - } - return 0; - - parent: - waitpid(pid, &status, 0); - done: - if (!vt) - term_clut(); - printf("%s\033[?25h\033[H\033[2J", (started && vt) ? "\033]P0000000" : ""); - fflush(stdout); - return WIFEXITED(status) ? WEXITSTATUS(status) : 0; -} - |