24e8a658309ee589320b0355e7270e2af73d2d15
[ncurses.git] / test / savescreen.c
1 /****************************************************************************
2  * Copyright (c) 2007 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  ****************************************************************************/
28 /*
29  * $Id: savescreen.c,v 1.9 2007/07/14 23:16:55 tom Exp $
30  *
31  * Demonstrate save/restore functions from the curses library.
32  * Thomas Dickey - 2007/7/14
33  */
34 /*
35 scr_set                 -
36 scr_init                -
37 */
38
39 #include <test.priv.h>
40
41 #if TIME_WITH_SYS_TIME
42 # include <sys/time.h>
43 # include <time.h>
44 #else
45 # if HAVE_SYS_TIME_H
46 #  include <sys/time.h>
47 # else
48 #  include <time.h>
49 # endif
50 #endif
51
52 static void
53 setup_next(void)
54 {
55     curs_set(1);
56     reset_shell_mode();
57 }
58
59 static void
60 cleanup(char *files[])
61 {
62     int n;
63
64     for (n = 0; files[n] != 0; ++n) {
65         unlink(files[n]);
66     }
67 }
68
69 /*
70  * scr_restore() or scr_set() operates on curscr.  If we read a character using
71  * getch() that will refresh stdscr, wiping out the result.  To avoid that,
72  * copy the data back from curscr to stdscr.
73  */
74 static void
75 after_load(void)
76 {
77     overwrite(curscr, stdscr);
78     doupdate();
79 }
80
81 static void
82 show_what(int which, int last)
83 {
84     int y, x;
85     time_t now = time((time_t *) 0);
86
87     getyx(stdscr, y, x);
88
89     move(0, 0);
90     printw("Saved %d of %d - %s", which, last + 1, ctime(&now));
91
92     move(y, x);
93
94     refresh();
95 }
96
97 static int
98 get_command(int which, int last)
99 {
100     int ch;
101
102     timeout(100);
103
104     do {
105         show_what(which, last);
106         ch = getch();
107     } while (ch == ERR);
108
109     return ch;
110 }
111
112 static void
113 usage(void)
114 {
115     static const char *msg[] =
116     {
117         "Usage: savescreen [-r] files",
118         "",
119         "Options:",
120         " -r  replay the screen-dump files"
121     };
122     unsigned n;
123     for (n = 0; n < SIZEOF(msg); ++n) {
124         fprintf(stderr, "%s\n", msg[n]);
125     }
126     ExitProgram(EXIT_FAILURE);
127 }
128
129 int
130 main(int argc, char *argv[])
131 {
132     int ch;
133     int which = 0;
134     int last;
135     bool replaying = FALSE;
136     bool done = FALSE;
137     char **files;
138
139     while ((ch = getopt(argc, argv, "r")) != -1) {
140         switch (ch) {
141         case 'r':
142             replaying = TRUE;
143             break;
144         default:
145             usage();
146             break;
147         }
148     }
149
150     initscr();
151     cbreak();
152     noecho();
153     keypad(stdscr, TRUE);
154     curs_set(0);
155     if (has_colors()) {
156         start_color();
157         for (ch = 0; ch < COLOR_PAIRS; ++ch) {
158             short pair = ch % COLOR_PAIRS;
159             init_pair(pair, COLOR_WHITE, ch % COLORS);
160         }
161     }
162
163     files = argv + optind;
164     last = argc - optind - 1;
165     if (replaying) {
166
167         /*
168          * Use the last file as the initial/current screen.
169          */
170         if (last < 0) {
171             endwin();
172             printf("No screen-dumps given\n");
173             ExitProgram(EXIT_FAILURE);
174         }
175
176         which = last;
177         if (scr_set(files[which]) == ERR) {
178             endwin();
179             printf("Cannot load screen-dump %s\n", files[which]);
180             ExitProgram(EXIT_FAILURE);
181         }
182         after_load();
183
184         while (!done && (ch = getch()) != ERR) {
185             switch (ch) {
186             case 'n':
187                 /*
188                  * If we got a "next" here, skip to the final screen before
189                  * moving to the next process.
190                  */
191                 setup_next();
192                 which = last;
193                 done = TRUE;
194                 break;
195             case 'q':
196                 endwin();
197                 cleanup(files);
198                 done = TRUE;
199                 break;
200             case KEY_BACKSPACE:
201             case '\b':
202                 if (--which < 0)
203                     which = last;
204                 break;
205             case ' ':
206                 if (++which > last)
207                     which = 0;
208                 break;
209             default:
210                 beep();
211                 continue;
212             }
213
214             if (ch == 'q') {
215                 ;
216             } else if (scr_restore(files[which]) == ERR) {
217                 endwin();
218                 printf("Cannot load screen-dump %s\n", files[which]);
219                 cleanup(files);
220                 ExitProgram(EXIT_FAILURE);
221             } else {
222                 wrefresh(curscr);
223             }
224         }
225     } else {
226         int y;
227         int x;
228
229         move(2, 0);
230         printw("Use h,j,k,l or arrows to move around the screen\n");
231         printw("Press 'q' to quit, ' ' to dump a screen\n");
232         printw("When the last screen has been dumped, press 'n' to run the\n");
233         printw("screen-loader.  That allows only 'q', backspace and ' ' for\n");
234         printw("stepping through the dumped/restored screens.\n");
235         getyx(stdscr, y, x);
236
237         while (!done) {
238             switch (ch = get_command(which, last)) {
239             case 'n':
240                 setup_next();
241                 done = TRUE;
242                 break;
243             case 'q':
244                 endwin();
245                 cleanup(files);
246                 done = TRUE;
247                 break;
248             case ' ':
249                 if (files[which] != 0) {
250                     show_what(which + 1, last);
251                     if (scr_dump(files[which]) == ERR) {
252                         endwin();
253                         printf("Cannot write screen-dump %s\n", files[which]);
254                         cleanup(files);
255                         done = TRUE;
256                         break;
257                     }
258                     ++which;
259                     if (has_colors()) {
260                         short pair = which % COLOR_PAIRS;
261                         bkgd(COLOR_PAIR(pair));
262                     }
263                 } else {
264                     beep();
265                 }
266                 break;
267             case KEY_LEFT:
268             case 'h':
269                 if (--x < 0)
270                     x = COLS - 1;
271                 break;
272             case KEY_DOWN:
273             case 'j':
274                 if (++y >= LINES)
275                     y = 1;
276                 break;
277             case KEY_UP:
278             case 'k':
279                 if (--y < 1)
280                     y = LINES - 1;
281                 break;
282             case KEY_RIGHT:
283             case 'l':
284                 if (++x >= COLS)
285                     x = 0;
286                 break;
287             }
288             if (!done) {
289                 time_t now = time((time_t *) 0);
290
291                 move(0, 0);
292                 addstr(ctime(&now));
293                 move(y, x);
294                 addch('#' | A_REVERSE);
295                 move(y, x);
296             }
297         }
298     }
299     ExitProgram(EXIT_SUCCESS);
300 }