+#if NCURSES_EXT_PUTWIN
+ if (win != 0) {
+ const char *version = curses_version();
+ char buffer[1024];
+ NCURSES_CH_T last_cell;
+
+ memset(&last_cell, 0, sizeof(last_cell));
+
+ clearerr(filep);
+
+ /*
+ * Our magic number is technically nonprinting, but aside from that,
+ * all of the file is printable ASCII.
+ */
+#define PUTS(s) if (fputs(s, filep) == EOF || ferror(filep)) returnCode(code)
+ PUTS(my_magic);
+ PUTS(version);
+ PUTS("\n");
+ for (y = 0; y < (int) SIZEOF(scr_params); ++y) {
+ const char *name = scr_params[y].name;
+ const char *data = (char *) win + scr_params[y].offset;
+ const void *dp = (const void *) data;
+
+ *buffer = '\0';
+ if (!strncmp(name, "_pad.", 5) && !(win->_flags & _ISPAD)) {
+ continue;
+ }
+ switch (scr_params[y].type) {
+ case pATTR:
+ encode_attr(buffer, (*(const attr_t *) dp) & ~A_CHARTEXT, A_NORMAL);
+ break;
+ case pBOOL:
+ if (!(*(const bool *) data)) {
+ continue;
+ }
+ strcpy(buffer, name);
+ name = "flag";
+ break;
+ case pCHAR:
+ encode_attr(buffer, *(const attr_t *) dp, A_NORMAL);
+ break;
+ case pINT:
+ if (!(*(const int *) dp))
+ continue;
+ sprintf(buffer, "%d", *(const int *) dp);
+ break;
+ case pSHORT:
+ if (!(*(const short *) dp))
+ continue;
+ sprintf(buffer, "%d", *(const short *) dp);
+ break;
+ case pSIZE:
+ if (!(*(const NCURSES_SIZE_T *) dp))
+ continue;
+ sprintf(buffer, "%d", *(const NCURSES_SIZE_T *) dp);
+ break;
+#if NCURSES_WIDECHAR
+ case pCCHAR:
+ encode_cell(buffer, (CARG_CH_T) dp, CHREF(last_cell));
+ break;
+#endif
+ }
+ /*
+ * Only write non-default data.
+ */
+ if (*buffer != '\0') {
+ if (fprintf(filep, "%s=%s\n", name, buffer) <= 0
+ || ferror(filep))
+ returnCode(code);
+ }
+ }
+ /* Write row-data */
+ fprintf(filep, "rows:\n");
+ for (y = 0; y <= win->_maxy; y++) {
+ NCURSES_CH_T *data = win->_line[y].text;
+ int x;
+ if (fprintf(filep, "%d:", y + 1) <= 0
+ || ferror(filep))
+ returnCode(code);
+ for (x = 0; x <= win->_maxx; x++) {
+#if NCURSES_WIDECHAR
+ int len = wcwidth(data[x].chars[0]);
+ encode_cell(buffer, CHREF(data[x]), CHREF(last_cell));
+ last_cell = data[x];
+ PUTS(buffer);
+ if (len > 1)
+ x += (len - 1);
+#else
+ encode_cell(buffer, CHREF(data[x]), CHREF(last_cell));
+ last_cell = data[x];
+ PUTS(buffer);
+#endif
+ }
+ PUTS("\n");
+ }
+ }
+#else
+ /*
+ * This is the original putwin():
+ * A straight binary dump is simple, but its format can depend on whether
+ * ncurses is compiled with wide-character support, and also may depend
+ * on the version of ncurses, e.g., if the WINDOW structure is extended.
+ */
+ if (win != 0) {
+ size_t len = (size_t) (win->_maxx + 1);
+
+ clearerr(filep);
+ if (fwrite(win, sizeof(WINDOW), (size_t) 1, filep) != 1
+ || ferror(filep))
+ returnCode(code);
+
+ for (y = 0; y <= win->_maxy; y++) {
+ if (fwrite(win->_line[y].text,
+ sizeof(NCURSES_CH_T), len, filep) != len
+ || ferror(filep)) {
+ returnCode(code);
+ }