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