chiark / gitweb /
Import upstream version 5.3.
[mup] / mup / mupdisp / at386.c
1
2 /* Copyright (c) 1995, 1996, 1998, 2000 by Arkkra Enterprises */
3 /* All rights reserved */
4
5 /* functions to support displaying multipage bitmap
6  * (as from Ghostscript -sDEVICE=bit) to AT386 console.
7  */
8
9 #include "mupdisp.h"
10
11 #if defined(AT386) && ! defined(linux) && ! defined(__DOS__)
12
13 #include <sys/kd.h>
14 #include <termio.h>
15
16 #define BPL             (80)    /* bytes per line on screen, AT386 mode */
17
18 unsigned char *Video_memory;
19 int Orig_video_mode;            /* to put video back the way it was */
20 struct termio Orig_ttyinfo;     /* to put keyboard back from raw mode */
21
22 static void setup_keyboard P((void));
23 \f
24
25 /* set up for TERM=AT386. Put video and keyboard in proper mode */
26
27 void
28 at386_setup()
29
30 {
31         register int n;                 /* for setting signal catching */
32
33
34         /* get current video mode, so we can put it back when we're done */
35         if ((Orig_video_mode = ioctl(1, CONS_GET, 0)) < 0) {
36                 fprintf(stderr, "failed to determine current video mode\n");
37                 generalcleanup(1);
38         }
39
40         /* need to put keyboard into raw mode, save current state */
41         if (ioctl(0, TCGETA, &Orig_ttyinfo) < 0) {
42                 fprintf(stderr, "failed to get tty info\n");
43                 generalcleanup(1);
44         }
45
46         /* make sure we always clean up, so user isn't left stuck in raw and/or
47          * graphics mode. */
48         for (n = 1; n < NSIG; n++) {
49                 if ( n != SIGKILL && n != SIGCLD) {
50                         sigset(n, Conf_info_p->cleanup);
51                 }
52         }
53         sigset(SIGWINCH, SIG_IGN);
54
55         /* put keyboard into raw mode */
56         setup_keyboard();
57
58         /* put screen into graphics mode */
59         if (ioctl(1, SW_CG640x350, 0) < 0) {
60                 generalcleanup(1);
61         }
62
63         /* get access to video memory */
64         Video_memory = (unsigned char *) ioctl(1, MAPCONS, 0);
65 }
66 \f
67
68 /* draw stuff onto screen. Draw starting at specified line of page */
69
70 void
71 at386_draw(line, small)
72
73 int line;       /* draw starting from this raster line of page */
74 int small;      /* YES if should draw small view of full page */
75
76 {
77         register int i;
78         register int j;
79         unsigned char buff[MAX_BYTES_PER_LINE]; /* a row of bits to display */
80         int extra;              /* how many unused bits in rightmost byte */
81         int mask;               /* to clear out unused bits */
82         unsigned char *v;       /* pointer into video memory */
83         long offset;            /* into bitmap file */
84         int fd;                 /* file to read bitmap from */
85
86
87         /* make sure we have a valid page to draw */
88         if (Currpage_p == (struct Pginfo *) 0) {
89                 ( *(Conf_info_p->error) ) ("page # out of range");
90                 return;
91         }
92
93         /* figure out where in the bitmap file this page is */
94         offset = Currpage_p->seqnum * BYTES_PER_PAGE;
95         fd = gen1file(small);
96         lseek(fd, offset + line * BYTES_PER_LINE, SEEK_SET);
97
98         /* read from file and put into video memory, inverting to
99          * black on white */
100         for (i = 0; i < Conf_info_p->vlines; i++) {
101                 read(fd, buff, BYTES_PER_LINE);
102
103                 /* if the page width is not on a byte boundary, blank
104                  * out the partial byte at the edge */
105                 mask = 1;
106                 for (mask = 1, extra = BYTES_PER_LINE & 0x7;
107                                         extra > 0; mask <<= 1, extra--) {
108                         buff[BYTES_PER_LINE - 1] |= mask;
109                 }
110
111                 /* point to row in video memory and transfer bitmap row */
112                 v = Video_memory + i * BPL;
113                 for (j = 0; j < BYTES_PER_LINE; j++) {
114                         v[j] = buff[j] ^ 0xff;
115                 }
116         }
117 }
118 \f
119
120 /* AT386 cleanup function.
121  * Put screen back into previous mode. Some day maybe we should save the data
122  * on the original screen and put it back when we're done... */
123
124 void
125 at386_cleanup(status)
126
127 int status;
128
129 {
130         /* put video back to normal */
131         ioctl(1, MODESWITCH | Orig_video_mode, 0);
132
133         /* put keyboard back to normal */
134         ioctl(0, TCSETA, &Orig_ttyinfo);
135         
136         /* call the non-terminal-type specific cleanup */
137         generalcleanup(status);
138 }
139 \f
140
141 /* read from keyboard and call do_cmd for each key read.
142  * Commands are described in
143  * the comment at the beginning of do_cmd() */
144
145 void
146 at386_user_interf()
147
148 {
149         int c;                  /* char read from keyboard */
150         int special = 0;        /* 1 = got an escape, 2 = got escape followed
151                                  * by [, 0 = not doing any special processing.
152                                  * This is to handle special function keys. */
153
154         while ( (c = getchar() ) != EOF) {
155                 if (c == 0x1b) {
156                         /* got ESC, could be a special function key */
157                         special = 1;
158                         continue;
159                 }
160                 else if (special == 1 && c == '[') {
161                         /* got ESC-[ */
162                         special = 2;
163                         continue;
164                 }
165                 else if (special == 2) {
166                         /* map special functions to their equivalent commands */
167                         if (c == 'V') {
168                                 c = 'p';        /* Page Up key ==> previous */
169                         }
170                         else if (c == 'U') {
171                                 c = 'n';        /* Page Down key ==> next */
172                         }
173                         else if (c == 'A') {
174                                 c = 'b';        /* Up key ==> backwards */
175                         }
176                         else if (c == 'B') {
177                                 c = 'f';        /* Down key ==> forwards */
178                         }
179                 }
180                 special = 0;
181                 do_cmd(c);
182         }
183 }
184 \f
185
186 /* Error handler.
187  * For now just beep. Maybe eventually pop up an error message */
188
189 void
190 at386_error(msg)
191
192 char *msg;
193
194 {
195         ioctl(1, KDMKTONE, (150L << 16) | 3600L);
196 }
197 \f
198
199 /* overlay a raster centered on the window */
200
201 void
202 at386_raster(bitmap, width, height)
203
204 unsigned char *bitmap;  /* what to display */
205 int width, height;      /* of bitmap, width is in bytes */
206
207 {
208         int i, j;
209         int x, y;       /* upper left corner of where to put bitmap, x in bytes */
210
211
212         /* figure out how to center on screen */
213         x = (BYTES_PER_LINE - width) / 2;
214         y = (Conf_info_p->vlines - height) / 2;
215
216         /* copy bitmap to screen */
217         for (i = 0; i < height; i++) {
218                 for (j = 0; j < width; j++) {
219                         Video_memory[(y + i) * BPL + (x + j)] =
220                                 bitmap[ (i * width) + j];
221                 }
222         }
223 }
224 \f
225
226 /* put keyboard in raw mode */
227
228 static void
229 setup_keyboard()
230
231 {
232         struct termio ttyinfo;
233
234
235         if (isatty(0) != 1) {
236                 fprintf(stderr, "stdin is not a tty\n");
237                 generalcleanup(1);
238         }
239
240         if (ioctl(0, TCGETA, &ttyinfo) < 0) {
241                 fprintf(stderr, "failed to get tty info\n");
242                 generalcleanup(1);
243         }
244
245         /* turn off echo and canonical */
246         ttyinfo.c_lflag &= ~(ICANON | ECHO);
247         ttyinfo.c_cc[VMIN] = 1;
248         ttyinfo.c_cc[VTIME] = 3;
249         if (ioctl(0, TCSETA, &ttyinfo) < 0) {
250                 fprintf(stderr, "failed to set keyboard modes, errno %d\n", errno);
251                 generalcleanup(1);
252         }
253 }
254 \f
255
256 #else
257
258 /* some compilers complain about files that are effectively empty,
259  * so put in something even when entire file is effectively ifdef-ed out */
260 static short dummy;
261
262 #endif