|
|
catpoint.c - catpoint - Catpoint simple presenting software. |
|
|
 |
git clone git://bitreich.org/catpoint/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/catpoint/ (git://bitreich.org) |
|
|
 |
Log |
|
|
 |
Files |
|
|
 |
Refs |
|
|
 |
Tags |
|
|
 |
README |
|
|
 |
LICENSE |
|
|
|
--- |
|
|
|
catpoint.c (3893B) |
|
|
|
--- |
|
|
|
1 /* See LICENSE file for license details. */ |
|
|
|
2 |
|
|
|
3 #include <sys/mman.h> |
|
|
|
4 #include <sys/stat.h> |
|
|
|
5 #include <sys/types.h> |
|
|
|
6 |
|
|
|
7 #include <curses.h> |
|
|
|
8 #include <errno.h> |
|
|
|
9 #include <fcntl.h> |
|
|
|
10 #include <locale.h> |
|
|
|
11 #include <signal.h> |
|
|
|
12 #include <stdarg.h> |
|
|
|
13 #include <stdio.h> |
|
|
|
14 #include <stdlib.h> |
|
|
|
15 #include <string.h> |
|
|
|
16 #include <unistd.h> |
|
|
|
17 |
|
|
|
18 void die(const char *, ...); |
|
|
|
19 |
|
|
|
20 char *currentslidep, **slidefiles; /* the slides */ |
|
|
|
21 int nslides, currentslide, currentslidelen; |
|
|
|
22 |
|
|
|
23 volatile sig_atomic_t slidechanged = 1; |
|
|
|
24 |
|
|
|
25 void |
|
|
|
26 unloadcurrentslide(void) |
|
|
|
27 { |
|
|
|
28 if (currentslidep == NULL) |
|
|
|
29 return; |
|
|
|
30 |
|
|
|
31 if (munmap(currentslidep, currentslidelen) < 0) |
|
|
|
32 die("munmap: %s", slidefiles[currentslide]); |
|
|
|
33 } |
|
|
|
34 |
|
|
|
35 void |
|
|
|
36 cleanup(void) |
|
|
|
37 { |
|
|
|
38 unloadcurrentslide(); |
|
|
|
39 |
|
|
|
40 endwin(); /* restore terminal */ |
|
|
|
41 } |
|
|
|
42 |
|
|
|
43 /* print to stderr, call cleanup() and _exit(). */ |
|
|
|
44 void |
|
|
|
45 die(const char *fmt, ...) |
|
|
|
46 { |
|
|
|
47 va_list ap; |
|
|
|
48 int saved_errno; |
|
|
|
49 |
|
|
|
50 saved_errno = errno; |
|
|
|
51 cleanup(); |
|
|
|
52 |
|
|
|
53 va_start(ap, fmt); |
|
|
|
54 vfprintf(stderr, fmt, ap); |
|
|
|
55 va_end(ap); |
|
|
|
56 |
|
|
|
57 if (saved_errno) |
|
|
|
58 fprintf(stderr, ": %s", strerror(saved_errno)); |
|
|
|
59 fflush(stderr); |
|
|
|
60 write(2, "\n", 1); |
|
|
|
61 |
|
|
|
62 _exit(1); |
|
|
|
63 } |
|
|
|
64 |
|
|
|
65 void |
|
|
|
66 quit(int sig) |
|
|
|
67 { |
|
|
|
68 cleanup(); |
|
|
|
69 _exit(128 + sig); |
|
|
|
70 } |
|
|
|
71 |
|
|
|
72 void |
|
|
|
73 loadcurrentslide(char **argv, int slide) |
|
|
|
74 { |
|
|
|
75 struct stat statbuf; |
|
|
|
76 int fd; |
|
|
|
77 |
|
|
|
78 unloadcurrentslide(); |
|
|
|
79 |
|
|
|
80 fd = open(slidefiles[slide], O_RDONLY, 0); |
|
|
|
81 if (fd < 0) |
|
|
|
82 die("open: %s", slidefiles[slide]); |
|
|
|
83 if (fstat(fd, &statbuf) < 0) |
|
|
|
84 die("fstat: %s", slidefiles[slide]); |
|
|
|
85 currentslidep = mmap(NULL, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); |
|
|
|
86 if (currentslidep == MAP_FAILED) { |
|
|
|
87 currentslidep = NULL; |
|
|
|
88 die("mmap: %s", slidefiles[slide]); |
|
|
|
89 } |
|
|
|
90 currentslidelen = statbuf.st_size; |
|
|
|
91 close(fd); |
|
|
|
92 } |
|
|
|
93 |
|
|
|
94 void |
|
|
|
95 reloadcurrentslide(int sig) |
|
|
|
96 { |
|
|
|
97 /* |
|
|
|
98 * Keep this out of SIGHUP, in case this is used somewhere else. |
|
|
|
99 */ |
|
|
|
100 slidechanged = 1; |
|
|
|
101 |
|
|
|
102 if (sig == SIGHUP) { |
|
|
|
103 /* Make ncurses redisplay slide. */ |
|
|
|
104 if (raise(SIGWINCH) < 0) |
|
|
|
105 die("raise"); |
|
|
|
106 } |
|
|
|
107 } |
|
|
|
108 |
|
|
|
109 void |
|
|
|
110 setsignal() |
|
|
|
111 { |
|
|
|
112 struct sigaction sa; |
|
|
|
113 |
|
|
|
114 memset(&sa, 0, sizeof(sa)); |
|
|
|
115 sigemptyset(&sa.sa_mask); |
|
|
|
116 sa.sa_flags = 0; |
|
|
|
117 |
|
|
|
118 sa.sa_handler = quit; |
|
|
|
119 sigaction(SIGINT, &sa, NULL); |
|
|
|
120 sigaction(SIGQUIT, &sa, NULL); |
|
|
|
121 sigaction(SIGTERM, &sa, NULL); |
|
|
|
122 |
|
|
|
123 sa.sa_handler = reloadcurrentslide; |
|
|
|
124 sigaction(SIGHUP, &sa, NULL); |
|
|
|
125 } |
|
|
|
126 |
|
|
|
127 int |
|
|
|
128 main(int argc, char *argv[]) |
|
|
|
129 { |
|
|
|
130 int c; |
|
|
|
131 |
|
|
|
132 if (argc == 1) { |
|
|
|
133 errno = 0; |
|
|
|
134 die("usage: %s file ...", argv[0]); |
|
|
|
135 } |
|
|
|
136 slidefiles = ++argv; |
|
|
|
137 nslides = --argc; |
|
|
|
138 |
|
|
|
139 setsignal(); |
|
|
|
140 setlocale(LC_ALL, ""); |
|
|
|
141 |
|
|
|
142 /* start */ |
|
|
|
143 currentslide = 0; |
|
|
|
144 currentslidep = NULL; |
|
|
|
145 currentslidelen = 0; |
|
|
|
146 |
|
|
|
147 /* init curses */ |
|
|
|
148 initscr(); |
|
|
|
149 cbreak(); |
|
|
|
150 noecho(); |
|
|
|
151 nonl(); |
|
|
|
152 intrflush(stdscr, FALSE); |
|
|
|
153 keypad(stdscr, TRUE); |
|
|
|
154 curs_set(FALSE); /* hide cursor */ |
|
|
|
155 |
|
|
|
156 show: |
|
|
|
157 /* display slide if changed */ |
|
|
|
158 if (slidechanged) { |
|
|
|
159 slidechanged = 0; |
|
|
|
160 loadcurrentslide(slidefiles, currentslide); |
|
|
|
161 } |
|
|
|
162 clear(); |
|
|
|
163 refresh(); |
|
|
|
164 printw("%.*s", currentslidelen, currentslidep); |
|
|
|
165 |
|
|
|
166 again: |
|
|
|
167 c = getch(); |
|
|
|
168 switch (c) { |
|
|
|
169 /* powerpoint remote presenter shortcuts */ |
|
|
|
170 case 4: /* ^D, EOT */ |
|
|
|
171 case 27: |
|
|
|
172 case KEY_F(5): |
|
|
|
173 /* end presentation */ |
|
|
|
174 case 'q': |
|
|
|
175 break; |
|
|
|
176 /* next */ |
|
|
|
177 case ' ': |
|
|
|
178 case 'l': |
|
|
|
179 case 'j': |
|
|
|
180 case KEY_RIGHT: |
|
|
|
181 case KEY_DOWN: |
|
|
|
182 case KEY_NPAGE: |
|
|
|
183 if (currentslide < nslides - 1) { |
|
|
|
184 slidechanged = 1; |
|
|
|
185 currentslide++; |
|
|
|
186 goto show; |
|
|
|
187 } |
|
|
|
188 goto again; |
|
|
|
189 /* prev */ |
|
|
|
190 case 'h': |
|
|
|
191 case 'k': |
|
|
|
192 case KEY_LEFT: |
|
|
|
193 case KEY_UP: |
|
|
|
194 case KEY_PPAGE: |
|
|
|
195 if (currentslide > 0) { |
|
|
|
196 slidechanged = 1; |
|
|
|
197 currentslide--; |
|
|
|
198 goto show; |
|
|
|
199 } |
|
|
|
200 goto again; |
|
|
|
201 /* shortcut from powerpoint. Needed for remote presenters. */ |
|
|
|
202 case '.': |
|
|
|
203 /* first */ |
|
|
|
204 case 'u': |
|
|
|
205 case KEY_BEG: |
|
|
|
206 case KEY_HOME: |
|
|
|
207 if (currentslide != 0) |
|
|
|
208 slidechanged = 1; |
|
|
|
209 currentslide = 0; |
|
|
|
210 goto show; |
|
|
|
211 /* last */ |
|
|
|
212 case 'i': |
|
|
|
213 case KEY_END: |
|
|
|
214 if (currentslide != (nslides - 1)) |
|
|
|
215 slidechanged = 1; |
|
|
|
216 currentslide = nslides - 1; |
|
|
|
217 goto show; |
|
|
|
218 /* reload */ |
|
|
|
219 case 'r': |
|
|
|
220 case 12: /* ^L, redraw */ |
|
|
|
221 case KEY_RESIZE: /* resize / SIGWINCH */ |
|
|
|
222 goto show; |
|
|
|
223 default: |
|
|
|
224 /* printf("key pressed = '%d'\n", c); */ |
|
|
|
225 goto again; |
|
|
|
226 } |
|
|
|
227 |
|
|
|
228 cleanup(); |
|
|
|
229 |
|
|
|
230 return 0; |
|
|
|
231 } |
|