diff options
-rw-r--r-- | .gitignore | 5 | ||||
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | src/unstickpixels.c | 186 | ||||
-rwxr-xr-x | unstickpixels | 107 |
4 files changed, 192 insertions, 112 deletions
@@ -15,3 +15,8 @@ __pycache__/ *.pdf *.ps *.dvi +*.out +*.o +*.su +*.gch + @@ -15,11 +15,7 @@ all: doc doc: info -info: unstickpixels.info.gz - -%.info.gz: info/%.texinfo - makeinfo "$<" - gzip -9 -f "$*.info" +info: unstickpixels.info install: install-cmd install-license install-info diff --git a/src/unstickpixels.c b/src/unstickpixels.c new file mode 100644 index 0000000..817ba83 --- /dev/null +++ b/src/unstickpixels.c @@ -0,0 +1,186 @@ +/** + * 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/>. + */ +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <signal.h> +#include <time.h> +#include <errno.h> +#include <ctype.h> +#include <sys/wait.h> + + + +#define t(...) do { if (__VA_ARGS__) goto fail; } while (0) + + +#define WELCOME_MESSAGE \ + "\033[?25l\033[H\033[2J" \ + "\033[H\033[01;31mWARNING: Do not used 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; + + + +/** + * 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* arg, struct timespec* interval, int* nonzero) +{ + char* end; + *nonzero = 1; + t (!isdigit(*arg)); + interval->tv_sec = (time_t)(errno = 0, strtol)(arg, &end, 10); + t (errno || *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; +} + + +int main(int argc, char* argv[]) +{ + int started = 0; + int with_sleep = 0; + struct timespec interval; + int _status; + pid_t pid; + + argv0 = (argc ? "unstickpixels" : *argv); + + if (argc > 1) + t (argv[1], &interval, &with_sleep); + + printf(WELCOME_MESSAGE); + fflush(stdout); + + if (read(STDIN_FILENO, &started, 1) < 0) + goto done; + started = 1; + + pid = xfork(); + if (pid == -1) + return perror(argv0), 1; + else if (pid) + goto parent; + + t (printf("\033[H") == -1); + t (fflush(stdout)); + + for (;;) + { + t (printf("\033]P0FF0000\033[2J") == -1); + t (fflush(stdout)); + if (with_sleep) + clock_nanosleep(CLOCK_MONOTONIC, 0, &interval, NULL); + + t (printf("\033]P000FF00\033[2J") == -1); + t (fflush(stdout)); + if (with_sleep) + clock_nanosleep(CLOCK_MONOTONIC, 0, &interval, NULL); + + t (printf("\033]P00000FF\033[2J") == -1); + t (fflush(stdout)); + if (with_sleep) + clock_nanosleep(CLOCK_MONOTONIC, 0, &interval, NULL); + } + + fail: + return 0; + + parent: + waitpid(pid, &_status, 0); + done: + printf("%s\033[?25h\033[H\033[2J", started ? "\033]P0000000" : ""); + fflush(stdout); + return 0; +} + diff --git a/unstickpixels b/unstickpixels deleted file mode 100755 index b0fc8eb..0000000 --- a/unstickpixels +++ /dev/null @@ -1,107 +0,0 @@ -#!/usr/bin/env python -## -# 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/>. -## - -import sys -import time -from subprocess import Popen, PIPE - - -def print(text, end = '\n'): - sys.stdout.buffer.write((text + end).encode('utf-8')) - sys.stdout.buffer.flush() - - -sleep = 0 if len(sys.argv) < 2 else int(sys.argv[1]) - - -(height, width) = Popen(['stty', 'size'], stdout=PIPE).communicate()[0].decode('utf-8', 'replace').split(' ') -(height, width) = (int(height), int(width)) -COPYING = ['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/>.'] - -print('\033[?25l\033[H\033[2J\033[%i;%iH%s' % (height - len(COPYING) + 1, 1, '\n'.join(COPYING)), '') -print('\033[H\033[01;31mWARNING: Do not used this if you have epilepsia.\033[00m') -print('') -print('It is recommended to massage the defective dots, whilst') -print('running this program.') -print('') -print('Press C-c to quit, and Enter to start (C-c will quit).') -print('') -print('') -print('You should not have to run this program. If the manufacture or') -print('reseller of your monitor refuse to replace or repair the monitor') -print('that was broken, because of manufacturing error, when it was') -print('chiped to you, please consider yelling at the support, threaten') -print('to report the personally because of involvement in organised') -print('crime (not replacing hardware that was chipped broken when you') -print('selled it is a crime, and they do this in an organised fashion') -print('to make money), call their executive director persistently at') -print('inconvenient times, report them applicable board for consumer') -print('disputes/complaints or equivalent agency. If this program does') -print('not help, and the manufacture is Packard Bell, or its') -print('supersidiary Acer, tell them that you have tried a program') -print('that was prompted by the complete suckness and incapability') -print('to repair defects that they have agreed to repair. They suck!') - -started = False -try: - input() - started = True - print('\033[H', '') - if sleep == 0: - while True: - sys.stdout.buffer.write('\033]P0FF0000\033[2J'.encode('utf-8')) - sys.stdout.buffer.flush() - sys.stdout.buffer.write('\033]P000FF00\033[2J'.encode('utf-8')) - sys.stdout.buffer.flush() - sys.stdout.buffer.write('\033]P00000FF\033[2J'.encode('utf-8')) - sys.stdout.buffer.flush() - else: - sleep /= 1000 - while True: - sys.stdout.buffer.write('\033]P0FF0000\033[2J'.encode('utf-8')) - sys.stdout.buffer.flush() - time.sleep(sleep) - sys.stdout.buffer.write('\033]P000FF00\033[2J'.encode('utf-8')) - sys.stdout.buffer.flush() - time.sleep(sleep) - sys.stdout.buffer.write('\033]P00000FF\033[2J'.encode('utf-8')) - sys.stdout.buffer.flush() - time.sleep(sleep) -except: - pass -if started: - print('\033]P0000000', '') -print('\033[?25h\033[H\033[2J', '') - |