1 /* Copyleft John McCutchan 2000 */
2 /* Contributions by Maurizio Sartori */
3 
4 /*
5  * this file is distributed in the hope that it will be useful, but
6  * WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
7  * to anyone for the consequences of using it or for whether it serves any
8  * particular purpose or works at all, unless he says so in writing.  Refer
9  * to the GNU General Public License for full details.
10  *
11  * Everyone is granted permission to copy, modify and redistribute
12  * this file, but only under the conditions described in the GNU
13  * General Public License.  A copy of this license is supposed to have been
14  * given to you along with this file so you can know your rights and
15  * responsibilities.  It should be in a file named COPYLEFT.  Among other
16  * things, the copyright notice and this notice must be preserved on all
17  * copies.
18  * */
19 
20 
21 #include <stdio.h>
22 #include <ncurses.h>
23 
24 #include "internal.h"
25 #include "types.h"
26 #include "colours.h"
27 #include "global.h"
28 
29 #include "editor.h"
30 #include "save.h"
31 #include "ansi.h"
32 #include "term.h"
33 #include "interface.h"
34 #include "sauce.h"
35 
36 /* this is a wrapper function that handles saving a file */
save_file(canvas * page)37 void save_file(canvas *page) {
38 	char *fname = (char *)NULL;
39 	FILE *fd = (FILE *)NULL;
40 	int ftype = 0;
41 	int count = 0;
42 
43 	char sauce_author[20];
44 	char sauce_group[20];
45 	char sauce_title[35];
46 
47 	if(!page) return;
48 
49 	fname = file_select();
50 	draw_editor(page);
51 	refresh();
52 
53 	if(!fname) return;
54 
55 	for(count = 0; count < 35; count++)
56 		sauce_title[count] = options.sauce_title[count];
57 	for(count = 0; count < 20; count++)
58 		sauce_group[count] = options.sauce_group[count];
59 	for(count = 0; count < 20; count++)
60 		sauce_author[count] = options.sauce_author[count];
61 
62 	sauce_load(fname, sauce_author, sauce_group, sauce_title);
63 
64 	/* find out file type */
65 	ftype = savei_filetype();
66 
67 	if(!ftype) {
68 		fname = m_free(fname);
69 		return;
70 	}
71 
72 	fd = fopen(fname, "w");
73 	fname = m_free(fname);
74 
75 	if(!fd) return;
76 
77 	if(ftype == 1) {
78 		if(savei_clearscreen()) {
79 			save_cls(fd);
80 		}
81 		save_ansi(page, fd);
82 		if(savei_sauce(sauce_author, sauce_group, sauce_title)) {
83 			sauce_save(fd, sauce_author, sauce_group, sauce_title, ftype);
84 		}
85 	}
86 	if(ftype == 2) {
87 		save_ascii(page, fd);
88 		if(savei_sauce(sauce_author, sauce_group, sauce_title)) {
89 			sauce_save(fd, sauce_author, sauce_group, sauce_title, ftype);
90 		}
91 	} else if (ftype == 3) {
92 		save_c(page, fd);
93 	} else if (ftype == 4) {
94 		save_bin(page, fd);
95 	}
96 	fclose(fd);
97 	page->modified = 0;
98 }
99 
100 /* this function saves a CLEAR screen ansi code to a file */
save_cls(FILE * fd)101 int save_cls(FILE *fd) {
102 	if(!fd) return 1;
103 	fputc(ESCAPE_CODE, fd);
104 	fputc(SQUARE_BRACKET, fd);
105 	fputc('2', fd);
106 	fputc(ED, fd);
107 	return 0;
108 }
109 
110 #define SA_ADDCH \
111 			fputc((page->buffer[y][x] & 0xFF), fd); \
112 			if(x == 78) { \
113 				/* the \r is for dos compatability */ \
114 				fputc('\r', fd); \
115 				fputc('\n', fd); \
116 				fputc(ESCAPE_CODE, fd); \
117 				fputc(SQUARE_BRACKET, fd); \
118 				fputc(CUU, fd); \
119 				fputc(ESCAPE_CODE, fd); \
120 				fputc(SQUARE_BRACKET, fd); \
121 				fputc('7', fd); \
122 				fputc('9', fd); \
123 				fputc(CUF, fd); \
124 			} \
125 			lfg = fg; \
126 			lbg = bg; \
127 			lbold = bold; \
128 			lblink = blink;
129 
130 			/* this function saves a ansi */
save_ansi(canvas * page,FILE * fd)131 int save_ansi(canvas *page, FILE *fd) {
132 
133 	coordinate x = 0;
134 	coordinate y = 0;
135 
136 	colour fg = COLOUR_WHITE;
137 	colour lfg = COLOUR_WHITE;
138 	colour bg = COLOUR_BLACK;
139 	colour lbg = COLOUR_BLACK;
140 
141 	flag bold = FALSE;
142 	flag lbold = FALSE;
143 
144 	flag blink = FALSE;
145 	flag lblink = FALSE;
146 
147 	flag first = FALSE;
148 
149 	if(!page) return 1;
150 
151 	if(!fd) return 1;
152 
153 	fputc(ESCAPE_CODE, fd);
154 	fputc(SQUARE_BRACKET, fd);
155 	fputc('0', fd);
156 	fputc(SGR, fd);
157 
158 	for(y = 0; y <= HY(page); y++) {
159 		for(x = 0; x < 80; x++) {
160 			tear_attrib(page->buffer[y][x], &fg, &bg, &bold, &blink);
161 			if(lfg != fg || lbg != bg || lbold != bold || lblink != blink) {
162 				first = TRUE;
163 
164 				fputc(ESCAPE_CODE, fd);
165 				fputc(SQUARE_BRACKET, fd);
166 
167 				if(lbold != bold) {
168 					first = FALSE;
169 					fprintf(fd,"%d", bold);
170 					if(!bold) {
171 						if(fg != COLOUR_WHITE || bg != COLOUR_BLACK || blink) {
172 							if(blink) fprintf(fd, ";5");
173 							if(fg != COLOUR_WHITE) fprintf(fd, ";%d", fg + 30);
174 							if(bg != COLOUR_BLACK) fprintf(fd, ";%d", bg + 40);
175 							fputc(SGR, fd);
176 							SA_ADDCH
177 							continue;
178 						}
179 					}
180 				}
181 
182 				if(lblink != blink) {
183 					if(first) {
184 						first = FALSE;
185 						if(blink) fprintf(fd, "5");
186 						else fprintf(fd, "0");
187 					}
188 					else
189 						if(blink) fprintf(fd, ";5");
190 						else fprintf(fd, ";0");
191 
192 					if(!blink) {
193 						if(fg != COLOUR_WHITE || bg != COLOUR_BLACK || bold) {
194 							if(bold) fprintf(fd, ";1");
195 							if(fg != COLOUR_WHITE) fprintf(fd, ";%d", fg + 30);
196 							if(bg != COLOUR_BLACK) fprintf(fd, ";%d", bg + 40);
197 							fputc(SGR, fd);
198 							SA_ADDCH
199 							continue;
200 						}
201 					}
202 				}
203 
204 				if(fg != lfg) {
205 					if(first) {
206 						first = FALSE;
207 						fprintf(fd, "%d", fg + 30);
208 					} else fprintf(fd, ";%d", fg + 30);
209 				}
210 
211 				if(bg != lbg) {
212 					if(first) {
213 						first = FALSE;
214 						fprintf(fd, "%d", bg + 40);
215 					} else fprintf(fd, ";%d", bg + 40);
216 				}
217 				fputc(SGR, fd);
218 			}
219 			SA_ADDCH
220 		}
221 		fputc('\r', fd);
222 		fputc('\n', fd);
223 	}
224 	fputc(ESCAPE_CODE, fd);
225 	fputc(SQUARE_BRACKET, fd);
226 	fputc('0', fd);
227 	fputc(SGR, fd);
228 	fputc(26, fd);
229 	return 0;
230 }
231 
232 /* this function saves the file format as a C header */
233 
save_c(canvas * page,FILE * fd)234 int save_c(canvas *page, FILE *fd) {
235 	int y = 0;
236 	int x = 0;
237 
238 	if(!page) return 1;
239 
240 	if(!fd) return 1;
241 
242 	fprintf(fd, "chtype ansi[%d][%d] = {\n", HY(page)+1, 80);
243 	for(y = 0; y <= HY(page); y++) {
244 		fprintf(fd, "{ ");
245 
246 		for(x = 0; x < 80; x++)
247 			fprintf(fd, "%ld,", page->buffer[y][x]);
248 
249 		fprintf(fd, "},\n");
250 	}
251 	fprintf(fd, "};\n");
252 	return 0;
253 }
254 
255 /* this function saves the image as a ascii */
save_ascii(canvas * page,FILE * fd)256 int save_ascii(canvas *page, FILE *fd) {
257 	int y = 0;
258 	int x = 0;
259 
260 	if(!page) return 1;
261 
262 	if(!fd) return 1;
263 
264 	for(y = 0; y <= HY(page); y++) {
265 		for(x = 0; x < 79; x++)
266 			fputc((page->buffer[y][x] & 0xFF), fd);
267 		/* the \r is for dos compatability */
268 		fputc('\r', fd);
269 		fputc('\n', fd);
270 	}
271 	fputc('\r', fd);
272 	fputc('\n', fd);
273 	return 0;
274 }
275 
276 /* this function saves the image as a binary file */
277 /* this was written by  Maurizio Sartori, <masar@libero.it>
278  */
save_bin(canvas * page,FILE * fd)279 int save_bin(canvas *page, FILE *fd) {
280 	int y = 0;
281 	int x = 0;
282 	colour fg = 0;
283 	colour bg = 0;
284 	flag bold = 0;
285 	flag blink = 0;
286 
287 	if(!page||!fd) return 1;
288 
289 	for(y = 0; y <= HY(page); y++) {
290 		for(x = 0; x < 80; x++) {
291 			tear_attrib(page->buffer[y][x], &fg, &bg, &bold, &blink);
292 			fputc((page->buffer[y][x] & 0xFF), fd);
293 			fputc((fg & 0x0F) | ((bg & 0x0F) << 4) |
294                               (bold ? 0x08 : 0) | (blink ? 0x80 : 0), fd);
295 		}
296 	}
297 	return 0;
298 }
299