1 /* Copyright (C) 1989, 1992, 1993 Aladdin Enterprises. All rights reserved. 2 3 This file is part of AFPL Ghostscript. 4 5 AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or 6 distributor accepts any responsibility for the consequences of using it, or 7 for whether it serves any particular purpose or works at all, unless he or 8 she says so in writing. Refer to the Aladdin Free Public License (the 9 "License") for full details. 10 11 Every copy of AFPL Ghostscript must include a copy of the License, normally 12 in a plain ASCII text file named PUBLIC. The License grants you the right 13 to copy, modify and redistribute AFPL Ghostscript, but only under certain 14 conditions described in the License. Among other things, the License 15 requires that the copyright notice and this notice be preserved on all 16 copies. 17 */ 18 19 /*$Id: gdevsco.c,v 1.3 2000/09/19 19:00:22 lpd Exp $ */ 20 /* 17Jul91 - wb - based on gdevpcfb.c */ 21 /* 31Jul91 - Rick Calder rick@rick.att.com - ifdefs for AT&T UNIX 4.0 2.1 */ 22 /* 13Sep91 - wb - modify for gs24b2 */ 23 /* 9Mar92 - wb - modify for gs24b4 */ 24 /* generate SCO Xenix/Unix style memory mapped ioctl output */ 25 #include "memory_.h" 26 #include "gx.h" 27 #include "gserrors.h" 28 #include "gxdevice.h" 29 #include "gdevpcfb.h" 30 #include <signal.h> 31 32 #ifdef M_XENIX 33 #include <sys/console.h> /* SCO Xenix and SCO UNIX */ 34 #ifndef CONSIO 35 #include <sys/machdep.h> /* Xenix needs this also */ 36 #endif 37 #else 38 #include <sys/kd.h> /* AT&T SVR4 */ 39 #endif 40 41 #if defined(__STDC__) 42 #include <stdlib.h> 43 #else 44 extern char *getenv(P1(const char *)); 45 #endif 46 47 #if defined(M_XENIX) 48 #include <prototypes.h> 49 #include <fcntl.h> 50 #else 51 extern int ioctl(P3(int, int,...)); 52 extern int open(P3(const char *, int,...)); 53 #endif 54 55 private int console_fd = -1; /* file descriptor of console */ 56 fb_ptr fb_addr; /* address of frame buffer for unix */ 57 private int cur_mode = -1; /* current video mode */ 58 59 /* open the console */ 60 /* possible files to open: 61 * /dev/console = current system console 62 * /dev/vga = vga monitor 63 * /dev/tty = current terminal 64 */ 65 66 private void open_console(P1(void)); 67 68 private void 69 open_console() 70 { 71 const char *dev; 72 73 if (console_fd != -1) 74 return; 75 dev = getenv("GSDEVICE"); 76 if (dev == NULL || *dev == '\0') 77 dev = "/dev/tty"; 78 console_fd = open(dev, 0); 79 if (console_fd == -1) { 80 ega_close((gx_device *) NULL); 81 eprintf1("unable to map display '%s'\n", dev); 82 perror("open_console"); 83 exit(1); 84 } 85 } 86 87 #if defined(__GNUC__) 88 /* Done with inline assembly in gdevpcfb.h */ 89 #else 90 /* Output to a port */ 91 void 92 outportb(uint port, byte data) 93 { 94 int i; 95 struct port_io_arg pio; 96 97 if (console_fd == -1) 98 open_console(); 99 pio.args[0].dir = OUT_ON_PORT; 100 pio.args[0].port = port; 101 pio.args[0].data = data; 102 pio.args[1].port = 0; 103 pio.args[2].port = 0; 104 pio.args[3].port = 0; 105 i = ioctl(console_fd, CONSIO, (long)(&pio)); 106 if (i == -1) { 107 ega_close((gx_device *) NULL); 108 eprintf("error setting device register\n"); 109 perror("outportb"); 110 exit(1); 111 } 112 } 113 114 /* Output to 2 consecutive ports */ 115 void 116 outport2(uint port, byte index, byte data) 117 { 118 int i; 119 struct port_io_arg pio; 120 121 if (console_fd == -1) 122 open_console(); 123 pio.args[0].dir = OUT_ON_PORT; 124 pio.args[0].port = port; 125 pio.args[0].data = index; 126 pio.args[1].dir = OUT_ON_PORT; 127 pio.args[1].port = port + 1; 128 pio.args[1].data = data; 129 pio.args[2].port = 0; 130 pio.args[3].port = 0; 131 i = ioctl(console_fd, CONSIO, (long)(&pio)); 132 if (i == -1) { 133 ega_close((gx_device *) NULL); 134 eprintf("error setting device register\n"); 135 perror("outport2"); 136 exit(1); 137 } 138 } 139 #endif 140 141 /* interrupt signal handler */ 142 /* restore the video mode and exit */ 143 private void 144 ega_int_handler(int sig) 145 { 146 ega_close((gx_device *) NULL); 147 eprintf("GS exiting...\n"); 148 exit(1); 149 } 150 151 /* 152 * FIXME to make this work, the SIGCONT handler must restore the 153 * the video state, including all the registers. 154 * For now, I made the SIGSTOP handler exit just call the SIGINT handler 155 */ 156 157 #ifdef SIGTSTP 158 /* user tried to stop us. restore video and stop */ 159 private void 160 ega_tstp_handler(int sig) 161 { 162 #if 1 163 ega_int_handler(sig); 164 #else 165 /* Preferable, but sco does not restore the monitor corretly */ 166 signal(SIGTSTP, ega_tstp_handler); 167 ega_close((gx_device *) NULL); 168 eprintf("GS stopping...\n"); 169 signal(SIGSTOP, SIG_DFL); 170 kill(getpid(), SIGSTOP); 171 #endif 172 } 173 #endif /* SIGTSTP */ 174 175 #ifdef SIGCONT 176 /* we were unstopped. reopen video */ 177 private void 178 ega_cont_handler(int sig) 179 { 180 #if 1 181 ega_int_handler(sig); 182 #else 183 signal(SIGCONT, ega_cont_handler); 184 ega_set_mode(cur_mode); 185 #endif 186 } 187 #endif /* SIGCONT */ 188 189 /* ------ Internal routines ------ */ 190 191 /* Catch signals so we can restore the video mode on exit. */ 192 void 193 pcfb_set_signals(gx_device * dev) 194 { 195 signal(SIGINT, ega_int_handler); 196 signal(SIGTERM, ega_int_handler); 197 #ifdef SIGTSTP 198 signal(SIGTSTP, ega_tstp_handler); 199 #endif 200 #ifdef SIGCONT 201 signal(SIGCONT, ega_cont_handler); 202 #endif 203 } 204 205 /* Read the device mode */ 206 void 207 pcfb_get_state(pcfb_bios_state * pbs) 208 { 209 int mode; 210 211 open_console(); 212 mode = ioctl(console_fd, CONS_CURRENT, 0L); 213 if (mode == -1) { 214 #ifdef __linux__ 215 mode = M_ENH_C80x25; 216 #else 217 ega_close((gx_device *) NULL); 218 eprintf("unable to get current console mode\n"); 219 perror("pcfb_get_state"); 220 exit(1); 221 #endif 222 } 223 pbs->display_mode = 224 (mode == M_ENH_CG640 || mode == M_CG640x350 ? 0x10 : 225 #ifdef M_VGA12 226 mode == M_VGA12 ? 0x12 : 227 #endif 228 0x03); 229 } 230 231 /* Set the device mode */ 232 void 233 pcfb_set_mode(int mode) 234 { 235 int i, mode1; 236 237 open_console(); 238 cur_mode = mode; 239 mode1 = -1; 240 if (mode == 0x10) 241 mode = SW_ENH_CG640; 242 #ifdef SW_VGA12 243 else if (mode == 0x12) 244 mode = SW_VGA12; 245 #endif 246 else if (mode == 0x03) { 247 #ifdef SW_VGA80x25 248 mode = SW_VGA80x25; 249 mode1 = SW_ENHC80x25; 250 #else 251 mode = SW_ENHC80x25; 252 #endif 253 } else { 254 eprintf1("can not set to video mode %d\n", mode); 255 exit(1); 256 } 257 i = ioctl(console_fd, mode, 0L); 258 if (i == -1 && mode1 != -1) 259 i = ioctl(console_fd, mode1, 0L); 260 if (i == -1) { 261 ega_close((gx_device *) NULL); 262 eprintf("unable to set console mode\n"); 263 perror("pcfb_set_mode"); 264 exit(1); 265 } 266 #ifdef VGA_IOPRIVL 267 if (ioctl(console_fd, VGA_IOPRIVL, 1) == -1) { 268 ega_close((gx_device *) NULL); 269 eprintf("unable to get I/O privilege\n"); 270 perror("pcfb_set_mode"); 271 exit(1); 272 } 273 #endif 274 i = ioctl(console_fd, MAPCONS, 0L); 275 if (i == -1) { 276 ega_close((gx_device *) NULL); 277 eprintf("unable to map console adaptor's display memory\n"); 278 perror("pcfb_set_mode"); 279 exit(1); 280 } 281 fb_addr = (fb_ptr) (i); 282 } 283 284 /* Restore the device state */ 285 void 286 pcfb_set_state(const pcfb_bios_state * pbs) 287 { 288 pcfb_set_mode(pbs->display_mode); 289 } 290