From 3215dfbccd76221a726cdbd3bb6888b7053309a8 Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Wed, 22 Sep 2021 18:46:14 -0400 Subject: Remove Linux-specific utilities I haven't used these in ages. --- bin/psfed.c | 577 ------------------------------------------------------------ 1 file changed, 577 deletions(-) delete mode 100644 bin/psfed.c (limited to 'bin/psfed.c') diff --git a/bin/psfed.c b/bin/psfed.c deleted file mode 100644 index 4f46b500..00000000 --- a/bin/psfed.c +++ /dev/null @@ -1,577 +0,0 @@ -/* Copyright (C) 2018 C. McEnroe - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static const wchar_t CP437[256] = - L"\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼" - L"►◄↕‼¶§▬↨↑↓→←∟↔▲▼" - L" !\"#$%&'()*+,-./" - L"0123456789:;<=>?" - L"@ABCDEFGHIJKLMNO" - L"PQRSTUVWXYZ[\\]^_" - L"`abcdefghijklmno" - L"pqrstuvwxyz{|}~⌂" - L"ÇüéâäàåçêëèïîìÄÅ" - L"ÉæÆôöòûùÿÖÜ¢£¥₧ƒ" - L"áíóúñѪº¿⌐¬½¼¡«»" - L"░▒▓│┤╡╢╖╕╣║╗╝╜╛┐" - L"└┴┬├─┼╞╟╚╔╩╦╠═╬╧" - L"╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀" - L"αßΓπΣσµτΦΘΩδ∞φε∩" - L"≡±≥≤⌠⌡÷≈°∙·√ⁿ²■\0"; - -static struct { - uint32_t width; - uint32_t height; - uint32_t *buffer; - uint32_t background; -} frame; - -static void frameClear(void) { - for (uint32_t i = 0; i < frame.width * frame.height; ++i) { - frame.buffer[i] = frame.background; - } -} - -static void frameOpen(void) { - const char *dev = getenv("FRAMEBUFFER"); - if (!dev) dev = "/dev/fb0"; - - int fd = open(dev, O_RDWR); - if (fd < 0) err(EX_OSFILE, "%s", dev); - - struct fb_var_screeninfo info; - int error = ioctl(fd, FBIOGET_VSCREENINFO, &info); - if (error) err(EX_IOERR, "%s", dev); - - frame.width = info.xres; - frame.height = 3 * info.yres / 4; - frame.buffer = mmap( - NULL, sizeof(*frame.buffer) * frame.width * frame.height, - PROT_READ | PROT_WRITE, MAP_SHARED, - fd, 0 - ); - if (frame.buffer == MAP_FAILED) err(EX_IOERR, "%s", dev); - close(fd); - - frame.background = frame.buffer[0]; - atexit(frameClear); -} - -static const uint32_t Magic = 0x864AB572; -static const uint32_t Version = 0; -static const uint32_t FlagUnicode = 1 << 0; -static uint32_t bytes(uint32_t bits) { - return (bits + 7) / 8; -} - -static char *path; -static struct { - uint32_t magic; - uint32_t version; - uint32_t size; - uint32_t flags; - struct { - uint32_t len; - uint32_t size; - uint32_t height; - uint32_t width; - } glyph; -} header; -static uint8_t *glyphs; - -static void fileRead(uint32_t newLen, uint32_t newWidth, uint32_t newHeight) { - FILE *file = fopen(path, "r"); - if (file) { - size_t len = fread(&header, sizeof(header), 1, file); - if (ferror(file)) err(EX_IOERR, "%s", path); - if (len < 1) errx(EX_DATAERR, "%s: truncated header", path); - - } else { - if (errno != ENOENT) err(EX_NOINPUT, "%s", path); - header.magic = Magic; - header.version = Version; - header.size = sizeof(header); - header.flags = 0; - header.glyph.len = newLen; - header.glyph.size = bytes(newWidth) * newHeight; - header.glyph.height = newHeight; - header.glyph.width = newWidth; - } - - if (header.magic != Magic) { - errx(EX_DATAERR, "%s: invalid magic %08X", path, header.magic); - } - if (header.version != Version) { - errx(EX_DATAERR, "%s: unsupported version %u", path, header.version); - } - if (header.flags & FlagUnicode) { - errx(EX_DATAERR, "%s: unsupported unicode table", path); - } - if (header.flags) { - errx(EX_DATAERR, "%s: unsupported flags %08X", path, header.flags); - } - - if (file && header.size > sizeof(header)) { - int error = fseek(file, header.size, SEEK_SET); - if (error) err(EX_IOERR, "%s", path); - - warnx("%s: truncating long header", path); - header.size = sizeof(header); - } - - glyphs = calloc(header.glyph.len, header.glyph.size); - if (!glyphs) err(EX_OSERR, "calloc"); - - if (file) { - size_t len = fread(glyphs, header.glyph.size, header.glyph.len, file); - if (ferror(file)) err(EX_IOERR, "%s", path); - if (len < header.glyph.len) { - errx(EX_DATAERR, "%s: truncated glyphs", path); - } - fclose(file); - } -} - -static void fileWrite(void) { - FILE *file = fopen(path, "w"); - if (!file) err(EX_CANTCREAT, "%s", path); - - fwrite(&header, sizeof(header), 1, file); - if (ferror(file)) err(EX_IOERR, "%s", path); - - fwrite(glyphs, header.glyph.size, header.glyph.len, file); - if (ferror(file)) err(EX_IOERR, "%s", path); - - int error = fclose(file); - if (error) err(EX_IOERR, "%s", path); -} - -static uint8_t *glyph(uint32_t index) { - return &glyphs[header.glyph.size * index]; -} -static uint8_t *bitByte(uint32_t index, uint32_t x, uint32_t y) { - return &glyph(index)[bytes(header.glyph.width) * y + x / 8]; -} -static uint8_t bitGet(uint32_t index, uint32_t x, uint32_t y) { - return *bitByte(index, x, y) >> (7 - x % 8) & 1; -} -static void bitFlip(uint32_t index, uint32_t x, uint32_t y) { - *bitByte(index, x, y) ^= 1 << (7 - x % 8); -} -static void bitSet(uint32_t index, uint32_t x, uint32_t y, uint8_t bit) { - *bitByte(index, x, y) &= ~(1 << (7 - x % 8)); - *bitByte(index, x, y) |= bit << (7 - x % 8); -} - -static void drawGlyph( - uint32_t destX, uint32_t destY, uint32_t scale, uint32_t index, - uint32_t selectX, uint32_t selectY, uint32_t guideX, uint32_t guideY -) { - destX <<= scale; - destY <<= scale; - - for (uint32_t y = 0; y < (header.glyph.height << scale); ++y) { - if (destY + y >= frame.height) break; - for (uint32_t x = 0; x < (header.glyph.width << scale); ++x) { - if (destX + x >= frame.width) break; - - uint32_t glyphX = x >> scale; - uint32_t glyphY = y >> scale; - uint32_t fill = -bitGet(index, glyphX, glyphY); - if (selectX & 1 << glyphX && selectY & 1 << glyphY) fill ^= 0x77; - if (guideX & 1 << glyphX || guideY & 1 << glyphY) fill ^= 0x3300; - - frame.buffer[frame.width * (destY + y) + destX + x] = fill; - } - } -} - -static void drawBorder(uint32_t destX, uint32_t destY, uint32_t scale) { - destX <<= scale; - destY <<= scale; - - for (uint32_t y = 0; y < destY; ++y) { - if (y >= frame.height) break; - uint32_t fill = -(y >> scale & 1) ^ 0x555555; - for (uint32_t x = 0; x < (uint32_t)(1 << scale); ++x) { - if (destX + x >= frame.width) break; - frame.buffer[frame.width * y + destX + x] = fill; - } - } - - for (uint32_t x = 0; x < destX; ++x) { - if (x >= frame.width) break; - uint32_t fill = -(x >> scale & 1) ^ 0x555555; - for (uint32_t y = 0; y < (uint32_t)(1 << scale); ++y) { - if (destY + y >= frame.height) break; - frame.buffer[frame.width * (destY + y) + x] = fill; - } - } -} - -enum { LF = '\n', Esc = '\33', Del = '\177' }; - -static enum { - Normal, - Edit, - Preview, - Discard, -} mode; - -static struct { - uint32_t scale; - uint32_t index; - bool modified; - bool to; - uint32_t from; -} normal; - -static struct { - uint32_t scale; - uint32_t index; - uint32_t x; - uint32_t y; - uint32_t guideX; - uint32_t guideY; - uint8_t *undo; - uint8_t *copy; -} edit = { - .scale = 4, -}; - -static const uint32_t NormalCols = 32; -static void drawNormal(void) { - for (uint32_t i = 0; i < header.glyph.len; ++i) { - drawGlyph( - header.glyph.width * (i % NormalCols), - header.glyph.height * (i / NormalCols), - normal.scale, i, - -(i == normal.index), -(i == normal.index), 0, 0 - ); - } -} - -static void normalDec(uint32_t n) { - if (normal.index >= n) normal.index -= n; -} -static void normalInc(uint32_t n) { - if (normal.index + n < header.glyph.len) normal.index += n; -} -static void normalPrint(const char *prefix) { - if (normal.index <= 256) { - printf( - "%s: %02X '%lc'\n", - prefix, normal.index, (wint_t)CP437[normal.index] - ); - } else { - printf("%s: %02X\n", prefix, normal.index); - } -} - -static void inputNormal(char ch) { - if (normal.to) { - if (ch < header.glyph.len) normal.index = ch; - normalPrint("index"); - normal.to = false; - return; - } - - switch (ch) { - break; case 'q': { - if (!normal.modified) exit(EX_OK); - mode = Discard; - } - break; case 'w': { - fileWrite(); - printf("write: %s\n", path); - normal.modified = false; - } - break; case '-': if (normal.scale) normal.scale--; frameClear(); - break; case '+': normal.scale++; - break; case 'h': normalDec(1); normalPrint("index"); - break; case 'l': normalInc(1); normalPrint("index"); - break; case 'k': normalDec(NormalCols); normalPrint("index"); - break; case 'j': normalInc(NormalCols); normalPrint("index"); - break; case 'f': normal.from = normal.index; normal.to = true; - break; case 047: normal.index = normal.from; normalPrint("index"); - break; case 'y': { - if (!edit.copy) edit.copy = malloc(header.glyph.size); - if (!edit.copy) err(EX_OSERR, "malloc"); - memcpy(edit.copy, glyph(normal.index), header.glyph.size); - normalPrint("copy"); - } - break; case 'e': { - normal.modified = true; - edit.index = normal.index; - if (!edit.undo) edit.undo = malloc(header.glyph.size); - if (!edit.undo) err(EX_OSERR, "malloc"); - memcpy(edit.undo, glyph(edit.index), header.glyph.size); - mode = Edit; - frameClear(); - } - break; case 'i': mode = Preview; frameClear(); - } -} - -static void drawEdit(void) { - drawGlyph( - 0, 0, edit.scale, edit.index, - 1 << edit.x, 1 << edit.y, edit.guideX, edit.guideY - ); - drawBorder(header.glyph.width, header.glyph.height, edit.scale); - drawGlyph( - header.glyph.width << edit.scale, - header.glyph.height << edit.scale, - 0, edit.index, - 0, 0, 0, 0 - ); -} - -static void inputEdit(char ch) { - switch (ch) { - break; case Esc: mode = Normal; frameClear(); - - break; case '-': if (edit.scale) edit.scale--; frameClear(); - break; case '+': edit.scale++; - break; case 'g': edit.guideY ^= 1 << edit.y; - break; case 'G': edit.guideX ^= 1 << edit.x; - - break; case 'h': if (edit.x) edit.x--; - break; case 'l': if (edit.x + 1 < header.glyph.width) edit.x++; - break; case 'k': if (edit.y) edit.y--; - break; case 'j': if (edit.y + 1 < header.glyph.height) edit.y++; - break; case ' ': bitFlip(edit.index, edit.x, edit.y); - - break; case 'r': { - for (uint32_t y = 0; y < header.glyph.height; ++y) { - for (uint32_t x = 0; x < header.glyph.width; ++x) { - bitFlip(edit.index, x, y); - } - } - } - - break; case 'H': { - for (uint32_t x = 0; x < header.glyph.width; ++x) { - for (uint32_t y = 0; y < header.glyph.height; ++y) { - if (x + 1 < header.glyph.width) { - bitSet(edit.index, x, y, bitGet(edit.index, x + 1, y)); - } else { - bitSet(edit.index, x, y, 0); - } - } - } - } - - break; case 'L': { - uint32_t width = header.glyph.width; - for (uint32_t x = width - 1; x < width; --x) { - for (uint32_t y = 0; y < header.glyph.height; ++y) { - if (x - 1 < width) { - bitSet(edit.index, x, y, bitGet(edit.index, x - 1, y)); - } else { - bitSet(edit.index, x, y, 0); - } - } - } - } - - break; case 'K': { - for (uint32_t y = 0; y < header.glyph.height; ++y) { - for (uint32_t x = 0; x < header.glyph.width; ++x) { - if (y + 1 < header.glyph.height) { - bitSet(edit.index, x, y, bitGet(edit.index, x, y + 1)); - } else { - bitSet(edit.index, x, y, 0); - } - } - } - } - - break; case 'J': { - uint32_t height = header.glyph.height; - for (uint32_t y = height - 1; y < height; --y) { - for (uint32_t x = 0; x < header.glyph.width; ++x) { - if (y - 1 < height) { - bitSet(edit.index, x, y, bitGet(edit.index, x, y - 1)); - } else { - bitSet(edit.index, x, y, 0); - } - } - } - } - - break; case 'p': { - if (!edit.copy) break; - memcpy(glyph(edit.index), edit.copy, header.glyph.size); - } - break; case 'u': { - if (!edit.undo) break; - memcpy(glyph(edit.index), edit.undo, header.glyph.size); - } - } -} - -enum { PreviewRows = 8, PreviewCols = 64 }; -static struct { - uint32_t glyphs[PreviewRows * PreviewCols]; - uint32_t index; -} preview; - -static void drawPreview(void) { - for (uint32_t i = 0; i < PreviewRows * PreviewCols; ++i) { - drawGlyph( - header.glyph.width * (i % PreviewCols), - header.glyph.height * (i / PreviewCols), - 0, preview.glyphs[i], - -(i == preview.index), -(i == preview.index), 0, 0 - ); - } -} - -static void inputPreview(char ch) { - switch (ch) { - break; case Esc: mode = Normal; frameClear(); - break; case Del: { - if (preview.index) preview.index--; - preview.glyphs[preview.index] = 0; - } - break; case LF: { - uint32_t tail = PreviewCols - (preview.index % PreviewCols); - memset( - &preview.glyphs[preview.index], - 0, sizeof(preview.glyphs[0]) * tail - ); - preview.index += tail; - } - break; default: preview.glyphs[preview.index++] = ch; - } - preview.index %= PreviewRows * PreviewCols; -} - -static void drawDiscard(void) { - printf("discard modifications? "); - fflush(stdout); -} - -static void inputDiscard(char ch) { - printf("%c\n", ch); - if (ch == 'Y' || ch == 'y') exit(EX_OK); - mode = Normal; -} - -static void draw(void) { - switch (mode) { - break; case Normal: drawNormal(); - break; case Edit: drawEdit(); - break; case Preview: drawPreview(); - break; case Discard: drawDiscard(); - } -} - -static void input(char ch) { - switch (mode) { - break; case Normal: inputNormal(ch); - break; case Edit: inputEdit(ch); - break; case Preview: inputPreview(ch); - break; case Discard: inputDiscard(ch); - } -} - -static struct termios saveTerm; -static void restoreTerm(void) { - tcsetattr(STDIN_FILENO, TCSADRAIN, &saveTerm); -} - -int main(int argc, char *argv[]) { - setlocale(LC_CTYPE, ""); - - uint32_t newLen = 256; - uint32_t newWidth = 8; - uint32_t newHeight = 16; - uint32_t setHeight = 0; - - int opt; - while (0 < (opt = getopt(argc, argv, "H:g:h:w:"))) { - switch (opt) { - break; case 'H': setHeight = strtoul(optarg, NULL, 0); - break; case 'g': newLen = strtoul(optarg, NULL, 0); - break; case 'h': newHeight = strtoul(optarg, NULL, 0); - break; case 'w': newWidth = strtoul(optarg, NULL, 0); - break; default: return EX_USAGE; - } - } - if (!newLen || !newWidth || !newHeight) return EX_USAGE; - if (optind == argc) return EX_USAGE; - - path = strdup(argv[optind]); - fileRead(newLen, newWidth, newHeight); - - if (setHeight) { - if (setHeight < header.glyph.height) { - errx(EX_CONFIG, "cannot decrease height"); - } - - uint32_t setSize = bytes(header.glyph.width) * setHeight; - uint8_t *setGlyphs = calloc(header.glyph.len, setSize); - for (uint32_t i = 0; i < header.glyph.len; ++i) { - memcpy(&setGlyphs[setSize * i], glyph(i), header.glyph.size); - } - free(glyphs); - glyphs = setGlyphs; - - header.glyph.height = setHeight; - header.glyph.size = setSize; - normal.modified = true; - } - - frameOpen(); - frameClear(); - - int error = tcgetattr(STDIN_FILENO, &saveTerm); - if (error) err(EX_IOERR, "tcgetattr"); - atexit(restoreTerm); - - struct termios term = saveTerm; - term.c_lflag &= ~(ICANON | ECHO); - error = tcsetattr(STDIN_FILENO, TCSADRAIN, &term); - if (error) err(EX_IOERR, "tcsetattr"); - - for (;;) { - draw(); - char ch; - ssize_t size = read(STDIN_FILENO, &ch, 1); - if (size < 0) err(EX_IOERR, "read"); - if (!size) return EX_SOFTWARE; - input(ch); - } -} -- cgit 1.4.1