URI: 
       vtv-viewer.c - vtv-tools - virtual terminal video tools
  HTML git clone git://bitreich.org/vtv-tools  git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/vtv-tools
   DIR Log
   DIR Files
   DIR Refs
   DIR Tags
   DIR README
   DIR LICENSE
       ---
       vtv-viewer.c (2513B)
       ---
            1 // Copyright 2023 Troels Henriksen <athas@sigkill.dk>
            2 //
            3 // See LICENSE file for licensing information.
            4 
            5 #include <assert.h>
            6 #include <stdint.h>
            7 #include <stdio.h>
            8 #include <stdlib.h>
            9 #include <string.h>
           10 #include <sys/ioctl.h>
           11 #include <termios.h>
           12 #include <unistd.h>
           13 #include <errno.h>
           14 
           15 #include "vtv.h"
           16 
           17 struct termios orig_termios;
           18 
           19 void cooked_mode() {
           20   tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios);
           21   printf("\033[?25h");
           22 }
           23 
           24 void raw_mode() {
           25   printf("\033[?25l");
           26 
           27   tcgetattr(STDIN_FILENO, &orig_termios);
           28   atexit(cooked_mode);
           29 
           30   struct termios raw = orig_termios;
           31   raw.c_iflag &= ~(IXON);
           32   raw.c_lflag &= ~(ECHO | ICANON);
           33   raw.c_cc[VMIN] = 1;
           34   raw.c_cc[VTIME] = 0;
           35   tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
           36 }
           37 
           38 void move(int x, int y) { printf("\033[%d;%dH", y, x); }
           39 void home() { printf("\033[;H"); }
           40 void clear_screen() { printf("\033[2J"); }
           41 void clear_line() { printf("\033[2K"); }
           42 void def() { printf("\033[0m"); }
           43 
           44 struct {
           45   int frame;
           46   int lines_per_frame;
           47   struct vtv* vtv;
           48 } state;
           49 
           50 void show_status() {
           51   printf("Frame (h/l): %5d    Framesize (j/k): %5d\n",
           52          state.frame, state.lines_per_frame);
           53 }
           54 
           55 void show_frame() {
           56   vtv_show_frame(state.vtv, stdout, state.frame, state.lines_per_frame,
           57                  "\033[0m   MISSING LINE");
           58 }
           59 
           60 int view(struct vtv* vtv) {
           61   raw_mode();
           62 
           63   state.frame = 0;
           64   state.lines_per_frame = 25;
           65   state.vtv = vtv;
           66 
           67   while (1) {
           68     home();
           69     def();
           70     clear_screen();
           71     show_frame();
           72     move(0, state.lines_per_frame+1);
           73     def();
           74     // It is intentional that the status is at the bottom, as VTV
           75     // files may assume that they are drawn from line 0.
           76     show_status();
           77     switch(getchar()) {
           78     case 'q':
           79       return 0;
           80     case 'h':
           81       if (state.frame != 0) { state.frame--; }
           82       break;
           83     case 'l':
           84       state.frame = (state.frame+1);
           85       break;
           86     case 'j':
           87       if (state.lines_per_frame != 0) {state.lines_per_frame--; }
           88       break;
           89     case 'k':
           90       state.lines_per_frame++;
           91       break;
           92     }
           93   }
           94 }
           95 
           96 int main(int argc, char** argv) {
           97   if (argc != 2) {
           98     fprintf(stderr, "Usage: %s FILE\n", argv[0]);
           99     return 1;
          100   }
          101 
          102   FILE* f = fopen(argv[1], "r");
          103   if (f == NULL) {
          104     fprintf(stderr, "%s: cannot open %s: %s\n",
          105             argv[0], argv[1], strerror(errno));
          106   }
          107 
          108   struct vtv *vtv = vtv_read(f);
          109 
          110   if (vtv == NULL) {
          111     fprintf(stderr, "%s: failed to read from %s: %s\n",
          112             argv[0], argv[1], strerror(errno));
          113   }
          114 
          115   int ret = view(vtv);
          116   vtv_free(vtv);
          117   return ret;
          118 }
          119