chiark / gitweb /
Import upstream version 5.3.
[mup] / mup / mupdisp / dos.c
CommitLineData
69695f33
MW
1
2/* Copyright (c) 1995, 1998 by Arkkra Enterprises */
3/* All rights reserved */
4
5/* Functions for displaying Mup/Ghostscript output on screen using
6 * Watcom C */
7
8#ifdef __WATCOMC__
9#include "mupdisp.h"
10#include <graph.h>
11#include <stdlib.h>
12#include <malloc.h>
13#include <stdio.h>
14#include <conio.h>
15#include <fcntl.h>
16#include <io.h>
17
18/* hard code X and Y sizes for the moment */
19#define XSIZE 640
20#define YSIZE 480
21
22/* image to be calloc'ed has 6 header bytes, then each row consecutively */
23#define BITS2BYTES(bits) (((bits) + 7) / 8) /* round upwards */
24#define SIZEIMAGE (6 + ((long)BITS2BYTES(XSIZE)*4) * (long)YSIZE)
25static char *Image;
26
27static void zapblock P((char *area, long size));
28\f
29
30/* initialize graphics driver, etc */
31
32void
33dos_setup()
34
35{
36 struct videoconfig vidinfo;
37
38
39 /* initalize best graphics mode */
40 if (_setvideomode(_VRES16COLOR) == 0) {
41 fprintf(stderr, "can't set graphics mode\n");
42 generalcleanup(1);
43 }
44
45 _getvideoconfig(&vidinfo);
46
47 if (vidinfo.numxpixels != XSIZE || vidinfo.numypixels != YSIZE) {
48 _setvideomode(_DEFAULTMODE);
49 fprintf(stderr, "video mode %dx%d not supported\n",
50 vidinfo.numxpixels, vidinfo.numypixels);
51 generalcleanup(0);
52 }
53
54 /*
55 * Allocate the image buffer. Note that both parameters must be less
56 * than 65536, but the total size (product) can be greater. The +1
57 * is to allow room for the header bytes (and then some).
58 */
59 Image = (char *)calloc(BITS2BYTES(YSIZE)*4 + 1, XSIZE);
60 if (Image == NULL) {
61 _setvideomode(_DEFAULTMODE);
62 fprintf(stderr, "can't allocate image buffer\n");
63 generalcleanup(0);
64 }
65
66 /* set aspect ratio adjust */
67 Conf_info_p->adjust = 1.375 * (double) vidinfo.numypixels
68 / (double) vidinfo.numxpixels;
69 Conf_info_p->vlines = vidinfo.numypixels;
70
71 /* set screen to all white */
72 _setbkcolor(_BRIGHTWHITE);
73 _clearscreen(_GCLEARSCREEN);
74}
75\f
76
77/* before exiting, clean up graphics, then call the general cleanup routine */
78
79void
80dos_cleanup(int status)
81{
82 _setvideomode(_DEFAULTMODE);
83 generalcleanup(status);
84}
85\f
86
87/* draw a screen worth of the bitmap, starting at specified raster line */
88
89void
90dos_draw(line, small)
91
92int line; /* start at this raster line */
93int small; /* YES or NO for small or large page image */
94
95{
96 int r; /* row index */
97 long offset; /* into bitmap file */
98 int fd; /* file descriptor */
99 int himage_bytes; /* horizontal image bytes */
100 char *row_ptr; /* point at a row of the image */
101 int n; /* loop variable */
102
103
104 /* make sure we have a valid page to draw */
105 if (Currpage_p == (struct Pginfo *) 0) {
106 ( *(Conf_info_p->error) ) ("page # out of range");
107 return;
108 }
109
110 /* figure out where in the bitmap file this page is */
111 offset = Currpage_p->seqnum * BYTES_PER_PAGE;
112 fd = gen1file(small);
113 lseek(fd, offset + (long)line * BYTES_PER_LINE, SEEK_SET);
114
115 /* zero out the image buffer */
116 zapblock(Image, SIZEIMAGE);
117
118 /* number of bytes representing one horizontal row in full page image */
119 himage_bytes = BITS2BYTES(XSIZE) * 4;
120
121 /* set the header bytes in the image */
122 Image[0] = XSIZE % 256;
123 Image[1] = XSIZE / 256;
124 Image[2] = YSIZE % 256;
125 Image[3] = YSIZE / 256;
126 Image[4] = 4;
127 Image[5] = 0;
128
129 /* set screen to all white */
130 _setbkcolor(_BRIGHTWHITE);
131 _clearscreen(_GCLEARSCREEN);
132
133 /* for each row */
134 for (r = 0; r < Conf_info_p->vlines; r++) {
135 /* read it directly into the image */
136 row_ptr = &Image[ 6 + r * himage_bytes ];
137 if (read(fd, row_ptr, BYTES_PER_LINE) != BYTES_PER_LINE) {
138 break;
139 }
140
141 if (small) {
142 /* black out the unused strip on the right */
143 for (n = BITS_PER_LINE; n < XSIZE; n++)
144 row_ptr[n/8] |= 1 << (7 - n%8);
145 }
146 }
147 /* put at upper left corner, (0, 0) */
148 _putimage(0, 0, Image, _GPSET);
149}
150\f
151
152/* for now we just beep on errors */
153/*ARGSUSED*/
154void
155dos_error(msg)
156
157char *msg;
158
159{
160 putc('\7', stderr);
161}
162\f
163
164/* for user interface, call command processor for each character read */
165
166void
167dos_user_interf()
168
169{
170 int c;
171 int special = 0; /* 1 = got a null, which is first character
172 * of special key sequence */
173 for ( ; ; ) {
174 c = getch();
175 if (c == '\0') {
176 special = 1;
177 continue;
178 }
179 if (special == 1) {
180 switch (c) {
181 case 0x49:
182 /* PgUp key */
183 c = 'p';
184 break;
185 case 0x51:
186 /* PgDown key */
187 c = 'n';
188 break;
189 case 0x48:
190 /* Up arrow key */
191 c = 'b';
192 break;
193 case 0x50:
194 /* Down arrow key */
195 c = 'f';
196 break;
197 default:
198 special = 0;
199 continue;
200 }
201 }
202 do_cmd(c);
203 special = 0;
204 }
205}
206\f
207
208/* display a raster centered on window */
209
210void
211dos_raster(bitmap, width, height)
212
213unsigned char *bitmap; /* what to display */
214int width, height; /* of bitmap, width is in bytes */
215
216{
217 int r, c; /* row and column indices */
218 int b; /* index through bits */
219 int x, y; /* upper left corner of where to put bitmap,
220 * x in bytes */
221 int himage_bytes; /* bytes needed for one row in image */
222 int n; /* loop variable */
223 char *row_ptr; /* point at a row of the image */
224
225
226 himage_bytes = 4 * width;
227
228 /* figure out how to center on screen */
229 x = (BYTES_PER_LINE - width) / 2 * 8;
230 y = (Conf_info_p->vlines - height) / 2;
231
232 /* zero out the image buffer */
233 zapblock(Image, SIZEIMAGE);
234
235 /* set the header bytes in the image */
236 Image[0] = (width * 8) % 256;
237 Image[1] = (width * 8) / 256;
238 Image[2] = height % 256;
239 Image[3] = height / 256;
240 Image[4] = 4;
241 Image[5] = 0;
242
243 /* for each row */
244 for (r = 0; r < height; r++) {
245 row_ptr = &Image[ 6 + r * himage_bytes ];
246 for (c = 0; c < width; c++) {
247 for (b = 0; b < 8; b++) {
248 if (bitmap[r*width+c] & (1 << (7-b))) {
249 /* white (15); set 4 copies of bit */
250 for (n = 0; n < 4; n++)
251 row_ptr[n*width + c] |=
252 (1 << (7-b));
253 } else {
254 /* black (8); set only the first */
255 row_ptr[c] |= (1 << (7-b));
256 }
257 }
258 }
259 }
260
261 _putimage(x, y, Image, _GPSET);
262}
263\f
264/* zero out a block of memory that may be bigger than 32K */
265
266#define BLOCKSIZE 0x3fff
267
268static void
269zapblock(area, size)
270
271char *area;
272long size;
273
274{
275 long k;
276
277 /*
278 * memset's third parm is "unsigned int", so we can't do the whole
279 * area at once.
280 */
281 for (k = 0; k < size; k += BLOCKSIZE) {
282 if (size - k >= BLOCKSIZE)
283 (void)memset(&area[k], 0, BLOCKSIZE);
284 else
285 (void)memset(&area[k], 0, size - k);
286 }
287}
288
289#else
290
291/* some compilers don't like empty files, so if __WATCOMC__ isn't defined,
292 * put something here to keep those compilers happy */
293static short dummy;
294
295#endif