libncurses: updated to 6.0
[tomato.git] / release / src / router / libncurses / test / savescreen.c
blob01bfe06b687752012c833a521b5ce24dba723f4b
1 /****************************************************************************
2 * Copyright (c) 2007-2011,2015 Free Software Foundation, Inc. *
3 * *
4 * Permission is hereby granted, free of charge, to any person obtaining a *
5 * copy of this software and associated documentation files (the *
6 * "Software"), to deal in the Software without restriction, including *
7 * without limitation the rights to use, copy, modify, merge, publish, *
8 * distribute, distribute with modifications, sublicense, and/or sell *
9 * copies of the Software, and to permit persons to whom the Software is *
10 * furnished to do so, subject to the following conditions: *
11 * *
12 * The above copyright notice and this permission notice shall be included *
13 * in all copies or substantial portions of the Software. *
14 * *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
22 * *
23 * Except as contained in this notice, the name(s) of the above copyright *
24 * holders shall not be used in advertising or otherwise to promote the *
25 * sale, use or other dealings in this Software without prior written *
26 * authorization. *
27 ****************************************************************************/
29 * $Id: savescreen.c,v 1.27 2015/03/28 23:21:28 tom Exp $
31 * Demonstrate save/restore functions from the curses library.
32 * Thomas Dickey - 2007/7/14
35 #include <test.priv.h>
37 #if HAVE_SCR_DUMP
39 #include <sys/types.h>
40 #include <sys/stat.h>
42 #if TIME_WITH_SYS_TIME
43 # include <sys/time.h>
44 # include <time.h>
45 #else
46 # if HAVE_SYS_TIME_H
47 # include <sys/time.h>
48 # else
49 # include <time.h>
50 # endif
51 #endif
53 static bool use_init = FALSE;
54 static bool keep_dumps = FALSE;
56 static int
57 fexists(const char *name)
59 struct stat sb;
60 return (stat(name, &sb) == 0 && (sb.st_mode & S_IFMT) == S_IFREG);
63 static void
64 setup_next(void)
66 curs_set(1);
67 reset_shell_mode();
70 static void
71 cleanup(char *files[])
73 int n;
75 if (!keep_dumps) {
76 for (n = 0; files[n] != 0; ++n) {
77 unlink(files[n]);
82 static int
83 load_screen(char *filename)
85 int result;
87 if (use_init) {
88 if ((result = scr_init(filename)) != ERR)
89 result = scr_restore(filename);
90 } else {
91 result = scr_set(filename);
93 return result;
97 * scr_restore() or scr_set() operates on curscr. If we read a character using
98 * getch() that will refresh stdscr, wiping out the result. To avoid that,
99 * copy the data back from curscr to stdscr.
101 static void
102 after_load(void)
104 overwrite(curscr, stdscr);
105 doupdate();
108 static void
109 show_what(int which, int last)
111 int y, x, n;
112 time_t now;
113 char *mytime;
115 getyx(stdscr, y, x);
117 move(0, 0);
118 printw("Saved %d of %d (? for help)", which, last + 1);
120 now = time((time_t *) 0);
121 mytime = ctime(&now);
122 for (n = (int) strlen(mytime) - 1; n >= 0; --n) {
123 if (isspace(UChar(mytime[n]))) {
124 mytime[n] = '\0';
125 } else {
126 break;
129 mvprintw(0, (COLS - n - 2), " %s", mytime);
131 move(y, x);
133 refresh();
136 static int
137 get_command(int which, int last)
139 int ch;
141 timeout(50);
143 do {
144 show_what(which, last);
145 ch = getch();
146 } while (ch == ERR);
148 return ch;
151 static void
152 show_help(const char **help)
154 WINDOW *mywin = newwin(LINES, COLS, 0, 0);
155 int n;
157 box(mywin, 0, 0);
158 wmove(mywin, 1, 1);
159 for (n = 0; help[n] != 0; ++n) {
160 wmove(mywin, 1 + n, 2);
161 wprintw(mywin, "%.*s", COLS - 4, help[n]);
163 wgetch(mywin);
164 delwin(mywin);
165 touchwin(stdscr);
166 refresh();
169 static void
170 editor_help(void)
172 static const char *msgs[] =
174 "You are now in the screen-editor, which allows you to make some",
175 "lines on the screen, as well as save copies of the screen to a",
176 "temporary file",
178 "Keys:",
179 " q quit",
180 " n run the screen-loader to show the saved screens",
181 " <space> dump a screen",
183 " a toggle between '#' and graphic symbol for drawing",
184 " c change color drawn by line to next in palette",
185 " h,j,k,l or arrows to move around the screen, drawing",
187 show_help(msgs);
190 static void
191 replay_help(void)
193 static const char *msgs[] =
195 "You are now in the screen-loader, which allows you to view",
196 "the dumped/restored screens.",
198 "Keys:",
199 " q quit",
200 " <space> load the next screen",
201 " <backspace> load the previous screen",
203 show_help(msgs);
206 static void
207 usage(void)
209 static const char *msg[] =
211 "Usage: savescreen [-r] files",
213 "Options:",
214 " -f file fill/initialize screen using text from this file",
215 " -i use scr_init/scr_restore rather than scr_set",
216 " -k keep the restored dump-files rather than removing them",
217 " -r replay the screen-dump files"
219 unsigned n;
220 for (n = 0; n < SIZEOF(msg); ++n) {
221 fprintf(stderr, "%s\n", msg[n]);
223 ExitProgram(EXIT_FAILURE);
227 main(int argc, char *argv[])
229 int ch;
230 int which = 0;
231 int last;
232 bool replaying = FALSE;
233 bool done = FALSE;
234 char **files;
235 char *fill_by = 0;
236 #if USE_WIDEC_SUPPORT
237 cchar_t mycc;
238 int myxx;
239 #endif
241 setlocale(LC_ALL, "");
243 while ((ch = getopt(argc, argv, "f:ikr")) != -1) {
244 switch (ch) {
245 case 'f':
246 fill_by = optarg;
247 break;
248 case 'i':
249 use_init = TRUE;
250 break;
251 case 'k':
252 keep_dumps = TRUE;
253 break;
254 case 'r':
255 replaying = TRUE;
256 break;
257 default:
258 usage();
259 break;
263 files = argv + optind;
264 last = argc - optind - 1;
266 if (replaying) {
267 while (last >= 0 && !fexists(files[last]))
268 --last;
271 initscr();
272 cbreak();
273 noecho();
274 keypad(stdscr, TRUE);
275 curs_set(0);
276 if (has_colors()) {
277 short pair;
278 short color;
280 start_color();
282 * Assume pairs is the square of colors, and assign pairs going down
283 * so that there is minimal conflict with the background color (which
284 * counts up). The intent is just to show how color pair values are
285 * saved and restored.
287 for (pair = 0; pair < COLOR_PAIRS; ++pair) {
288 color = (short) (pair % (COLORS - 1));
289 init_pair(pair, (short) (COLOR_WHITE - color), color);
293 if (fill_by != 0) {
294 FILE *fp = fopen(fill_by, "r");
295 if (fp != 0) {
296 bool filled = FALSE;
297 move(1, 0);
298 while ((ch = fgetc(fp)) != EOF) {
299 if (addch(UChar(ch)) == ERR) {
300 filled = TRUE;
301 break;
304 fclose(fp);
305 if (!filled) {
306 while (addch(' ') != ERR) {
310 move(0, 0);
311 } else {
312 endwin();
313 fprintf(stderr, "Cannot open \"%s\"\n", fill_by);
314 ExitProgram(EXIT_FAILURE);
318 if (replaying) {
321 * Use the last file as the initial/current screen.
323 if (last < 0) {
324 endwin();
325 printf("No screen-dumps given\n");
326 ExitProgram(EXIT_FAILURE);
329 which = last;
330 if (load_screen(files[which]) == ERR) {
331 endwin();
332 printf("Cannot load screen-dump %s\n", files[which]);
333 ExitProgram(EXIT_FAILURE);
335 after_load();
337 while (!done && (ch = getch()) != ERR) {
338 switch (ch) {
339 case 'n':
341 * If we got a "next" here, skip to the final screen before
342 * moving to the next process.
344 setup_next();
345 which = last;
346 done = TRUE;
347 break;
348 case 'q':
349 cleanup(files);
350 done = TRUE;
351 break;
352 case KEY_BACKSPACE:
353 case '\b':
354 if (--which < 0)
355 which = last;
356 break;
357 case ' ':
358 if (++which > last)
359 which = 0;
360 break;
361 case '?':
362 replay_help();
363 break;
364 default:
365 beep();
366 continue;
369 if (ch == 'q') {
371 } else if (scr_restore(files[which]) == ERR) {
372 endwin();
373 printf("Cannot load screen-dump %s\n", files[which]);
374 cleanup(files);
375 ExitProgram(EXIT_FAILURE);
376 } else {
377 wrefresh(curscr);
380 endwin();
381 } else {
382 int y = 0;
383 int x = 0;
384 int color = 0;
385 int altchars = 0;
387 while (!done) {
388 switch (get_command(which, last)) {
389 case 'n':
390 setup_next();
391 done = TRUE;
392 break;
393 case 'q':
394 cleanup(files);
395 done = TRUE;
396 break;
397 case ' ':
398 if (files[which] != 0) {
399 show_what(which + 1, last);
400 if (scr_dump(files[which]) == ERR) {
401 endwin();
402 printf("Cannot write screen-dump %s\n", files[which]);
403 cleanup(files);
404 done = TRUE;
405 break;
407 ++which;
408 if (has_colors()) {
409 int cx, cy;
410 short pair = (short) (which % COLOR_PAIRS);
412 * Change the background color, to make it more
413 * obvious. But that changes the existing text-color.
414 * Copy the old values from the currently displayed
415 * screen.
417 bkgd((chtype) COLOR_PAIR(pair));
418 for (cy = 1; cy < LINES; ++cy) {
419 for (cx = 0; cx < COLS; ++cx) {
420 wmove(curscr, cy, cx);
421 wmove(stdscr, cy, cx);
422 #if USE_WIDEC_SUPPORT
423 if (win_wch(curscr, &mycc) != ERR) {
424 myxx = wcwidth(mycc.chars[0]);
425 if (myxx > 0) {
426 wadd_wchnstr(stdscr, &mycc, 1);
427 cx += (myxx - 1);
430 #else
431 waddch(stdscr, winch(curscr));
432 #endif
436 } else {
437 beep();
439 break;
440 case KEY_LEFT:
441 case 'h':
442 if (--x < 0)
443 x = COLS - 1;
444 break;
445 case KEY_DOWN:
446 case 'j':
447 if (++y >= LINES)
448 y = 1;
449 break;
450 case KEY_UP:
451 case 'k':
452 if (--y < 1)
453 y = LINES - 1;
454 break;
455 case KEY_RIGHT:
456 case 'l':
457 if (++x >= COLS)
458 x = 0;
459 break;
460 case 'a':
461 altchars = !altchars;
462 break;
463 case 'c':
464 color = (color + 1) % COLORS;
465 break;
466 case '?':
467 editor_help();
468 break;
469 default:
470 beep();
471 continue;
473 if (!done) {
474 attr_t attr = (A_REVERSE | COLOR_PAIR(color * COLORS));
475 chtype ch2 = (altchars ? ACS_DIAMOND : '#');
476 move(y, x);
477 addch(ch2 | attr);
478 move(y, x);
481 endwin();
483 ExitProgram(EXIT_SUCCESS);
486 #else
488 main(int argc, char *argv[])
490 printf("This program requires the screen-dump functions\n");
491 ExitProgram(EXIT_FAILURE);
493 #endif