1fdd4e1e0SJan Lentfer /****************************************************************************
2*32bb5217SDaniel Fojt * Copyright 2019,2020 Thomas E. Dickey *
3*32bb5217SDaniel Fojt * Copyright 1998-2017,2018 Free Software Foundation, Inc. *
4fdd4e1e0SJan Lentfer * *
5fdd4e1e0SJan Lentfer * Permission is hereby granted, free of charge, to any person obtaining a *
6fdd4e1e0SJan Lentfer * copy of this software and associated documentation files (the *
7fdd4e1e0SJan Lentfer * "Software"), to deal in the Software without restriction, including *
8fdd4e1e0SJan Lentfer * without limitation the rights to use, copy, modify, merge, publish, *
9fdd4e1e0SJan Lentfer * distribute, distribute with modifications, sublicense, and/or sell *
10fdd4e1e0SJan Lentfer * copies of the Software, and to permit persons to whom the Software is *
11fdd4e1e0SJan Lentfer * furnished to do so, subject to the following conditions: *
12fdd4e1e0SJan Lentfer * *
13fdd4e1e0SJan Lentfer * The above copyright notice and this permission notice shall be included *
14fdd4e1e0SJan Lentfer * in all copies or substantial portions of the Software. *
15fdd4e1e0SJan Lentfer * *
16fdd4e1e0SJan Lentfer * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
17fdd4e1e0SJan Lentfer * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
18fdd4e1e0SJan Lentfer * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
19fdd4e1e0SJan Lentfer * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
20fdd4e1e0SJan Lentfer * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
21fdd4e1e0SJan Lentfer * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
22fdd4e1e0SJan Lentfer * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
23fdd4e1e0SJan Lentfer * *
24fdd4e1e0SJan Lentfer * Except as contained in this notice, the name(s) of the above copyright *
25fdd4e1e0SJan Lentfer * holders shall not be used in advertising or otherwise to promote the *
26fdd4e1e0SJan Lentfer * sale, use or other dealings in this Software without prior written *
27fdd4e1e0SJan Lentfer * authorization. *
28fdd4e1e0SJan Lentfer ****************************************************************************/
29fdd4e1e0SJan Lentfer
30fdd4e1e0SJan Lentfer /****************************************************************************
31fdd4e1e0SJan Lentfer * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 *
32fdd4e1e0SJan Lentfer * and: Eric S. Raymond <esr@snark.thyrsus.com> *
33fdd4e1e0SJan Lentfer * and: Thomas E. Dickey 1996 on *
3400d8f3c4SJohn Marino * and: Juergen Pfeifer 2009 *
35fdd4e1e0SJan Lentfer ****************************************************************************/
36fdd4e1e0SJan Lentfer
37fdd4e1e0SJan Lentfer #include <curses.priv.h>
38fdd4e1e0SJan Lentfer
393468e90cSJohn Marino #include <ctype.h>
403468e90cSJohn Marino
4100d8f3c4SJohn Marino #ifndef CUR
4200d8f3c4SJohn Marino #define CUR SP_TERMTYPE
4300d8f3c4SJohn Marino #endif
4400d8f3c4SJohn Marino
45*32bb5217SDaniel Fojt MODULE_ID("$Id: lib_screen.c,v 1.97 2020/02/02 23:34:34 tom Exp $")
461d102085SJan Lentfer
471d102085SJan Lentfer #define MAX_SIZE 0x3fff /* 16k is big enough for a window or pad */
48fdd4e1e0SJan Lentfer
493468e90cSJohn Marino #define MARKER '\\'
503468e90cSJohn Marino #define APPEND '+'
513468e90cSJohn Marino #define GUTTER '|'
523468e90cSJohn Marino #define L_CURL '{'
533468e90cSJohn Marino #define R_CURL '}'
543468e90cSJohn Marino
55*32bb5217SDaniel Fojt #if USE_STRING_HACKS && HAVE_SNPRINTF
56*32bb5217SDaniel Fojt #define ARG_SLIMIT(name) size_t name,
57*32bb5217SDaniel Fojt #else
58*32bb5217SDaniel Fojt #define ARG_SLIMIT(name) /* nothing */
59*32bb5217SDaniel Fojt #endif
60*32bb5217SDaniel Fojt
61*32bb5217SDaniel Fojt #define CUR_SLIMIT _nc_SLIMIT(limit - (target - base))
62*32bb5217SDaniel Fojt #define TOP_SLIMIT _nc_SLIMIT(sizeof(buffer))
63*32bb5217SDaniel Fojt
643468e90cSJohn Marino /*
65*32bb5217SDaniel Fojt * Use 0x888888 as the magic number for new-format files, since it cannot be
663468e90cSJohn Marino * mistaken for the _cury/_curx pair of 16-bit numbers which start the old
673468e90cSJohn Marino * format. It happens to be unused in the file 5.22 database (2015/03/07).
683468e90cSJohn Marino */
693468e90cSJohn Marino static const char my_magic[] =
703468e90cSJohn Marino {'\210', '\210', '\210', '\210'};
713468e90cSJohn Marino
723468e90cSJohn Marino #if NCURSES_EXT_PUTWIN
733468e90cSJohn Marino typedef enum {
743468e90cSJohn Marino pINT /* int */
753468e90cSJohn Marino ,pSHORT /* short */
763468e90cSJohn Marino ,pBOOL /* bool */
773468e90cSJohn Marino ,pATTR /* attr_t */
783468e90cSJohn Marino ,pCHAR /* chtype */
793468e90cSJohn Marino ,pSIZE /* NCURSES_SIZE_T */
803468e90cSJohn Marino #if NCURSES_WIDECHAR
813468e90cSJohn Marino ,pCCHAR /* cchar_t */
823468e90cSJohn Marino #endif
833468e90cSJohn Marino } PARAM_TYPE;
843468e90cSJohn Marino
853468e90cSJohn Marino typedef struct {
863468e90cSJohn Marino const char name[11];
873468e90cSJohn Marino attr_t attr;
883468e90cSJohn Marino } SCR_ATTRS;
893468e90cSJohn Marino
903468e90cSJohn Marino typedef struct {
913468e90cSJohn Marino const char name[17];
923468e90cSJohn Marino PARAM_TYPE type;
933468e90cSJohn Marino size_t size;
943468e90cSJohn Marino size_t offset;
953468e90cSJohn Marino } SCR_PARAMS;
963468e90cSJohn Marino
973468e90cSJohn Marino #define DATA(name) { { #name }, A_##name }
983468e90cSJohn Marino static const SCR_ATTRS scr_attrs[] =
993468e90cSJohn Marino {
1003468e90cSJohn Marino DATA(NORMAL),
1013468e90cSJohn Marino DATA(STANDOUT),
1023468e90cSJohn Marino DATA(UNDERLINE),
1033468e90cSJohn Marino DATA(REVERSE),
1043468e90cSJohn Marino DATA(BLINK),
1053468e90cSJohn Marino DATA(DIM),
1063468e90cSJohn Marino DATA(BOLD),
1073468e90cSJohn Marino DATA(ALTCHARSET),
1083468e90cSJohn Marino DATA(INVIS),
1093468e90cSJohn Marino DATA(PROTECT),
1103468e90cSJohn Marino DATA(HORIZONTAL),
1113468e90cSJohn Marino DATA(LEFT),
1123468e90cSJohn Marino DATA(LOW),
1133468e90cSJohn Marino DATA(RIGHT),
1143468e90cSJohn Marino DATA(TOP),
1153468e90cSJohn Marino DATA(VERTICAL),
1163468e90cSJohn Marino
1173468e90cSJohn Marino #ifdef A_ITALIC
1183468e90cSJohn Marino DATA(ITALIC),
1193468e90cSJohn Marino #endif
1203468e90cSJohn Marino };
1213468e90cSJohn Marino #undef DATA
1223468e90cSJohn Marino
1233468e90cSJohn Marino #define sizeof2(type,name) sizeof(((type *)0)->name)
1243468e90cSJohn Marino #define DATA(name, type) { { #name }, type, sizeof2(WINDOW, name), offsetof(WINDOW, name) }
1253468e90cSJohn Marino
1263468e90cSJohn Marino static const SCR_PARAMS scr_params[] =
1273468e90cSJohn Marino {
1283468e90cSJohn Marino DATA(_cury, pSIZE),
1293468e90cSJohn Marino DATA(_curx, pSIZE),
1303468e90cSJohn Marino DATA(_maxy, pSIZE),
1313468e90cSJohn Marino DATA(_maxx, pSIZE),
1323468e90cSJohn Marino DATA(_begy, pSIZE),
1333468e90cSJohn Marino DATA(_begx, pSIZE),
1343468e90cSJohn Marino DATA(_flags, pSHORT),
1353468e90cSJohn Marino DATA(_attrs, pATTR),
1363468e90cSJohn Marino DATA(_bkgd, pCHAR),
1373468e90cSJohn Marino DATA(_notimeout, pBOOL),
1383468e90cSJohn Marino DATA(_clear, pBOOL),
1393468e90cSJohn Marino DATA(_leaveok, pBOOL),
1403468e90cSJohn Marino DATA(_scroll, pBOOL),
1413468e90cSJohn Marino DATA(_idlok, pBOOL),
1423468e90cSJohn Marino DATA(_idcok, pBOOL),
1433468e90cSJohn Marino DATA(_immed, pBOOL),
1443468e90cSJohn Marino DATA(_sync, pBOOL),
1453468e90cSJohn Marino DATA(_use_keypad, pBOOL),
1463468e90cSJohn Marino DATA(_delay, pINT),
1473468e90cSJohn Marino DATA(_regtop, pSIZE),
1483468e90cSJohn Marino DATA(_regbottom, pSIZE),
1493468e90cSJohn Marino DATA(_pad._pad_y, pSIZE),
1503468e90cSJohn Marino DATA(_pad._pad_x, pSIZE),
1513468e90cSJohn Marino DATA(_pad._pad_top, pSIZE),
1523468e90cSJohn Marino DATA(_pad._pad_left, pSIZE),
1533468e90cSJohn Marino DATA(_pad._pad_bottom, pSIZE),
1543468e90cSJohn Marino DATA(_pad._pad_right, pSIZE),
1553468e90cSJohn Marino DATA(_yoffset, pSIZE),
1563468e90cSJohn Marino #if NCURSES_WIDECHAR
1573468e90cSJohn Marino DATA(_bkgrnd, pCCHAR),
1583468e90cSJohn Marino #if NCURSES_EXT_COLORS
1593468e90cSJohn Marino DATA(_color, pINT),
1603468e90cSJohn Marino #endif
1613468e90cSJohn Marino #endif
1623468e90cSJohn Marino };
1633468e90cSJohn Marino #undef DATA
1643468e90cSJohn Marino
1653468e90cSJohn Marino static const NCURSES_CH_T blank = NewChar(BLANK_TEXT);
1663468e90cSJohn Marino
1673468e90cSJohn Marino /*
1683468e90cSJohn Marino * Allocate and read a line of text. Caller must free it.
1693468e90cSJohn Marino */
1703468e90cSJohn Marino static char *
read_txt(FILE * fp)1713468e90cSJohn Marino read_txt(FILE *fp)
1723468e90cSJohn Marino {
1733468e90cSJohn Marino size_t limit = 1024;
1743468e90cSJohn Marino char *result = malloc(limit);
1753468e90cSJohn Marino char *buffer;
1763468e90cSJohn Marino
1773468e90cSJohn Marino if (result != 0) {
1783468e90cSJohn Marino int ch = 0;
179*32bb5217SDaniel Fojt size_t used = 0;
1803468e90cSJohn Marino
1813468e90cSJohn Marino clearerr(fp);
1823468e90cSJohn Marino result[used] = '\0';
1833468e90cSJohn Marino do {
1843468e90cSJohn Marino if (used + 2 >= limit) {
1853468e90cSJohn Marino limit += 1024;
1863468e90cSJohn Marino buffer = realloc(result, limit);
1873468e90cSJohn Marino if (buffer == 0) {
1883468e90cSJohn Marino free(result);
1893468e90cSJohn Marino result = 0;
1903468e90cSJohn Marino break;
1913468e90cSJohn Marino }
1923468e90cSJohn Marino result = buffer;
1933468e90cSJohn Marino }
1943468e90cSJohn Marino ch = fgetc(fp);
1953468e90cSJohn Marino if (ch == EOF)
1963468e90cSJohn Marino break;
1973468e90cSJohn Marino result[used++] = (char) ch;
1983468e90cSJohn Marino result[used] = '\0';
1993468e90cSJohn Marino } while (ch != '\n');
2003468e90cSJohn Marino
2013468e90cSJohn Marino if (ch == '\n') {
2023468e90cSJohn Marino result[--used] = '\0';
2033468e90cSJohn Marino T(("READ:%s", result));
2043468e90cSJohn Marino } else if (used == 0) {
2053468e90cSJohn Marino free(result);
2063468e90cSJohn Marino result = 0;
2073468e90cSJohn Marino }
2083468e90cSJohn Marino }
2093468e90cSJohn Marino return result;
2103468e90cSJohn Marino }
2113468e90cSJohn Marino
2123468e90cSJohn Marino static char *
decode_attr(char * source,attr_t * target,int * color)2133468e90cSJohn Marino decode_attr(char *source, attr_t *target, int *color)
2143468e90cSJohn Marino {
2153468e90cSJohn Marino bool found = FALSE;
2163468e90cSJohn Marino
2173468e90cSJohn Marino T(("decode_attr '%s'", source));
2183468e90cSJohn Marino
2193468e90cSJohn Marino while (*source) {
2203468e90cSJohn Marino if (source[0] == MARKER && source[1] == L_CURL) {
2213468e90cSJohn Marino source += 2;
2223468e90cSJohn Marino found = TRUE;
2233468e90cSJohn Marino } else if (source[0] == R_CURL) {
2243468e90cSJohn Marino source++;
2253468e90cSJohn Marino found = FALSE;
2263468e90cSJohn Marino } else if (found) {
2273468e90cSJohn Marino size_t n;
2283468e90cSJohn Marino char *next = source;
2293468e90cSJohn Marino
2303468e90cSJohn Marino if (source[0] == GUTTER) {
2313468e90cSJohn Marino ++next;
2323468e90cSJohn Marino } else if (*next == 'C') {
2333468e90cSJohn Marino int value = 0;
2343468e90cSJohn Marino unsigned pair;
2353468e90cSJohn Marino next++;
2363468e90cSJohn Marino while (isdigit(UChar(*next))) {
2373468e90cSJohn Marino value = value * 10 + (*next++ - '0');
2383468e90cSJohn Marino }
2393468e90cSJohn Marino *target &= ~A_COLOR;
2403468e90cSJohn Marino pair = (unsigned) ((value > 256)
2413468e90cSJohn Marino ? COLOR_PAIR(255)
2423468e90cSJohn Marino : COLOR_PAIR(value));
2433468e90cSJohn Marino *target |= pair;
2443468e90cSJohn Marino *color = value;
2453468e90cSJohn Marino } else {
2463468e90cSJohn Marino while (isalnum(UChar(*next))) {
2473468e90cSJohn Marino ++next;
2483468e90cSJohn Marino }
2493468e90cSJohn Marino for (n = 0; n < SIZEOF(scr_attrs); ++n) {
2503468e90cSJohn Marino if ((size_t) (next - source) == strlen(scr_attrs[n].name)) {
2513468e90cSJohn Marino if (scr_attrs[n].attr) {
2523468e90cSJohn Marino *target |= scr_attrs[n].attr;
2533468e90cSJohn Marino } else {
2543468e90cSJohn Marino *target = A_NORMAL;
2553468e90cSJohn Marino }
2563468e90cSJohn Marino break;
2573468e90cSJohn Marino }
2583468e90cSJohn Marino }
2593468e90cSJohn Marino }
2603468e90cSJohn Marino source = next;
2613468e90cSJohn Marino } else {
2623468e90cSJohn Marino break;
2633468e90cSJohn Marino }
2643468e90cSJohn Marino }
2653468e90cSJohn Marino return source;
2663468e90cSJohn Marino }
2673468e90cSJohn Marino
2683468e90cSJohn Marino static char *
decode_char(char * source,int * target)2693468e90cSJohn Marino decode_char(char *source, int *target)
2703468e90cSJohn Marino {
2713468e90cSJohn Marino int limit = 0;
2723468e90cSJohn Marino int base = 16;
2733468e90cSJohn Marino const char digits[] = "0123456789abcdef";
2743468e90cSJohn Marino
2753468e90cSJohn Marino T(("decode_char '%s'", source));
2763468e90cSJohn Marino *target = ' ';
2773468e90cSJohn Marino switch (*source) {
2783468e90cSJohn Marino case MARKER:
2793468e90cSJohn Marino switch (*++source) {
2803468e90cSJohn Marino case APPEND:
2813468e90cSJohn Marino break;
2823468e90cSJohn Marino case MARKER:
2833468e90cSJohn Marino *target = MARKER;
2843468e90cSJohn Marino ++source;
2853468e90cSJohn Marino break;
2863468e90cSJohn Marino case 's':
2873468e90cSJohn Marino *target = ' ';
2883468e90cSJohn Marino ++source;
2893468e90cSJohn Marino break;
2903468e90cSJohn Marino case '0':
2913468e90cSJohn Marino case '1':
2923468e90cSJohn Marino case '2':
2933468e90cSJohn Marino case '3':
2943468e90cSJohn Marino base = 8;
2953468e90cSJohn Marino limit = 3;
2963468e90cSJohn Marino break;
2973468e90cSJohn Marino case 'u':
2983468e90cSJohn Marino limit = 4;
2993468e90cSJohn Marino ++source;
3003468e90cSJohn Marino break;
3013468e90cSJohn Marino case 'U':
3023468e90cSJohn Marino limit = 8;
3033468e90cSJohn Marino ++source;
3043468e90cSJohn Marino break;
3053468e90cSJohn Marino }
3063468e90cSJohn Marino if (limit) {
3073468e90cSJohn Marino *target = 0;
3083468e90cSJohn Marino while (limit-- > 0) {
3093468e90cSJohn Marino char *find = strchr(digits, *source++);
3103468e90cSJohn Marino int ch = (find != 0) ? (int) (find - digits) : -1;
3113468e90cSJohn Marino *target *= base;
3123468e90cSJohn Marino if (ch >= 0 && ch < base) {
3133468e90cSJohn Marino *target += ch;
3143468e90cSJohn Marino }
3153468e90cSJohn Marino }
3163468e90cSJohn Marino }
3173468e90cSJohn Marino break;
3183468e90cSJohn Marino default:
3193468e90cSJohn Marino *target = *source++;
3203468e90cSJohn Marino break;
3213468e90cSJohn Marino }
3223468e90cSJohn Marino return source;
3233468e90cSJohn Marino }
3243468e90cSJohn Marino
3253468e90cSJohn Marino static char *
decode_chtype(char * source,chtype fillin,chtype * target)3263468e90cSJohn Marino decode_chtype(char *source, chtype fillin, chtype *target)
3273468e90cSJohn Marino {
3283468e90cSJohn Marino attr_t attr = ChAttrOf(fillin);
3293468e90cSJohn Marino int color = PAIR_NUMBER((int) attr);
3303468e90cSJohn Marino int value;
3313468e90cSJohn Marino
3323468e90cSJohn Marino T(("decode_chtype '%s'", source));
3333468e90cSJohn Marino source = decode_attr(source, &attr, &color);
3343468e90cSJohn Marino source = decode_char(source, &value);
3353468e90cSJohn Marino *target = (ChCharOf(value) | attr | (chtype) COLOR_PAIR(color));
3363468e90cSJohn Marino /* FIXME - ignore combining characters */
3373468e90cSJohn Marino return source;
3383468e90cSJohn Marino }
3393468e90cSJohn Marino
3403468e90cSJohn Marino #if NCURSES_WIDECHAR
3413468e90cSJohn Marino static char *
decode_cchar(char * source,cchar_t * fillin,cchar_t * target)3423468e90cSJohn Marino decode_cchar(char *source, cchar_t *fillin, cchar_t *target)
3433468e90cSJohn Marino {
3443468e90cSJohn Marino int color;
3453468e90cSJohn Marino attr_t attr = fillin->attr;
3463468e90cSJohn Marino wchar_t chars[CCHARW_MAX];
3473468e90cSJohn Marino int append = 0;
3483468e90cSJohn Marino int value = 0;
3493468e90cSJohn Marino
3503468e90cSJohn Marino T(("decode_cchar '%s'", source));
3513468e90cSJohn Marino *target = blank;
3523468e90cSJohn Marino #if NCURSES_EXT_COLORS
3533468e90cSJohn Marino color = fillin->ext_color;
3543468e90cSJohn Marino #else
3553468e90cSJohn Marino color = (int) PAIR_NUMBER(attr);
3563468e90cSJohn Marino #endif
3573468e90cSJohn Marino source = decode_attr(source, &attr, &color);
3583468e90cSJohn Marino memset(chars, 0, sizeof(chars));
3593468e90cSJohn Marino source = decode_char(source, &value);
3603468e90cSJohn Marino chars[0] = (wchar_t) value;
3613468e90cSJohn Marino /* handle combining characters */
3623468e90cSJohn Marino while (source[0] == MARKER && source[1] == APPEND) {
3633468e90cSJohn Marino source += 2;
3643468e90cSJohn Marino source = decode_char(source, &value);
3653468e90cSJohn Marino if (++append < CCHARW_MAX) {
3663468e90cSJohn Marino chars[append] = (wchar_t) value;
3673468e90cSJohn Marino }
3683468e90cSJohn Marino }
369*32bb5217SDaniel Fojt setcchar(target, chars, attr, (short) color, &color);
3703468e90cSJohn Marino return source;
3713468e90cSJohn Marino }
3723468e90cSJohn Marino #endif
3733468e90cSJohn Marino
3743468e90cSJohn Marino static int
read_win(WINDOW * win,FILE * fp)3753468e90cSJohn Marino read_win(WINDOW *win, FILE *fp)
3763468e90cSJohn Marino {
3773468e90cSJohn Marino int code = ERR;
3783468e90cSJohn Marino size_t n;
3793468e90cSJohn Marino int color;
3803468e90cSJohn Marino #if NCURSES_WIDECHAR
3813468e90cSJohn Marino NCURSES_CH_T prior;
3823468e90cSJohn Marino #endif
3833468e90cSJohn Marino chtype prior2;
3843468e90cSJohn Marino
3853468e90cSJohn Marino memset(win, 0, sizeof(WINDOW));
3863468e90cSJohn Marino for (;;) {
387*32bb5217SDaniel Fojt char *name;
388*32bb5217SDaniel Fojt char *value;
389*32bb5217SDaniel Fojt char *txt = read_txt(fp);
390*32bb5217SDaniel Fojt
3913468e90cSJohn Marino if (txt == 0)
3923468e90cSJohn Marino break;
3933468e90cSJohn Marino if (!strcmp(txt, "rows:")) {
3943468e90cSJohn Marino free(txt);
3953468e90cSJohn Marino code = OK;
3963468e90cSJohn Marino break;
3973468e90cSJohn Marino }
3983468e90cSJohn Marino if ((value = strchr(txt, '=')) == 0) {
3993468e90cSJohn Marino free(txt);
4003468e90cSJohn Marino continue;
4013468e90cSJohn Marino }
4023468e90cSJohn Marino *value++ = '\0';
4033468e90cSJohn Marino name = !strcmp(txt, "flag") ? value : txt;
4043468e90cSJohn Marino for (n = 0; n < SIZEOF(scr_params); ++n) {
4053468e90cSJohn Marino if (!strcmp(name, scr_params[n].name)) {
4063468e90cSJohn Marino void *data = (void *) ((char *) win + scr_params[n].offset);
4073468e90cSJohn Marino
4083468e90cSJohn Marino switch (scr_params[n].type) {
4093468e90cSJohn Marino case pATTR:
4103468e90cSJohn Marino (void) decode_attr(value, data, &color);
4113468e90cSJohn Marino break;
4123468e90cSJohn Marino case pBOOL:
4133468e90cSJohn Marino *(bool *) data = TRUE;
4143468e90cSJohn Marino break;
4153468e90cSJohn Marino case pCHAR:
4163468e90cSJohn Marino prior2 = ' ';
4173468e90cSJohn Marino decode_chtype(value, prior2, data);
4183468e90cSJohn Marino break;
4193468e90cSJohn Marino case pINT:
4203468e90cSJohn Marino *(int *) data = atoi(value);
4213468e90cSJohn Marino break;
4223468e90cSJohn Marino case pSHORT:
4233468e90cSJohn Marino *(short *) data = (short) atoi(value);
4243468e90cSJohn Marino break;
4253468e90cSJohn Marino case pSIZE:
4263468e90cSJohn Marino *(NCURSES_SIZE_T *) data = (NCURSES_SIZE_T) atoi(value);
4273468e90cSJohn Marino break;
4283468e90cSJohn Marino #if NCURSES_WIDECHAR
4293468e90cSJohn Marino case pCCHAR:
4303468e90cSJohn Marino prior = blank;
4313468e90cSJohn Marino decode_cchar(value, &prior, data);
4323468e90cSJohn Marino break;
4333468e90cSJohn Marino #endif
4343468e90cSJohn Marino }
4353468e90cSJohn Marino break;
4363468e90cSJohn Marino }
4373468e90cSJohn Marino }
4383468e90cSJohn Marino free(txt);
4393468e90cSJohn Marino }
4403468e90cSJohn Marino return code;
4413468e90cSJohn Marino }
4423468e90cSJohn Marino
4433468e90cSJohn Marino static int
read_row(char * source,NCURSES_CH_T * prior,NCURSES_CH_T * target,int length)4443468e90cSJohn Marino read_row(char *source, NCURSES_CH_T * prior, NCURSES_CH_T * target, int length)
4453468e90cSJohn Marino {
4463468e90cSJohn Marino while (*source != '\0' && length > 0) {
4473468e90cSJohn Marino #if NCURSES_WIDECHAR
448*32bb5217SDaniel Fojt int len;
449*32bb5217SDaniel Fojt
4503468e90cSJohn Marino source = decode_cchar(source, prior, target);
451*32bb5217SDaniel Fojt len = _nc_wacs_width(target->chars[0]);
4523468e90cSJohn Marino if (len > 1) {
453*32bb5217SDaniel Fojt int n;
454*32bb5217SDaniel Fojt
4553468e90cSJohn Marino SetWidecExt(CHDEREF(target), 0);
4563468e90cSJohn Marino for (n = 1; n < len; ++n) {
4573468e90cSJohn Marino target[n] = target[0];
4583468e90cSJohn Marino SetWidecExt(CHDEREF(target), n);
4593468e90cSJohn Marino }
4603468e90cSJohn Marino target += (len - 1);
4613468e90cSJohn Marino length -= (len - 1);
4623468e90cSJohn Marino }
4633468e90cSJohn Marino #else
4643468e90cSJohn Marino source = decode_chtype(source, *prior, target);
4653468e90cSJohn Marino #endif
4663468e90cSJohn Marino *prior = *target;
4673468e90cSJohn Marino ++target;
4683468e90cSJohn Marino --length;
4693468e90cSJohn Marino }
4703468e90cSJohn Marino while (length-- > 0) {
4713468e90cSJohn Marino *target++ = blank;
4723468e90cSJohn Marino }
4733468e90cSJohn Marino /* FIXME - see what error conditions should apply if I need to return ERR */
4743468e90cSJohn Marino return 0;
4753468e90cSJohn Marino }
4763468e90cSJohn Marino #endif /* NCURSES_EXT_PUTWIN */
4773468e90cSJohn Marino
4783468e90cSJohn Marino /*
4793468e90cSJohn Marino * Originally, getwin/putwin used fread/fwrite, because they used binary data.
4803468e90cSJohn Marino * The new format uses printable ASCII, which does not have as predictable
4813468e90cSJohn Marino * sizes. Consequently, we use buffered I/O, e.g., fgetc/fprintf, which need
4823468e90cSJohn Marino * special handling if we want to read screen dumps from an older library.
4833468e90cSJohn Marino */
4843468e90cSJohn Marino static int
read_block(void * target,size_t length,FILE * fp)4853468e90cSJohn Marino read_block(void *target, size_t length, FILE *fp)
4863468e90cSJohn Marino {
4873468e90cSJohn Marino int result = 0;
4883468e90cSJohn Marino char *buffer = target;
4893468e90cSJohn Marino
4903468e90cSJohn Marino clearerr(fp);
4913468e90cSJohn Marino while (length-- != 0) {
4923468e90cSJohn Marino int ch = fgetc(fp);
4933468e90cSJohn Marino if (ch == EOF) {
4943468e90cSJohn Marino result = -1;
4953468e90cSJohn Marino break;
4963468e90cSJohn Marino }
4973468e90cSJohn Marino *buffer++ = (char) ch;
4983468e90cSJohn Marino }
4993468e90cSJohn Marino return result;
5003468e90cSJohn Marino }
5013468e90cSJohn Marino
502fdd4e1e0SJan Lentfer NCURSES_EXPORT(WINDOW *)
NCURSES_SP_NAME(getwin)50300d8f3c4SJohn Marino NCURSES_SP_NAME(getwin) (NCURSES_SP_DCLx FILE *filep)
504fdd4e1e0SJan Lentfer {
505fdd4e1e0SJan Lentfer WINDOW tmp, *nwin;
5063468e90cSJohn Marino bool old_format = FALSE;
507fdd4e1e0SJan Lentfer
50800d8f3c4SJohn Marino T((T_CALLED("getwin(%p)"), (void *) filep));
509fdd4e1e0SJan Lentfer
5103468e90cSJohn Marino if (filep == 0) {
5113468e90cSJohn Marino returnWin(0);
5123468e90cSJohn Marino }
5133468e90cSJohn Marino
5143468e90cSJohn Marino /*
5153468e90cSJohn Marino * Read the first 4 bytes to determine first if this is an old-format
5163468e90cSJohn Marino * screen-dump, or new-format.
5173468e90cSJohn Marino */
518*32bb5217SDaniel Fojt if (read_block(&tmp, (size_t) 4, filep) < 0) {
5193468e90cSJohn Marino returnWin(0);
5203468e90cSJohn Marino }
5213468e90cSJohn Marino /*
5223468e90cSJohn Marino * If this is a new-format file, and we do not support it, give up.
5233468e90cSJohn Marino */
524*32bb5217SDaniel Fojt if (!memcmp(&tmp, my_magic, (size_t) 4)) {
5253468e90cSJohn Marino #if NCURSES_EXT_PUTWIN
5263468e90cSJohn Marino if (read_win(&tmp, filep) < 0)
5273468e90cSJohn Marino #endif
5283468e90cSJohn Marino returnWin(0);
5293468e90cSJohn Marino } else if (read_block(((char *) &tmp) + 4, sizeof(WINDOW) - 4, filep) < 0) {
5303468e90cSJohn Marino returnWin(0);
5313468e90cSJohn Marino } else {
5323468e90cSJohn Marino old_format = TRUE;
5333468e90cSJohn Marino }
5343468e90cSJohn Marino
5353468e90cSJohn Marino /*
5363468e90cSJohn Marino * Check the window-size:
5373468e90cSJohn Marino */
5383468e90cSJohn Marino if (tmp._maxy == 0 ||
5393468e90cSJohn Marino tmp._maxy > MAX_SIZE ||
5403468e90cSJohn Marino tmp._maxx == 0 ||
5413468e90cSJohn Marino tmp._maxx > MAX_SIZE) {
542fdd4e1e0SJan Lentfer returnWin(0);
54300d8f3c4SJohn Marino }
544fdd4e1e0SJan Lentfer
545fdd4e1e0SJan Lentfer if (tmp._flags & _ISPAD) {
54600d8f3c4SJohn Marino nwin = NCURSES_SP_NAME(newpad) (NCURSES_SP_ARGx
54700d8f3c4SJohn Marino tmp._maxy + 1,
54800d8f3c4SJohn Marino tmp._maxx + 1);
549fdd4e1e0SJan Lentfer } else {
55000d8f3c4SJohn Marino nwin = NCURSES_SP_NAME(newwin) (NCURSES_SP_ARGx
55100d8f3c4SJohn Marino tmp._maxy + 1,
55200d8f3c4SJohn Marino tmp._maxx + 1, 0, 0);
553fdd4e1e0SJan Lentfer }
554fdd4e1e0SJan Lentfer
555fdd4e1e0SJan Lentfer /*
556fdd4e1e0SJan Lentfer * We deliberately do not restore the _parx, _pary, or _parent
557fdd4e1e0SJan Lentfer * fields, because the window hierarchy within which they
558fdd4e1e0SJan Lentfer * made sense is probably gone.
559fdd4e1e0SJan Lentfer */
560fdd4e1e0SJan Lentfer if (nwin != 0) {
561*32bb5217SDaniel Fojt int n;
56200d8f3c4SJohn Marino size_t linesize = sizeof(NCURSES_CH_T) * (size_t) (tmp._maxx + 1);
56300d8f3c4SJohn Marino
564fdd4e1e0SJan Lentfer nwin->_curx = tmp._curx;
565fdd4e1e0SJan Lentfer nwin->_cury = tmp._cury;
566fdd4e1e0SJan Lentfer nwin->_maxy = tmp._maxy;
567fdd4e1e0SJan Lentfer nwin->_maxx = tmp._maxx;
568fdd4e1e0SJan Lentfer nwin->_begy = tmp._begy;
569fdd4e1e0SJan Lentfer nwin->_begx = tmp._begx;
570fdd4e1e0SJan Lentfer nwin->_yoffset = tmp._yoffset;
571fdd4e1e0SJan Lentfer nwin->_flags = tmp._flags & ~(_SUBWIN);
572fdd4e1e0SJan Lentfer
5731d102085SJan Lentfer WINDOW_ATTRS(nwin) = WINDOW_ATTRS(&tmp);
574fdd4e1e0SJan Lentfer nwin->_nc_bkgd = tmp._nc_bkgd;
575fdd4e1e0SJan Lentfer
576fdd4e1e0SJan Lentfer nwin->_notimeout = tmp._notimeout;
577fdd4e1e0SJan Lentfer nwin->_clear = tmp._clear;
578fdd4e1e0SJan Lentfer nwin->_leaveok = tmp._leaveok;
579fdd4e1e0SJan Lentfer nwin->_idlok = tmp._idlok;
580fdd4e1e0SJan Lentfer nwin->_idcok = tmp._idcok;
581fdd4e1e0SJan Lentfer nwin->_immed = tmp._immed;
582fdd4e1e0SJan Lentfer nwin->_scroll = tmp._scroll;
583fdd4e1e0SJan Lentfer nwin->_sync = tmp._sync;
584fdd4e1e0SJan Lentfer nwin->_use_keypad = tmp._use_keypad;
585fdd4e1e0SJan Lentfer nwin->_delay = tmp._delay;
586fdd4e1e0SJan Lentfer
587fdd4e1e0SJan Lentfer nwin->_regtop = tmp._regtop;
588fdd4e1e0SJan Lentfer nwin->_regbottom = tmp._regbottom;
589fdd4e1e0SJan Lentfer
590fdd4e1e0SJan Lentfer if (tmp._flags & _ISPAD)
591fdd4e1e0SJan Lentfer nwin->_pad = tmp._pad;
592fdd4e1e0SJan Lentfer
5933468e90cSJohn Marino if (old_format) {
5943468e90cSJohn Marino T(("reading old-format screen dump"));
595fdd4e1e0SJan Lentfer for (n = 0; n <= nwin->_maxy; n++) {
5963468e90cSJohn Marino if (read_block(nwin->_line[n].text, linesize, filep) < 0) {
597fdd4e1e0SJan Lentfer delwin(nwin);
598fdd4e1e0SJan Lentfer returnWin(0);
599fdd4e1e0SJan Lentfer }
600fdd4e1e0SJan Lentfer }
6013468e90cSJohn Marino }
6023468e90cSJohn Marino #if NCURSES_EXT_PUTWIN
6033468e90cSJohn Marino else {
6043468e90cSJohn Marino char *txt = 0;
6053468e90cSJohn Marino bool success = TRUE;
6063468e90cSJohn Marino NCURSES_CH_T prior = blank;
6073468e90cSJohn Marino
6083468e90cSJohn Marino T(("reading new-format screen dump"));
6093468e90cSJohn Marino for (n = 0; n <= nwin->_maxy; n++) {
6103468e90cSJohn Marino long row;
6113468e90cSJohn Marino char *next;
6123468e90cSJohn Marino
6133468e90cSJohn Marino if ((txt = read_txt(filep)) == 0) {
6143468e90cSJohn Marino T(("...failed to read string for row %d", n + 1));
6153468e90cSJohn Marino success = FALSE;
6163468e90cSJohn Marino break;
6173468e90cSJohn Marino }
6183468e90cSJohn Marino row = strtol(txt, &next, 10);
6193468e90cSJohn Marino if (row != (n + 1) || *next != ':') {
6203468e90cSJohn Marino T(("...failed to read row-number %d", n + 1));
6213468e90cSJohn Marino success = FALSE;
6223468e90cSJohn Marino break;
6233468e90cSJohn Marino }
6243468e90cSJohn Marino
6253468e90cSJohn Marino if (read_row(++next, &prior, nwin->_line[n].text, tmp._maxx
6263468e90cSJohn Marino + 1) < 0) {
6273468e90cSJohn Marino T(("...failed to read cells for row %d", n + 1));
6283468e90cSJohn Marino success = FALSE;
6293468e90cSJohn Marino break;
6303468e90cSJohn Marino }
6313468e90cSJohn Marino free(txt);
6323468e90cSJohn Marino txt = 0;
6333468e90cSJohn Marino }
6343468e90cSJohn Marino
6353468e90cSJohn Marino if (!success) {
6363468e90cSJohn Marino free(txt);
6373468e90cSJohn Marino delwin(nwin);
6383468e90cSJohn Marino returnWin(0);
6393468e90cSJohn Marino }
6403468e90cSJohn Marino }
6413468e90cSJohn Marino #endif
642fdd4e1e0SJan Lentfer touchwin(nwin);
643fdd4e1e0SJan Lentfer }
644fdd4e1e0SJan Lentfer returnWin(nwin);
645fdd4e1e0SJan Lentfer }
646fdd4e1e0SJan Lentfer
64700d8f3c4SJohn Marino #if NCURSES_SP_FUNCS
64800d8f3c4SJohn Marino NCURSES_EXPORT(WINDOW *)
getwin(FILE * filep)64900d8f3c4SJohn Marino getwin(FILE *filep)
65000d8f3c4SJohn Marino {
65100d8f3c4SJohn Marino return NCURSES_SP_NAME(getwin) (CURRENT_SCREEN, filep);
65200d8f3c4SJohn Marino }
65300d8f3c4SJohn Marino #endif
65400d8f3c4SJohn Marino
6553468e90cSJohn Marino #if NCURSES_EXT_PUTWIN
6563468e90cSJohn Marino static void
encode_attr(char * target,ARG_SLIMIT (limit)attr_t source,attr_t prior,int source_color,int prior_color)657*32bb5217SDaniel Fojt encode_attr(char *target, ARG_SLIMIT(limit)
658*32bb5217SDaniel Fojt attr_t source,
659*32bb5217SDaniel Fojt attr_t prior,
660*32bb5217SDaniel Fojt int source_color,
661*32bb5217SDaniel Fojt int prior_color)
6623468e90cSJohn Marino {
663*32bb5217SDaniel Fojt #if USE_STRING_HACKS && HAVE_SNPRINTF
664*32bb5217SDaniel Fojt char *base = target;
665*32bb5217SDaniel Fojt #endif
6663468e90cSJohn Marino source &= ~A_CHARTEXT;
6673468e90cSJohn Marino prior &= ~A_CHARTEXT;
6683468e90cSJohn Marino
6693468e90cSJohn Marino *target = '\0';
670*32bb5217SDaniel Fojt if ((source != prior) || (source_color != prior_color)) {
6713468e90cSJohn Marino size_t n;
6723468e90cSJohn Marino bool first = TRUE;
6733468e90cSJohn Marino
6743468e90cSJohn Marino *target++ = MARKER;
6753468e90cSJohn Marino *target++ = L_CURL;
6763468e90cSJohn Marino
6773468e90cSJohn Marino for (n = 0; n < SIZEOF(scr_attrs); ++n) {
6783468e90cSJohn Marino if ((source & scr_attrs[n].attr) != 0 ||
6793468e90cSJohn Marino ((source & ALL_BUT_COLOR) == 0 &&
6803468e90cSJohn Marino (scr_attrs[n].attr == A_NORMAL))) {
6813468e90cSJohn Marino if (first) {
6823468e90cSJohn Marino first = FALSE;
6833468e90cSJohn Marino } else {
6843468e90cSJohn Marino *target++ = '|';
6853468e90cSJohn Marino }
686*32bb5217SDaniel Fojt _nc_STRCPY(target, scr_attrs[n].name, limit);
6873468e90cSJohn Marino target += strlen(target);
6883468e90cSJohn Marino }
6893468e90cSJohn Marino }
690*32bb5217SDaniel Fojt if (source_color != prior_color) {
6913468e90cSJohn Marino if (!first)
6923468e90cSJohn Marino *target++ = '|';
693*32bb5217SDaniel Fojt _nc_SPRINTF(target, CUR_SLIMIT "C%d", source_color);
6943468e90cSJohn Marino target += strlen(target);
6953468e90cSJohn Marino }
6963468e90cSJohn Marino
6973468e90cSJohn Marino *target++ = R_CURL;
6983468e90cSJohn Marino *target = '\0';
6993468e90cSJohn Marino }
7003468e90cSJohn Marino }
7013468e90cSJohn Marino
7023468e90cSJohn Marino static void
encode_cell(char * target,ARG_SLIMIT (limit)CARG_CH_T source,CARG_CH_T previous)703*32bb5217SDaniel Fojt encode_cell(char *target, ARG_SLIMIT(limit) CARG_CH_T source, CARG_CH_T previous)
7043468e90cSJohn Marino {
705*32bb5217SDaniel Fojt #if USE_STRING_HACKS && HAVE_SNPRINTF
706*32bb5217SDaniel Fojt char *base = target;
707*32bb5217SDaniel Fojt #endif
7083468e90cSJohn Marino #if NCURSES_WIDECHAR
7093468e90cSJohn Marino size_t n;
710*32bb5217SDaniel Fojt int source_pair = GetPair(*source);
711*32bb5217SDaniel Fojt int previous_pair = GetPair(*previous);
7123468e90cSJohn Marino
7133468e90cSJohn Marino *target = '\0';
714*32bb5217SDaniel Fojt if ((previous->attr != source->attr) || (previous_pair != source_pair)) {
715*32bb5217SDaniel Fojt encode_attr(target, CUR_SLIMIT
716*32bb5217SDaniel Fojt source->attr,
717*32bb5217SDaniel Fojt previous->attr,
718*32bb5217SDaniel Fojt source_pair,
719*32bb5217SDaniel Fojt previous_pair);
7203468e90cSJohn Marino }
7213468e90cSJohn Marino target += strlen(target);
7223468e90cSJohn Marino #if NCURSES_EXT_COLORS
7233468e90cSJohn Marino if (previous->ext_color != source->ext_color) {
724*32bb5217SDaniel Fojt _nc_SPRINTF(target, CUR_SLIMIT
725*32bb5217SDaniel Fojt "%c%cC%d%c", MARKER, L_CURL, source->ext_color, R_CURL);
7263468e90cSJohn Marino }
7273468e90cSJohn Marino #endif
7283468e90cSJohn Marino for (n = 0; n < SIZEOF(source->chars); ++n) {
7293468e90cSJohn Marino unsigned uch = (unsigned) source->chars[n];
7303468e90cSJohn Marino if (uch == 0)
7313468e90cSJohn Marino continue;
7323468e90cSJohn Marino if (n) {
7333468e90cSJohn Marino *target++ = MARKER;
7343468e90cSJohn Marino *target++ = APPEND;
7353468e90cSJohn Marino }
7363468e90cSJohn Marino *target++ = MARKER;
7373468e90cSJohn Marino if (uch > 0xffff) {
738*32bb5217SDaniel Fojt _nc_SPRINTF(target, CUR_SLIMIT "U%08x", uch);
7393468e90cSJohn Marino } else if (uch > 0xff) {
740*32bb5217SDaniel Fojt _nc_SPRINTF(target, CUR_SLIMIT "u%04x", uch);
7413468e90cSJohn Marino } else if (uch < 32 || uch >= 127) {
742*32bb5217SDaniel Fojt _nc_SPRINTF(target, CUR_SLIMIT "%03o", uch & 0xff);
7433468e90cSJohn Marino } else {
7443468e90cSJohn Marino switch (uch) {
7453468e90cSJohn Marino case ' ':
746*32bb5217SDaniel Fojt _nc_STRCPY(target, "s", limit);
7473468e90cSJohn Marino break;
7483468e90cSJohn Marino case MARKER:
7493468e90cSJohn Marino *target++ = MARKER;
7503468e90cSJohn Marino *target = '\0';
7513468e90cSJohn Marino break;
7523468e90cSJohn Marino default:
753*32bb5217SDaniel Fojt --target;
754*32bb5217SDaniel Fojt _nc_SPRINTF(target, CUR_SLIMIT "%c", uch);
7553468e90cSJohn Marino break;
7563468e90cSJohn Marino }
7573468e90cSJohn Marino }
7583468e90cSJohn Marino target += strlen(target);
7593468e90cSJohn Marino }
7603468e90cSJohn Marino #else
7613468e90cSJohn Marino chtype ch = CharOfD(source);
7623468e90cSJohn Marino
7633468e90cSJohn Marino *target = '\0';
7643468e90cSJohn Marino if (AttrOfD(previous) != AttrOfD(source)) {
765*32bb5217SDaniel Fojt encode_attr(target, CUR_SLIMIT
766*32bb5217SDaniel Fojt AttrOfD(source),
767*32bb5217SDaniel Fojt AttrOfD(previous),
768*32bb5217SDaniel Fojt GetPair(source),
769*32bb5217SDaniel Fojt GetPair(previous));
7703468e90cSJohn Marino }
7713468e90cSJohn Marino target += strlen(target);
7723468e90cSJohn Marino *target++ = MARKER;
7733468e90cSJohn Marino if (ch < 32 || ch >= 127) {
774*32bb5217SDaniel Fojt _nc_SPRINTF(target, CUR_SLIMIT "%03o", UChar(ch));
7753468e90cSJohn Marino } else {
7763468e90cSJohn Marino switch (ch) {
7773468e90cSJohn Marino case ' ':
778*32bb5217SDaniel Fojt _nc_STRCPY(target, "s", limit);
7793468e90cSJohn Marino break;
7803468e90cSJohn Marino case MARKER:
7813468e90cSJohn Marino *target++ = MARKER;
7823468e90cSJohn Marino *target = '\0';
7833468e90cSJohn Marino break;
7843468e90cSJohn Marino default:
785*32bb5217SDaniel Fojt --target;
786*32bb5217SDaniel Fojt _nc_SPRINTF(target, CUR_SLIMIT "%c", UChar(ch));
7873468e90cSJohn Marino break;
7883468e90cSJohn Marino }
7893468e90cSJohn Marino }
7903468e90cSJohn Marino #endif
7913468e90cSJohn Marino }
7923468e90cSJohn Marino #endif
7933468e90cSJohn Marino
794fdd4e1e0SJan Lentfer NCURSES_EXPORT(int)
putwin(WINDOW * win,FILE * filep)795fdd4e1e0SJan Lentfer putwin(WINDOW *win, FILE *filep)
796fdd4e1e0SJan Lentfer {
797fdd4e1e0SJan Lentfer int code = ERR;
798fdd4e1e0SJan Lentfer
79900d8f3c4SJohn Marino T((T_CALLED("putwin(%p,%p)"), (void *) win, (void *) filep));
800fdd4e1e0SJan Lentfer
8013468e90cSJohn Marino #if NCURSES_EXT_PUTWIN
8023468e90cSJohn Marino if (win != 0) {
8033468e90cSJohn Marino const char *version = curses_version();
8043468e90cSJohn Marino char buffer[1024];
8053468e90cSJohn Marino NCURSES_CH_T last_cell;
806*32bb5217SDaniel Fojt int y;
8073468e90cSJohn Marino
8083468e90cSJohn Marino memset(&last_cell, 0, sizeof(last_cell));
8093468e90cSJohn Marino
8103468e90cSJohn Marino clearerr(filep);
8113468e90cSJohn Marino
8123468e90cSJohn Marino /*
8133468e90cSJohn Marino * Our magic number is technically nonprinting, but aside from that,
8143468e90cSJohn Marino * all of the file is printable ASCII.
8153468e90cSJohn Marino */
8163468e90cSJohn Marino #define PUTS(s) if (fputs(s, filep) == EOF || ferror(filep)) returnCode(code)
8173468e90cSJohn Marino PUTS(my_magic);
8183468e90cSJohn Marino PUTS(version);
8193468e90cSJohn Marino PUTS("\n");
8203468e90cSJohn Marino for (y = 0; y < (int) SIZEOF(scr_params); ++y) {
8213468e90cSJohn Marino const char *name = scr_params[y].name;
8223468e90cSJohn Marino const char *data = (char *) win + scr_params[y].offset;
8233468e90cSJohn Marino const void *dp = (const void *) data;
824*32bb5217SDaniel Fojt attr_t attr;
8253468e90cSJohn Marino
8263468e90cSJohn Marino *buffer = '\0';
827*32bb5217SDaniel Fojt if (!strncmp(name, "_pad.", (size_t) 5) && !(win->_flags & _ISPAD)) {
8283468e90cSJohn Marino continue;
8293468e90cSJohn Marino }
8303468e90cSJohn Marino switch (scr_params[y].type) {
8313468e90cSJohn Marino case pATTR:
832*32bb5217SDaniel Fojt attr = (*(const attr_t *) dp) & ~A_CHARTEXT;
833*32bb5217SDaniel Fojt encode_attr(buffer, TOP_SLIMIT
834*32bb5217SDaniel Fojt (*(const attr_t *) dp) & ~A_CHARTEXT,
835*32bb5217SDaniel Fojt A_NORMAL,
836*32bb5217SDaniel Fojt COLOR_PAIR((int) attr),
837*32bb5217SDaniel Fojt 0);
8383468e90cSJohn Marino break;
8393468e90cSJohn Marino case pBOOL:
8403468e90cSJohn Marino if (!(*(const bool *) data)) {
8413468e90cSJohn Marino continue;
8423468e90cSJohn Marino }
843*32bb5217SDaniel Fojt _nc_STRCPY(buffer, name, sizeof(buffer));
8443468e90cSJohn Marino name = "flag";
8453468e90cSJohn Marino break;
8463468e90cSJohn Marino case pCHAR:
847*32bb5217SDaniel Fojt attr = (*(const attr_t *) dp);
848*32bb5217SDaniel Fojt encode_attr(buffer, TOP_SLIMIT
849*32bb5217SDaniel Fojt * (const attr_t *) dp,
850*32bb5217SDaniel Fojt A_NORMAL,
851*32bb5217SDaniel Fojt COLOR_PAIR((int) attr),
852*32bb5217SDaniel Fojt 0);
8533468e90cSJohn Marino break;
8543468e90cSJohn Marino case pINT:
8553468e90cSJohn Marino if (!(*(const int *) dp))
8563468e90cSJohn Marino continue;
857*32bb5217SDaniel Fojt _nc_SPRINTF(buffer, TOP_SLIMIT
858*32bb5217SDaniel Fojt "%d", *(const int *) dp);
8593468e90cSJohn Marino break;
8603468e90cSJohn Marino case pSHORT:
8613468e90cSJohn Marino if (!(*(const short *) dp))
8623468e90cSJohn Marino continue;
863*32bb5217SDaniel Fojt _nc_SPRINTF(buffer, TOP_SLIMIT
864*32bb5217SDaniel Fojt "%d", *(const short *) dp);
8653468e90cSJohn Marino break;
8663468e90cSJohn Marino case pSIZE:
8673468e90cSJohn Marino if (!(*(const NCURSES_SIZE_T *) dp))
8683468e90cSJohn Marino continue;
869*32bb5217SDaniel Fojt _nc_SPRINTF(buffer, TOP_SLIMIT
870*32bb5217SDaniel Fojt "%d", *(const NCURSES_SIZE_T *) dp);
8713468e90cSJohn Marino break;
8723468e90cSJohn Marino #if NCURSES_WIDECHAR
8733468e90cSJohn Marino case pCCHAR:
874*32bb5217SDaniel Fojt encode_cell(buffer, TOP_SLIMIT
875*32bb5217SDaniel Fojt (CARG_CH_T) dp, CHREF(last_cell));
8763468e90cSJohn Marino break;
8773468e90cSJohn Marino #endif
8783468e90cSJohn Marino }
8793468e90cSJohn Marino /*
8803468e90cSJohn Marino * Only write non-default data.
8813468e90cSJohn Marino */
8823468e90cSJohn Marino if (*buffer != '\0') {
8833468e90cSJohn Marino if (fprintf(filep, "%s=%s\n", name, buffer) <= 0
8843468e90cSJohn Marino || ferror(filep))
8853468e90cSJohn Marino returnCode(code);
8863468e90cSJohn Marino }
8873468e90cSJohn Marino }
8883468e90cSJohn Marino /* Write row-data */
8893468e90cSJohn Marino fprintf(filep, "rows:\n");
8903468e90cSJohn Marino for (y = 0; y <= win->_maxy; y++) {
8913468e90cSJohn Marino NCURSES_CH_T *data = win->_line[y].text;
8923468e90cSJohn Marino int x;
8933468e90cSJohn Marino if (fprintf(filep, "%d:", y + 1) <= 0
8943468e90cSJohn Marino || ferror(filep))
8953468e90cSJohn Marino returnCode(code);
8963468e90cSJohn Marino for (x = 0; x <= win->_maxx; x++) {
8973468e90cSJohn Marino #if NCURSES_WIDECHAR
898*32bb5217SDaniel Fojt int len = _nc_wacs_width(data[x].chars[0]);
899*32bb5217SDaniel Fojt encode_cell(buffer, TOP_SLIMIT CHREF(data[x]), CHREF(last_cell));
9003468e90cSJohn Marino last_cell = data[x];
9013468e90cSJohn Marino PUTS(buffer);
9023468e90cSJohn Marino if (len > 1)
9033468e90cSJohn Marino x += (len - 1);
9043468e90cSJohn Marino #else
905*32bb5217SDaniel Fojt encode_cell(buffer, TOP_SLIMIT CHREF(data[x]), CHREF(last_cell));
9063468e90cSJohn Marino last_cell = data[x];
9073468e90cSJohn Marino PUTS(buffer);
9083468e90cSJohn Marino #endif
9093468e90cSJohn Marino }
9103468e90cSJohn Marino PUTS("\n");
9113468e90cSJohn Marino }
912*32bb5217SDaniel Fojt code = OK;
9133468e90cSJohn Marino }
9143468e90cSJohn Marino #else
9153468e90cSJohn Marino /*
9163468e90cSJohn Marino * This is the original putwin():
9173468e90cSJohn Marino * A straight binary dump is simple, but its format can depend on whether
9183468e90cSJohn Marino * ncurses is compiled with wide-character support, and also may depend
9193468e90cSJohn Marino * on the version of ncurses, e.g., if the WINDOW structure is extended.
9203468e90cSJohn Marino */
921fdd4e1e0SJan Lentfer if (win != 0) {
9221d102085SJan Lentfer size_t len = (size_t) (win->_maxx + 1);
923*32bb5217SDaniel Fojt int y;
924fdd4e1e0SJan Lentfer
925fdd4e1e0SJan Lentfer clearerr(filep);
9263468e90cSJohn Marino if (fwrite(win, sizeof(WINDOW), (size_t) 1, filep) != 1
927fdd4e1e0SJan Lentfer || ferror(filep))
928fdd4e1e0SJan Lentfer returnCode(code);
929fdd4e1e0SJan Lentfer
9303468e90cSJohn Marino for (y = 0; y <= win->_maxy; y++) {
9313468e90cSJohn Marino if (fwrite(win->_line[y].text,
932fdd4e1e0SJan Lentfer sizeof(NCURSES_CH_T), len, filep) != len
933fdd4e1e0SJan Lentfer || ferror(filep)) {
934fdd4e1e0SJan Lentfer returnCode(code);
935fdd4e1e0SJan Lentfer }
936fdd4e1e0SJan Lentfer }
937fdd4e1e0SJan Lentfer code = OK;
938fdd4e1e0SJan Lentfer }
9393468e90cSJohn Marino #endif
940fdd4e1e0SJan Lentfer returnCode(code);
941fdd4e1e0SJan Lentfer }
942fdd4e1e0SJan Lentfer
943fdd4e1e0SJan Lentfer NCURSES_EXPORT(int)
NCURSES_SP_NAME(scr_restore)94400d8f3c4SJohn Marino NCURSES_SP_NAME(scr_restore) (NCURSES_SP_DCLx const char *file)
945fdd4e1e0SJan Lentfer {
946fdd4e1e0SJan Lentfer FILE *fp = 0;
9473468e90cSJohn Marino int code = ERR;
948fdd4e1e0SJan Lentfer
94900d8f3c4SJohn Marino T((T_CALLED("scr_restore(%p,%s)"), (void *) SP_PARM, _nc_visbuf(file)));
950fdd4e1e0SJan Lentfer
9513468e90cSJohn Marino if (_nc_access(file, R_OK) >= 0
952*32bb5217SDaniel Fojt && (fp = fopen(file, BIN_R)) != 0) {
95300d8f3c4SJohn Marino delwin(NewScreen(SP_PARM));
95400d8f3c4SJohn Marino NewScreen(SP_PARM) = getwin(fp);
9551d102085SJan Lentfer #if !USE_REENTRANT
95600d8f3c4SJohn Marino newscr = NewScreen(SP_PARM);
9571d102085SJan Lentfer #endif
958fdd4e1e0SJan Lentfer (void) fclose(fp);
9593468e90cSJohn Marino if (NewScreen(SP_PARM) != 0) {
9603468e90cSJohn Marino code = OK;
961fdd4e1e0SJan Lentfer }
962fdd4e1e0SJan Lentfer }
9633468e90cSJohn Marino returnCode(code);
9643468e90cSJohn Marino }
965fdd4e1e0SJan Lentfer
96600d8f3c4SJohn Marino #if NCURSES_SP_FUNCS
96700d8f3c4SJohn Marino NCURSES_EXPORT(int)
scr_restore(const char * file)96800d8f3c4SJohn Marino scr_restore(const char *file)
96900d8f3c4SJohn Marino {
97000d8f3c4SJohn Marino return NCURSES_SP_NAME(scr_restore) (CURRENT_SCREEN, file);
97100d8f3c4SJohn Marino }
97200d8f3c4SJohn Marino #endif
97300d8f3c4SJohn Marino
974fdd4e1e0SJan Lentfer NCURSES_EXPORT(int)
scr_dump(const char * file)975fdd4e1e0SJan Lentfer scr_dump(const char *file)
976fdd4e1e0SJan Lentfer {
9773468e90cSJohn Marino int result;
978fdd4e1e0SJan Lentfer FILE *fp = 0;
979fdd4e1e0SJan Lentfer
980fdd4e1e0SJan Lentfer T((T_CALLED("scr_dump(%s)"), _nc_visbuf(file)));
981fdd4e1e0SJan Lentfer
982fdd4e1e0SJan Lentfer if (_nc_access(file, W_OK) < 0
983*32bb5217SDaniel Fojt || (fp = fopen(file, BIN_W)) == 0) {
9843468e90cSJohn Marino result = ERR;
985fdd4e1e0SJan Lentfer } else {
986fdd4e1e0SJan Lentfer (void) putwin(newscr, fp);
987fdd4e1e0SJan Lentfer (void) fclose(fp);
9883468e90cSJohn Marino result = OK;
989fdd4e1e0SJan Lentfer }
9903468e90cSJohn Marino returnCode(result);
991fdd4e1e0SJan Lentfer }
992fdd4e1e0SJan Lentfer
993fdd4e1e0SJan Lentfer NCURSES_EXPORT(int)
NCURSES_SP_NAME(scr_init)99400d8f3c4SJohn Marino NCURSES_SP_NAME(scr_init) (NCURSES_SP_DCLx const char *file)
995fdd4e1e0SJan Lentfer {
99600d8f3c4SJohn Marino int code = ERR;
997fdd4e1e0SJan Lentfer
99800d8f3c4SJohn Marino T((T_CALLED("scr_init(%p,%s)"), (void *) SP_PARM, _nc_visbuf(file)));
999fdd4e1e0SJan Lentfer
100000d8f3c4SJohn Marino if (SP_PARM != 0 &&
100100d8f3c4SJohn Marino #ifdef USE_TERM_DRIVER
100200d8f3c4SJohn Marino InfoOf(SP_PARM).caninit
100300d8f3c4SJohn Marino #else
100400d8f3c4SJohn Marino !(exit_ca_mode && non_rev_rmcup)
100500d8f3c4SJohn Marino #endif
100600d8f3c4SJohn Marino ) {
1007*32bb5217SDaniel Fojt FILE *fp = 0;
1008*32bb5217SDaniel Fojt
100900d8f3c4SJohn Marino if (_nc_access(file, R_OK) >= 0
1010*32bb5217SDaniel Fojt && (fp = fopen(file, BIN_R)) != 0) {
101100d8f3c4SJohn Marino delwin(CurScreen(SP_PARM));
101200d8f3c4SJohn Marino CurScreen(SP_PARM) = getwin(fp);
10131d102085SJan Lentfer #if !USE_REENTRANT
101400d8f3c4SJohn Marino curscr = CurScreen(SP_PARM);
10151d102085SJan Lentfer #endif
1016fdd4e1e0SJan Lentfer (void) fclose(fp);
10173468e90cSJohn Marino if (CurScreen(SP_PARM) != 0) {
101800d8f3c4SJohn Marino code = OK;
101900d8f3c4SJohn Marino }
102000d8f3c4SJohn Marino }
10213468e90cSJohn Marino }
102200d8f3c4SJohn Marino returnCode(code);
102300d8f3c4SJohn Marino }
102400d8f3c4SJohn Marino
102500d8f3c4SJohn Marino #if NCURSES_SP_FUNCS
102600d8f3c4SJohn Marino NCURSES_EXPORT(int)
scr_init(const char * file)102700d8f3c4SJohn Marino scr_init(const char *file)
102800d8f3c4SJohn Marino {
102900d8f3c4SJohn Marino return NCURSES_SP_NAME(scr_init) (CURRENT_SCREEN, file);
103000d8f3c4SJohn Marino }
103100d8f3c4SJohn Marino #endif
103200d8f3c4SJohn Marino
103300d8f3c4SJohn Marino NCURSES_EXPORT(int)
NCURSES_SP_NAME(scr_set)103400d8f3c4SJohn Marino NCURSES_SP_NAME(scr_set) (NCURSES_SP_DCLx const char *file)
103500d8f3c4SJohn Marino {
10363468e90cSJohn Marino int code = ERR;
10373468e90cSJohn Marino
103800d8f3c4SJohn Marino T((T_CALLED("scr_set(%p,%s)"), (void *) SP_PARM, _nc_visbuf(file)));
103900d8f3c4SJohn Marino
10403468e90cSJohn Marino if (NCURSES_SP_NAME(scr_init) (NCURSES_SP_ARGx file) == OK) {
104100d8f3c4SJohn Marino delwin(NewScreen(SP_PARM));
104200d8f3c4SJohn Marino NewScreen(SP_PARM) = dupwin(curscr);
104300d8f3c4SJohn Marino #if !USE_REENTRANT
104400d8f3c4SJohn Marino newscr = NewScreen(SP_PARM);
104500d8f3c4SJohn Marino #endif
10463468e90cSJohn Marino if (NewScreen(SP_PARM) != 0) {
10473468e90cSJohn Marino code = OK;
1048fdd4e1e0SJan Lentfer }
1049fdd4e1e0SJan Lentfer }
10503468e90cSJohn Marino returnCode(code);
10513468e90cSJohn Marino }
1052fdd4e1e0SJan Lentfer
105300d8f3c4SJohn Marino #if NCURSES_SP_FUNCS
1054fdd4e1e0SJan Lentfer NCURSES_EXPORT(int)
scr_set(const char * file)1055fdd4e1e0SJan Lentfer scr_set(const char *file)
1056fdd4e1e0SJan Lentfer {
105700d8f3c4SJohn Marino return NCURSES_SP_NAME(scr_set) (CURRENT_SCREEN, file);
105800d8f3c4SJohn Marino }
10591d102085SJan Lentfer #endif
1060