diff options
| author | Louis Burda <quent.burda@gmail.com> | 2022-10-03 01:49:49 +0200 |
|---|---|---|
| committer | Louis Burda <quent.burda@gmail.com> | 2022-10-18 12:48:41 +0200 |
| commit | 00f06c0f2ecfad3c26b8a3e3ea1114908a6dc8d0 (patch) | |
| tree | 7291c64d16c69b6a5ce11ae33839a41d1487f445 | |
| download | morse-00f06c0f2ecfad3c26b8a3e3ea1114908a6dc8d0.tar.gz morse-00f06c0f2ecfad3c26b8a3e3ea1114908a6dc8d0.zip | |
Initial prototype
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Makefile | 10 | ||||
| -rw-r--r-- | lut.c | 40 | ||||
| -rw-r--r-- | morse.c | 121 |
4 files changed, 172 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d7abc1f --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +morse diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d67c2b7 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +LDLIBS = -lX11 + +all: morse + +clean: + rm -f morse + +morse: morse.c + +.PHONY: all clean @@ -0,0 +1,40 @@ +static const char *morse_lut[] = { + "A" ".-", + "B" "-...", + "C" "-.-.", + "D" "-..", + "E" ".", + "F" "..-.", + "G" "--.", + "H" "....", + "I" "..", + "J" ".---", + "K" "-.-", + "L" ".-..", + "M" "--", + "N" "-.", + "O" "---", + "P" ".--.", + "Q" "--.-", + "R" ".-.", + "S" "...", + "T" "-", + "U" "..-", + "V" "...-", + "W" ".--", + "X" "-..-", + "Y" "-.--", + "Z" "--..", + "1" ".----", + "2" "..---", + "3" "...--", + "4" "....-", + "5" ".....", + "6" "-....", + "7" "--...", + "8" "---..", + "9" "----.", + "0" "-----" +}; + + @@ -0,0 +1,121 @@ +#include <X11/X.h> +#include <X11/Xlib.h> +#include <X11/keysym.h> + +#include <time.h> +#include <unistd.h> +#include <time.h> +#include <err.h> +#include <string.h> +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> + +#include "lut.c" + +#define ARRLEN(x) (sizeof(x) / sizeof((x)[0])) + +static char translate(const char *seq); + +static const int long_ms = 300; +static const int letter_ms = 1000; + +static char seqbuf[64]; +static int seqlen; + +char +translate(const char *seq) +{ + int i; + + for (i = 0; i < ARRLEN(morse_lut); i++) { + if (!strcmp(seq, morse_lut[i] + 1)) + return morse_lut[i][0]; + } + + return '?'; +} + +int +main(int argc, const char **argv) +{ + struct timespec press, release; + unsigned long diff_ms; + bool is_pressed; + int timeout_cnt; + Display *display; + XEvent event; + Window root; + int sleep_cnt; + int x11fd; + int ret; + + setvbuf(stdout, NULL, _IONBF, 0); + + display = XOpenDisplay(NULL); + if (!display) errx(1, "No display found"); + + root = DefaultRootWindow(display); + XGrabKey(display, XKeysymToKeycode(display, 'n'), 0, root, + False, GrabModeAsync, GrabModeAsync); + + memset(&press, 0, sizeof(struct timespec)); + memset(&release, 0, sizeof(struct timespec)); + + seqlen = 0; + seqbuf[seqlen] = '\0'; + + x11fd = XConnectionNumber(display); + + timeout_cnt = 10; + is_pressed = false; + while (true) { + /* inaccurate and hacky but select() + * with XGrabKey is not working */ + sleep_cnt = 0; + while (!XPending(display) && sleep_cnt < letter_ms) { + usleep(1000); + sleep_cnt++; + } + + if (!XPending(display)) { + if (!is_pressed) { + timeout_cnt++; + if (timeout_cnt == 1) { + putchar(translate(seqbuf)); + seqlen = 0; + seqbuf[seqlen] = '\0'; + } + if (timeout_cnt == 2) + putchar(' '); + } + continue; + } else { + timeout_cnt = 0; + } + + XNextEvent(display, &event); + if (event.type == KeyPress && !is_pressed) { + is_pressed = true; + if (clock_gettime(CLOCK_REALTIME, &press)) + err(1, "clock_gettime"); + } else if (event.type == KeyRelease && is_pressed) { + is_pressed = false; + if (clock_gettime(CLOCK_REALTIME, &release)) + err(1, "clock_gettime"); + if (press.tv_sec == 0) continue; + diff_ms = (release.tv_sec - press.tv_sec) * 1000 + + (release.tv_nsec - press.tv_nsec) / 1000000; + if (seqlen >= sizeof(seqbuf) - 1) + continue; + if (diff_ms > long_ms) { + seqbuf[seqlen++] = '-'; + } else { + seqbuf[seqlen++] = '.'; + } + seqbuf[seqlen] = '\0'; + } + } + + XCloseDisplay(display); +} |
