1 /* Public Domain Curses */
2 
3 #include <curspriv.h>
4 
5 /*man-start**************************************************************
6 
7 scr_dump
8 --------
9 
10 ### Synopsis
11 
12     int putwin(WINDOW *win, FILE *filep);
13     WINDOW *getwin(FILE *filep);
14     int scr_dump(const char *filename);
15     int scr_init(const char *filename);
16     int scr_restore(const char *filename);
17     int scr_set(const char *filename);
18 
19 ### Description
20 
21    getwin() reads window-related data previously stored in a file
22    by putwin(). It then creates and initialises a new window using
23    that data.
24 
25    putwin() writes all data associated with a window into a file,
26    using an unspecified format. This information can be retrieved
27    later using getwin().
28 
29    scr_dump() writes the current contents of the virtual screen to
30    the file named by filename in an unspecified format.
31 
32    scr_restore() function sets the virtual screen to the contents
33    of the file named by filename, which must have been written
34    using scr_dump(). The next refresh operation restores the screen
35    to the way it looked in the dump file.
36 
37    In PDCurses, scr_init() does nothing, and scr_set() is a synonym
38    for scr_restore(). Also, scr_dump() and scr_restore() save and
39    load from curscr. This differs from some other implementations,
40    where scr_init() works with curscr, and scr_restore() works with
41    newscr; but the effect should be the same. (PDCurses has no
42    newscr.)
43 
44 ### Return Value
45 
46    On successful completion, getwin() returns a pointer to the
47    window it created. Otherwise, it returns a null pointer. Other
48    functions return OK or ERR.
49 
50 ### Portability
51                              X/Open    BSD    SYS V
52     putwin                      Y
53     getwin                      Y
54     scr_dump                    Y
55     scr_init                    Y
56     scr_restore                 Y
57     scr_set                     Y
58 
59 **man-end****************************************************************/
60 
61 #include <stdlib.h>
62 #include <string.h>
63 
64 #define DUMPVER 1   /* Should be updated whenever the WINDOW struct is
65                        changed */
66 
putwin(WINDOW * win,FILE * filep)67 int putwin(WINDOW *win, FILE *filep)
68 {
69     static const char *marker = "PDC";
70     static const unsigned char version = DUMPVER;
71 
72     PDC_LOG(("putwin() - called\n"));
73 
74     /* write the marker and the WINDOW struct */
75 
76     if (filep && fwrite(marker, strlen(marker), 1, filep)
77               && fwrite(&version, 1, 1, filep)
78               && fwrite(win, sizeof(WINDOW), 1, filep))
79     {
80         int i;
81 
82         /* write each line */
83 
84         for (i = 0; i < win->_maxy && win->_y[i]; i++)
85             if (!fwrite(win->_y[i], win->_maxx * sizeof(chtype), 1, filep))
86                 return ERR;
87 
88         return OK;
89     }
90 
91     return ERR;
92 }
93 
getwin(FILE * filep)94 WINDOW *getwin(FILE *filep)
95 {
96     WINDOW *win;
97     char marker[4];
98     int i, nlines, ncols;
99 
100     PDC_LOG(("getwin() - called\n"));
101 
102     if ( !(win = malloc(sizeof(WINDOW))) )
103         return (WINDOW *)NULL;
104 
105     /* check for the marker, and load the WINDOW struct */
106 
107     if (!filep || !fread(marker, 4, 1, filep) || strncmp(marker, "PDC", 3)
108         || marker[3] != DUMPVER || !fread(win, sizeof(WINDOW), 1, filep))
109     {
110         free(win);
111         return (WINDOW *)NULL;
112     }
113 
114     nlines = win->_maxy;
115     ncols = win->_maxx;
116 
117     /* allocate the line pointer array */
118 
119     if ( !(win->_y = malloc(nlines * sizeof(chtype *))) )
120     {
121         free(win);
122         return (WINDOW *)NULL;
123     }
124 
125     /* allocate the minchng and maxchng arrays */
126 
127     if ( !(win->_firstch = malloc(nlines * sizeof(int))) )
128     {
129         free(win->_y);
130         free(win);
131         return (WINDOW *)NULL;
132     }
133 
134     if ( !(win->_lastch = malloc(nlines * sizeof(int))) )
135     {
136         free(win->_firstch);
137         free(win->_y);
138         free(win);
139         return (WINDOW *)NULL;
140     }
141 
142     /* allocate the lines */
143 
144     if ( !(win = PDC_makelines(win)) )
145         return (WINDOW *)NULL;
146 
147     /* read them */
148 
149     for (i = 0; i < nlines; i++)
150     {
151         if (!fread(win->_y[i], ncols * sizeof(chtype), 1, filep))
152         {
153             delwin(win);
154             return (WINDOW *)NULL;
155         }
156     }
157 
158     touchwin(win);
159 
160     return win;
161 }
162 
scr_dump(const char * filename)163 int scr_dump(const char *filename)
164 {
165     FILE *filep;
166 
167     PDC_LOG(("scr_dump() - called: filename %s\n", filename));
168 
169     if (filename && (filep = fopen(filename, "wb")) != NULL)
170     {
171         int result = putwin(curscr, filep);
172         fclose(filep);
173         return result;
174     }
175 
176     return ERR;
177 }
178 
scr_init(const char * filename)179 int scr_init(const char *filename)
180 {
181     PDC_LOG(("scr_init() - called: filename %s\n", filename));
182 
183     return OK;
184 }
185 
scr_restore(const char * filename)186 int scr_restore(const char *filename)
187 {
188     FILE *filep;
189 
190     PDC_LOG(("scr_restore() - called: filename %s\n", filename));
191 
192     if (filename && (filep = fopen(filename, "rb")) != NULL)
193     {
194         WINDOW *replacement = getwin(filep);
195         fclose(filep);
196 
197         if (replacement)
198         {
199             int result = overwrite(replacement, curscr);
200             delwin(replacement);
201             return result;
202         }
203     }
204 
205     return ERR;
206 }
207 
scr_set(const char * filename)208 int scr_set(const char *filename)
209 {
210     PDC_LOG(("scr_set() - called: filename %s\n", filename));
211 
212     return scr_restore(filename);
213 }
214