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