libncurses: updated to 6.0
[tomato.git] / release / src / router / libncurses / ncurses / base / lib_screen.c
bloba03ceecef691b50836fb4cd0c7fa6924e32f7589
1 /****************************************************************************
2 * Copyright (c) 1998-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 /****************************************************************************
30 * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
31 * and: Eric S. Raymond <esr@snark.thyrsus.com> *
32 * and: Thomas E. Dickey 1996 on *
33 * and: Juergen Pfeifer 2009 *
34 ****************************************************************************/
36 #include <curses.priv.h>
38 #include <ctype.h>
40 #ifndef CUR
41 #define CUR SP_TERMTYPE
42 #endif
44 MODULE_ID("$Id: lib_screen.c,v 1.77 2015/07/04 22:54:14 tom Exp $")
46 #define MAX_SIZE 0x3fff /* 16k is big enough for a window or pad */
48 #define MARKER '\\'
49 #define APPEND '+'
50 #define GUTTER '|'
51 #define L_CURL '{'
52 #define R_CURL '}'
55 * Use 0x8888 as the magic number for new-format files, since it cannot be
56 * mistaken for the _cury/_curx pair of 16-bit numbers which start the old
57 * format. It happens to be unused in the file 5.22 database (2015/03/07).
59 static const char my_magic[] =
60 {'\210', '\210', '\210', '\210'};
62 #if NCURSES_EXT_PUTWIN
63 typedef enum {
64 pINT /* int */
65 ,pSHORT /* short */
66 ,pBOOL /* bool */
67 ,pATTR /* attr_t */
68 ,pCHAR /* chtype */
69 ,pSIZE /* NCURSES_SIZE_T */
70 #if NCURSES_WIDECHAR
71 ,pCCHAR /* cchar_t */
72 #endif
73 } PARAM_TYPE;
75 typedef struct {
76 const char name[11];
77 attr_t attr;
78 } SCR_ATTRS;
80 typedef struct {
81 const char name[17];
82 PARAM_TYPE type;
83 size_t size;
84 size_t offset;
85 } SCR_PARAMS;
87 #define DATA(name) { { #name }, A_##name }
88 static const SCR_ATTRS scr_attrs[] =
90 DATA(NORMAL),
91 DATA(STANDOUT),
92 DATA(UNDERLINE),
93 DATA(REVERSE),
94 DATA(BLINK),
95 DATA(DIM),
96 DATA(BOLD),
97 DATA(ALTCHARSET),
98 DATA(INVIS),
99 DATA(PROTECT),
100 DATA(HORIZONTAL),
101 DATA(LEFT),
102 DATA(LOW),
103 DATA(RIGHT),
104 DATA(TOP),
105 DATA(VERTICAL),
107 #ifdef A_ITALIC
108 DATA(ITALIC),
109 #endif
111 #undef DATA
113 #define sizeof2(type,name) sizeof(((type *)0)->name)
114 #define DATA(name, type) { { #name }, type, sizeof2(WINDOW, name), offsetof(WINDOW, name) }
116 static const SCR_PARAMS scr_params[] =
118 DATA(_cury, pSIZE),
119 DATA(_curx, pSIZE),
120 DATA(_maxy, pSIZE),
121 DATA(_maxx, pSIZE),
122 DATA(_begy, pSIZE),
123 DATA(_begx, pSIZE),
124 DATA(_flags, pSHORT),
125 DATA(_attrs, pATTR),
126 DATA(_bkgd, pCHAR),
127 DATA(_notimeout, pBOOL),
128 DATA(_clear, pBOOL),
129 DATA(_leaveok, pBOOL),
130 DATA(_scroll, pBOOL),
131 DATA(_idlok, pBOOL),
132 DATA(_idcok, pBOOL),
133 DATA(_immed, pBOOL),
134 DATA(_sync, pBOOL),
135 DATA(_use_keypad, pBOOL),
136 DATA(_delay, pINT),
137 DATA(_regtop, pSIZE),
138 DATA(_regbottom, pSIZE),
139 DATA(_pad._pad_y, pSIZE),
140 DATA(_pad._pad_x, pSIZE),
141 DATA(_pad._pad_top, pSIZE),
142 DATA(_pad._pad_left, pSIZE),
143 DATA(_pad._pad_bottom, pSIZE),
144 DATA(_pad._pad_right, pSIZE),
145 DATA(_yoffset, pSIZE),
146 #if NCURSES_WIDECHAR
147 DATA(_bkgrnd, pCCHAR),
148 #if NCURSES_EXT_COLORS
149 DATA(_color, pINT),
150 #endif
151 #endif
153 #undef DATA
155 static const NCURSES_CH_T blank = NewChar(BLANK_TEXT);
158 * Allocate and read a line of text. Caller must free it.
160 static char *
161 read_txt(FILE *fp)
163 size_t limit = 1024;
164 size_t used = 0;
165 char *result = malloc(limit);
166 char *buffer;
168 if (result != 0) {
169 int ch = 0;
171 clearerr(fp);
172 result[used] = '\0';
173 do {
174 if (used + 2 >= limit) {
175 limit += 1024;
176 buffer = realloc(result, limit);
177 if (buffer == 0) {
178 free(result);
179 result = 0;
180 break;
182 result = buffer;
184 ch = fgetc(fp);
185 if (ch == EOF)
186 break;
187 result[used++] = (char) ch;
188 result[used] = '\0';
189 } while (ch != '\n');
191 if (ch == '\n') {
192 result[--used] = '\0';
193 T(("READ:%s", result));
194 } else if (used == 0) {
195 free(result);
196 result = 0;
199 return result;
202 static char *
203 decode_attr(char *source, attr_t *target, int *color)
205 bool found = FALSE;
207 T(("decode_attr '%s'", source));
209 while (*source) {
210 if (source[0] == MARKER && source[1] == L_CURL) {
211 source += 2;
212 found = TRUE;
213 } else if (source[0] == R_CURL) {
214 source++;
215 found = FALSE;
216 } else if (found) {
217 size_t n;
218 char *next = source;
220 if (source[0] == GUTTER) {
221 ++next;
222 } else if (*next == 'C') {
223 int value = 0;
224 unsigned pair;
225 next++;
226 while (isdigit(UChar(*next))) {
227 value = value * 10 + (*next++ - '0');
229 *target &= ~A_COLOR;
230 pair = (unsigned) ((value > 256)
231 ? COLOR_PAIR(255)
232 : COLOR_PAIR(value));
233 *target |= pair;
234 *color = value;
235 } else {
236 while (isalnum(UChar(*next))) {
237 ++next;
239 for (n = 0; n < SIZEOF(scr_attrs); ++n) {
240 if ((size_t) (next - source) == strlen(scr_attrs[n].name)) {
241 if (scr_attrs[n].attr) {
242 *target |= scr_attrs[n].attr;
243 } else {
244 *target = A_NORMAL;
246 break;
250 source = next;
251 } else {
252 break;
255 return source;
258 static char *
259 decode_char(char *source, int *target)
261 int limit = 0;
262 int base = 16;
263 const char digits[] = "0123456789abcdef";
265 T(("decode_char '%s'", source));
266 *target = ' ';
267 switch (*source) {
268 case MARKER:
269 switch (*++source) {
270 case APPEND:
271 break;
272 case MARKER:
273 *target = MARKER;
274 ++source;
275 break;
276 case 's':
277 *target = ' ';
278 ++source;
279 break;
280 case '0':
281 case '1':
282 case '2':
283 case '3':
284 base = 8;
285 limit = 3;
286 break;
287 case 'u':
288 limit = 4;
289 ++source;
290 break;
291 case 'U':
292 limit = 8;
293 ++source;
294 break;
296 if (limit) {
297 *target = 0;
298 while (limit-- > 0) {
299 char *find = strchr(digits, *source++);
300 int ch = (find != 0) ? (int) (find - digits) : -1;
301 *target *= base;
302 if (ch >= 0 && ch < base) {
303 *target += ch;
307 break;
308 default:
309 *target = *source++;
310 break;
312 return source;
315 static char *
316 decode_chtype(char *source, chtype fillin, chtype *target)
318 attr_t attr = ChAttrOf(fillin);
319 int color = PAIR_NUMBER((int) attr);
320 int value;
322 T(("decode_chtype '%s'", source));
323 source = decode_attr(source, &attr, &color);
324 source = decode_char(source, &value);
325 *target = (ChCharOf(value) | attr | (chtype) COLOR_PAIR(color));
326 /* FIXME - ignore combining characters */
327 return source;
330 #if NCURSES_WIDECHAR
331 static char *
332 decode_cchar(char *source, cchar_t *fillin, cchar_t *target)
334 int color;
335 attr_t attr = fillin->attr;
336 wchar_t chars[CCHARW_MAX];
337 int append = 0;
338 int value = 0;
340 T(("decode_cchar '%s'", source));
341 *target = blank;
342 #if NCURSES_EXT_COLORS
343 color = fillin->ext_color;
344 #else
345 color = (int) PAIR_NUMBER(attr);
346 #endif
347 source = decode_attr(source, &attr, &color);
348 memset(chars, 0, sizeof(chars));
349 source = decode_char(source, &value);
350 chars[0] = (wchar_t) value;
351 /* handle combining characters */
352 while (source[0] == MARKER && source[1] == APPEND) {
353 source += 2;
354 source = decode_char(source, &value);
355 if (++append < CCHARW_MAX) {
356 chars[append] = (wchar_t) value;
359 setcchar(target, chars, attr, (short) color, NULL);
360 return source;
362 #endif
364 static int
365 read_win(WINDOW *win, FILE *fp)
367 int code = ERR;
368 char *txt;
369 char *name;
370 char *value;
371 size_t n;
372 int color;
373 #if NCURSES_WIDECHAR
374 NCURSES_CH_T prior;
375 #endif
376 chtype prior2;
378 memset(win, 0, sizeof(WINDOW));
379 for (;;) {
380 txt = read_txt(fp);
381 if (txt == 0)
382 break;
383 if (!strcmp(txt, "rows:")) {
384 free(txt);
385 code = OK;
386 break;
388 if ((value = strchr(txt, '=')) == 0) {
389 free(txt);
390 continue;
392 *value++ = '\0';
393 name = !strcmp(txt, "flag") ? value : txt;
394 for (n = 0; n < SIZEOF(scr_params); ++n) {
395 if (!strcmp(name, scr_params[n].name)) {
396 void *data = (void *) ((char *) win + scr_params[n].offset);
398 switch (scr_params[n].type) {
399 case pATTR:
400 (void) decode_attr(value, data, &color);
401 break;
402 case pBOOL:
403 *(bool *) data = TRUE;
404 break;
405 case pCHAR:
406 prior2 = ' ';
407 decode_chtype(value, prior2, data);
408 break;
409 case pINT:
410 *(int *) data = atoi(value);
411 break;
412 case pSHORT:
413 *(short *) data = (short) atoi(value);
414 break;
415 case pSIZE:
416 *(NCURSES_SIZE_T *) data = (NCURSES_SIZE_T) atoi(value);
417 break;
418 #if NCURSES_WIDECHAR
419 case pCCHAR:
420 prior = blank;
421 decode_cchar(value, &prior, data);
422 break;
423 #endif
425 break;
428 free(txt);
430 return code;
433 static int
434 read_row(char *source, NCURSES_CH_T * prior, NCURSES_CH_T * target, int length)
436 while (*source != '\0' && length > 0) {
437 #if NCURSES_WIDECHAR
438 int n, len;
439 source = decode_cchar(source, prior, target);
440 len = wcwidth(target->chars[0]);
441 if (len > 1) {
442 SetWidecExt(CHDEREF(target), 0);
443 for (n = 1; n < len; ++n) {
444 target[n] = target[0];
445 SetWidecExt(CHDEREF(target), n);
447 target += (len - 1);
448 length -= (len - 1);
450 #else
451 source = decode_chtype(source, *prior, target);
452 #endif
453 *prior = *target;
454 ++target;
455 --length;
457 while (length-- > 0) {
458 *target++ = blank;
460 /* FIXME - see what error conditions should apply if I need to return ERR */
461 return 0;
463 #endif /* NCURSES_EXT_PUTWIN */
466 * Originally, getwin/putwin used fread/fwrite, because they used binary data.
467 * The new format uses printable ASCII, which does not have as predictable
468 * sizes. Consequently, we use buffered I/O, e.g., fgetc/fprintf, which need
469 * special handling if we want to read screen dumps from an older library.
471 static int
472 read_block(void *target, size_t length, FILE *fp)
474 int result = 0;
475 char *buffer = target;
477 clearerr(fp);
478 while (length-- != 0) {
479 int ch = fgetc(fp);
480 if (ch == EOF) {
481 result = -1;
482 break;
484 *buffer++ = (char) ch;
486 return result;
489 NCURSES_EXPORT(WINDOW *)
490 NCURSES_SP_NAME(getwin) (NCURSES_SP_DCLx FILE *filep)
492 WINDOW tmp, *nwin;
493 int n;
494 bool old_format = FALSE;
496 T((T_CALLED("getwin(%p)"), (void *) filep));
498 if (filep == 0) {
499 returnWin(0);
503 * Read the first 4 bytes to determine first if this is an old-format
504 * screen-dump, or new-format.
506 if (read_block(&tmp, 4, filep) < 0) {
507 returnWin(0);
510 * If this is a new-format file, and we do not support it, give up.
512 if (!memcmp(&tmp, my_magic, 4)) {
513 #if NCURSES_EXT_PUTWIN
514 if (read_win(&tmp, filep) < 0)
515 #endif
516 returnWin(0);
517 } else if (read_block(((char *) &tmp) + 4, sizeof(WINDOW) - 4, filep) < 0) {
518 returnWin(0);
519 } else {
520 old_format = TRUE;
524 * Check the window-size:
526 if (tmp._maxy == 0 ||
527 tmp._maxy > MAX_SIZE ||
528 tmp._maxx == 0 ||
529 tmp._maxx > MAX_SIZE) {
530 returnWin(0);
533 if (tmp._flags & _ISPAD) {
534 nwin = NCURSES_SP_NAME(newpad) (NCURSES_SP_ARGx
535 tmp._maxy + 1,
536 tmp._maxx + 1);
537 } else {
538 nwin = NCURSES_SP_NAME(newwin) (NCURSES_SP_ARGx
539 tmp._maxy + 1,
540 tmp._maxx + 1, 0, 0);
544 * We deliberately do not restore the _parx, _pary, or _parent
545 * fields, because the window hierarchy within which they
546 * made sense is probably gone.
548 if (nwin != 0) {
549 size_t linesize = sizeof(NCURSES_CH_T) * (size_t) (tmp._maxx + 1);
551 nwin->_curx = tmp._curx;
552 nwin->_cury = tmp._cury;
553 nwin->_maxy = tmp._maxy;
554 nwin->_maxx = tmp._maxx;
555 nwin->_begy = tmp._begy;
556 nwin->_begx = tmp._begx;
557 nwin->_yoffset = tmp._yoffset;
558 nwin->_flags = tmp._flags & ~(_SUBWIN);
560 WINDOW_ATTRS(nwin) = WINDOW_ATTRS(&tmp);
561 nwin->_nc_bkgd = tmp._nc_bkgd;
563 nwin->_notimeout = tmp._notimeout;
564 nwin->_clear = tmp._clear;
565 nwin->_leaveok = tmp._leaveok;
566 nwin->_idlok = tmp._idlok;
567 nwin->_idcok = tmp._idcok;
568 nwin->_immed = tmp._immed;
569 nwin->_scroll = tmp._scroll;
570 nwin->_sync = tmp._sync;
571 nwin->_use_keypad = tmp._use_keypad;
572 nwin->_delay = tmp._delay;
574 nwin->_regtop = tmp._regtop;
575 nwin->_regbottom = tmp._regbottom;
577 if (tmp._flags & _ISPAD)
578 nwin->_pad = tmp._pad;
580 if (old_format) {
581 T(("reading old-format screen dump"));
582 for (n = 0; n <= nwin->_maxy; n++) {
583 if (read_block(nwin->_line[n].text, linesize, filep) < 0) {
584 delwin(nwin);
585 returnWin(0);
589 #if NCURSES_EXT_PUTWIN
590 else {
591 char *txt;
592 bool success = TRUE;
593 NCURSES_CH_T prior = blank;
595 T(("reading new-format screen dump"));
596 for (n = 0; n <= nwin->_maxy; n++) {
597 long row;
598 char *next;
600 if ((txt = read_txt(filep)) == 0) {
601 T(("...failed to read string for row %d", n + 1));
602 success = FALSE;
603 break;
605 row = strtol(txt, &next, 10);
606 if (row != (n + 1) || *next != ':') {
607 T(("...failed to read row-number %d", n + 1));
608 success = FALSE;
609 break;
612 if (read_row(++next, &prior, nwin->_line[n].text, tmp._maxx
613 + 1) < 0) {
614 T(("...failed to read cells for row %d", n + 1));
615 success = FALSE;
616 break;
618 free(txt);
619 txt = 0;
622 if (!success) {
623 free(txt);
624 delwin(nwin);
625 returnWin(0);
628 #endif
629 touchwin(nwin);
631 returnWin(nwin);
634 #if NCURSES_SP_FUNCS
635 NCURSES_EXPORT(WINDOW *)
636 getwin(FILE *filep)
638 return NCURSES_SP_NAME(getwin) (CURRENT_SCREEN, filep);
640 #endif
642 #if NCURSES_EXT_PUTWIN
643 static void
644 encode_attr(char *target, attr_t source, attr_t prior)
646 source &= ~A_CHARTEXT;
647 prior &= ~A_CHARTEXT;
649 *target = '\0';
650 if (source != prior) {
651 size_t n;
652 bool first = TRUE;
654 *target++ = MARKER;
655 *target++ = L_CURL;
657 for (n = 0; n < SIZEOF(scr_attrs); ++n) {
658 if ((source & scr_attrs[n].attr) != 0 ||
659 ((source & ALL_BUT_COLOR) == 0 &&
660 (scr_attrs[n].attr == A_NORMAL))) {
661 if (first) {
662 first = FALSE;
663 } else {
664 *target++ = '|';
666 strcpy(target, scr_attrs[n].name);
667 target += strlen(target);
670 if ((source & A_COLOR) != (prior & A_COLOR)) {
671 if (!first)
672 *target++ = '|';
673 sprintf(target, "C%d", PAIR_NUMBER((int) source));
674 target += strlen(target);
677 *target++ = R_CURL;
678 *target = '\0';
682 static void
683 encode_cell(char *target, CARG_CH_T source, CARG_CH_T previous)
685 #if NCURSES_WIDECHAR
686 size_t n;
688 *target = '\0';
689 if (previous->attr != source->attr) {
690 encode_attr(target, source->attr, previous->attr);
692 target += strlen(target);
693 #if NCURSES_EXT_COLORS
694 if (previous->ext_color != source->ext_color) {
695 sprintf(target, "%c%cC%d%c", MARKER, L_CURL, source->ext_color, R_CURL);
697 #endif
698 for (n = 0; n < SIZEOF(source->chars); ++n) {
699 unsigned uch = (unsigned) source->chars[n];
700 if (uch == 0)
701 continue;
702 if (n) {
703 *target++ = MARKER;
704 *target++ = APPEND;
706 *target++ = MARKER;
707 if (uch > 0xffff) {
708 sprintf(target, "U%08x", uch);
709 } else if (uch > 0xff) {
710 sprintf(target, "u%04x", uch);
711 } else if (uch < 32 || uch >= 127) {
712 sprintf(target, "%03o", uch & 0xff);
713 } else {
714 switch (uch) {
715 case ' ':
716 strcpy(target, "s");
717 break;
718 case MARKER:
719 *target++ = MARKER;
720 *target = '\0';
721 break;
722 default:
723 sprintf(--target, "%c", uch);
724 break;
727 target += strlen(target);
729 #else
730 chtype ch = CharOfD(source);
732 *target = '\0';
733 if (AttrOfD(previous) != AttrOfD(source)) {
734 encode_attr(target, AttrOfD(source), AttrOfD(previous));
736 target += strlen(target);
737 *target++ = MARKER;
738 if (ch < 32 || ch >= 127) {
739 sprintf(target, "%03o", UChar(ch));
740 } else {
741 switch (ch) {
742 case ' ':
743 strcpy(target, "s");
744 break;
745 case MARKER:
746 *target++ = MARKER;
747 *target = '\0';
748 break;
749 default:
750 sprintf(--target, "%c", UChar(ch));
751 break;
754 target += strlen(target);
755 #endif
757 #endif
759 NCURSES_EXPORT(int)
760 putwin(WINDOW *win, FILE *filep)
762 int code = ERR;
763 int y;
765 T((T_CALLED("putwin(%p,%p)"), (void *) win, (void *) filep));
767 #if NCURSES_EXT_PUTWIN
768 if (win != 0) {
769 const char *version = curses_version();
770 char buffer[1024];
771 NCURSES_CH_T last_cell;
773 memset(&last_cell, 0, sizeof(last_cell));
775 clearerr(filep);
778 * Our magic number is technically nonprinting, but aside from that,
779 * all of the file is printable ASCII.
781 #define PUTS(s) if (fputs(s, filep) == EOF || ferror(filep)) returnCode(code)
782 PUTS(my_magic);
783 PUTS(version);
784 PUTS("\n");
785 for (y = 0; y < (int) SIZEOF(scr_params); ++y) {
786 const char *name = scr_params[y].name;
787 const char *data = (char *) win + scr_params[y].offset;
788 const void *dp = (const void *) data;
790 *buffer = '\0';
791 if (!strncmp(name, "_pad.", 5) && !(win->_flags & _ISPAD)) {
792 continue;
794 switch (scr_params[y].type) {
795 case pATTR:
796 encode_attr(buffer, (*(const attr_t *) dp) & ~A_CHARTEXT, A_NORMAL);
797 break;
798 case pBOOL:
799 if (!(*(const bool *) data)) {
800 continue;
802 strcpy(buffer, name);
803 name = "flag";
804 break;
805 case pCHAR:
806 encode_attr(buffer, *(const attr_t *) dp, A_NORMAL);
807 break;
808 case pINT:
809 if (!(*(const int *) dp))
810 continue;
811 sprintf(buffer, "%d", *(const int *) dp);
812 break;
813 case pSHORT:
814 if (!(*(const short *) dp))
815 continue;
816 sprintf(buffer, "%d", *(const short *) dp);
817 break;
818 case pSIZE:
819 if (!(*(const NCURSES_SIZE_T *) dp))
820 continue;
821 sprintf(buffer, "%d", *(const NCURSES_SIZE_T *) dp);
822 break;
823 #if NCURSES_WIDECHAR
824 case pCCHAR:
825 encode_cell(buffer, (CARG_CH_T) dp, CHREF(last_cell));
826 break;
827 #endif
830 * Only write non-default data.
832 if (*buffer != '\0') {
833 if (fprintf(filep, "%s=%s\n", name, buffer) <= 0
834 || ferror(filep))
835 returnCode(code);
838 /* Write row-data */
839 fprintf(filep, "rows:\n");
840 for (y = 0; y <= win->_maxy; y++) {
841 NCURSES_CH_T *data = win->_line[y].text;
842 int x;
843 if (fprintf(filep, "%d:", y + 1) <= 0
844 || ferror(filep))
845 returnCode(code);
846 for (x = 0; x <= win->_maxx; x++) {
847 #if NCURSES_WIDECHAR
848 int len = wcwidth(data[x].chars[0]);
849 encode_cell(buffer, CHREF(data[x]), CHREF(last_cell));
850 last_cell = data[x];
851 PUTS(buffer);
852 if (len > 1)
853 x += (len - 1);
854 #else
855 encode_cell(buffer, CHREF(data[x]), CHREF(last_cell));
856 last_cell = data[x];
857 PUTS(buffer);
858 #endif
860 PUTS("\n");
863 #else
865 * This is the original putwin():
866 * A straight binary dump is simple, but its format can depend on whether
867 * ncurses is compiled with wide-character support, and also may depend
868 * on the version of ncurses, e.g., if the WINDOW structure is extended.
870 if (win != 0) {
871 size_t len = (size_t) (win->_maxx + 1);
873 clearerr(filep);
874 if (fwrite(win, sizeof(WINDOW), (size_t) 1, filep) != 1
875 || ferror(filep))
876 returnCode(code);
878 for (y = 0; y <= win->_maxy; y++) {
879 if (fwrite(win->_line[y].text,
880 sizeof(NCURSES_CH_T), len, filep) != len
881 || ferror(filep)) {
882 returnCode(code);
885 code = OK;
887 #endif
888 returnCode(code);
891 NCURSES_EXPORT(int)
892 NCURSES_SP_NAME(scr_restore) (NCURSES_SP_DCLx const char *file)
894 FILE *fp = 0;
895 int code = ERR;
897 T((T_CALLED("scr_restore(%p,%s)"), (void *) SP_PARM, _nc_visbuf(file)));
899 if (_nc_access(file, R_OK) >= 0
900 && (fp = fopen(file, "rb")) != 0) {
901 delwin(NewScreen(SP_PARM));
902 NewScreen(SP_PARM) = getwin(fp);
903 #if !USE_REENTRANT
904 newscr = NewScreen(SP_PARM);
905 #endif
906 (void) fclose(fp);
907 if (NewScreen(SP_PARM) != 0) {
908 code = OK;
911 returnCode(code);
914 #if NCURSES_SP_FUNCS
915 NCURSES_EXPORT(int)
916 scr_restore(const char *file)
918 return NCURSES_SP_NAME(scr_restore) (CURRENT_SCREEN, file);
920 #endif
922 NCURSES_EXPORT(int)
923 scr_dump(const char *file)
925 int result;
926 FILE *fp = 0;
928 T((T_CALLED("scr_dump(%s)"), _nc_visbuf(file)));
930 if (_nc_access(file, W_OK) < 0
931 || (fp = fopen(file, "wb")) == 0) {
932 result = ERR;
933 } else {
934 (void) putwin(newscr, fp);
935 (void) fclose(fp);
936 result = OK;
938 returnCode(result);
941 NCURSES_EXPORT(int)
942 NCURSES_SP_NAME(scr_init) (NCURSES_SP_DCLx const char *file)
944 FILE *fp = 0;
945 int code = ERR;
947 T((T_CALLED("scr_init(%p,%s)"), (void *) SP_PARM, _nc_visbuf(file)));
949 if (SP_PARM != 0 &&
950 #ifdef USE_TERM_DRIVER
951 InfoOf(SP_PARM).caninit
952 #else
953 !(exit_ca_mode && non_rev_rmcup)
954 #endif
956 if (_nc_access(file, R_OK) >= 0
957 && (fp = fopen(file, "rb")) != 0) {
958 delwin(CurScreen(SP_PARM));
959 CurScreen(SP_PARM) = getwin(fp);
960 #if !USE_REENTRANT
961 curscr = CurScreen(SP_PARM);
962 #endif
963 (void) fclose(fp);
964 if (CurScreen(SP_PARM) != 0) {
965 code = OK;
969 returnCode(code);
972 #if NCURSES_SP_FUNCS
973 NCURSES_EXPORT(int)
974 scr_init(const char *file)
976 return NCURSES_SP_NAME(scr_init) (CURRENT_SCREEN, file);
978 #endif
980 NCURSES_EXPORT(int)
981 NCURSES_SP_NAME(scr_set) (NCURSES_SP_DCLx const char *file)
983 int code = ERR;
985 T((T_CALLED("scr_set(%p,%s)"), (void *) SP_PARM, _nc_visbuf(file)));
987 if (NCURSES_SP_NAME(scr_init) (NCURSES_SP_ARGx file) == OK) {
988 delwin(NewScreen(SP_PARM));
989 NewScreen(SP_PARM) = dupwin(curscr);
990 #if !USE_REENTRANT
991 newscr = NewScreen(SP_PARM);
992 #endif
993 if (NewScreen(SP_PARM) != 0) {
994 code = OK;
997 returnCode(code);
1000 #if NCURSES_SP_FUNCS
1001 NCURSES_EXPORT(int)
1002 scr_set(const char *file)
1004 return NCURSES_SP_NAME(scr_set) (CURRENT_SCREEN, file);
1006 #endif