git clone catpoint catpoint Log gph
Found at: gopher.r-36.net:70/scm/catpoint/file/catpoint.c.gph
tcatpoint.c - catpoint - Catpoint simple presenting software.
git clone git://r-36.net/catpoint
---
tcatpoint.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 }
.