aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--Makefile6
-rw-r--r--src/unstickpixels.c186
-rwxr-xr-xunstickpixels107
4 files changed, 192 insertions, 112 deletions
diff --git a/.gitignore b/.gitignore
index 76bb32e..87b0676 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,8 @@ __pycache__/
*.pdf
*.ps
*.dvi
+*.out
+*.o
+*.su
+*.gch
+
diff --git a/Makefile b/Makefile
index 647651f..e10e472 100644
--- a/Makefile
+++ b/Makefile
@@ -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', '')
-