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