The repository formerly known as dotfiles
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

fb.c 2.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /* Copyright (c) 2018, Curtis McEnroe <programble@gmail.com>
  2. *
  3. * This program is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU Affero General Public License as published by
  5. * the Free Software Foundation, either version 3 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU Affero General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Affero General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include <err.h>
  17. #include <fcntl.h>
  18. #include <linux/fb.h>
  19. #include <stdbool.h>
  20. #include <stdint.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <sys/ioctl.h>
  25. #include <sys/mman.h>
  26. #include <sysexits.h>
  27. #include <termios.h>
  28. #include <unistd.h>
  29. #include "gfx.h"
  30. static struct termios saveTerm;
  31. static void restoreTerm(void) {
  32. tcsetattr(STDERR_FILENO, TCSADRAIN, &saveTerm);
  33. }
  34. int main(int argc, char *argv[]) {
  35. int error;
  36. error = init(argc, argv);
  37. if (error) return error;
  38. const char *path = getenv("FRAMEBUFFER");
  39. if (!path) path = "/dev/fb0";
  40. int fb = open(path, O_RDWR);
  41. if (fb < 0) err(EX_OSFILE, "%s", path);
  42. struct fb_var_screeninfo info;
  43. error = ioctl(fb, FBIOGET_VSCREENINFO, &info);
  44. if (error) err(EX_IOERR, "%s", path);
  45. size_t size = 4 * info.xres * info.yres;
  46. uint32_t *buf = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);
  47. if (buf == MAP_FAILED) err(EX_IOERR, "%s", path);
  48. error = tcgetattr(STDERR_FILENO, &saveTerm);
  49. if (error) err(EX_IOERR, "tcgetattr");
  50. atexit(restoreTerm);
  51. struct termios term = saveTerm;
  52. term.c_lflag &= ~(ICANON | ECHO);
  53. error = tcsetattr(STDERR_FILENO, TCSADRAIN, &term);
  54. if (error) err(EX_IOERR, "tcsetattr");
  55. uint32_t saveBg = buf[0];
  56. uint32_t back[info.xres * info.yres];
  57. for (;;) {
  58. draw(back, info.xres, info.yres);
  59. memcpy(buf, back, size);
  60. char in;
  61. ssize_t len = read(STDERR_FILENO, &in, 1);
  62. if (len < 0) err(EX_IOERR, "read");
  63. if (!len) return EX_DATAERR;
  64. if (!input(in)) {
  65. for (uint32_t i = 0; i < info.xres * info.yres; ++i) {
  66. buf[i] = saveBg;
  67. }
  68. fprintf(stderr, "%s\n", status());
  69. return EX_OK;
  70. }
  71. }
  72. }