|
|
vtv-viewer.c - vtv-tools - virtual terminal video tools |
|
|
 |
git clone git://bitreich.org/vtv-tools git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/vtv-tools (git://bitreich.org) |
|
|
 |
Log |
|
|
 |
Files |
|
|
 |
Refs |
|
|
 |
Tags |
|
|
 |
README |
|
|
 |
LICENSE |
|
|
|
--- |
|
|
|
vtv-viewer.c (2512B) |
|
|
|
--- |
|
|
|
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 } |
|