summaryrefslogtreecommitdiff
path: root/gs/src/gdevsco.c
diff options
context:
space:
mode:
Diffstat (limited to 'gs/src/gdevsco.c')
-rw-r--r--gs/src/gdevsco.c275
1 files changed, 275 insertions, 0 deletions
diff --git a/gs/src/gdevsco.c b/gs/src/gdevsco.c
new file mode 100644
index 000000000..c7e869b87
--- /dev/null
+++ b/gs/src/gdevsco.c
@@ -0,0 +1,275 @@
+/* Copyright (C) 1989, 1992, 1993 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+*/
+
+/* gdevsco.c - 17Jul91 - wb - based on gdevpcfb.c */
+/* 31Jul91 - Rick Calder rick@rick.att.com - ifdefs for AT&T UNIX 4.0 2.1 */
+/* 13Sep91 - wb - modify for gs24b2 */
+/* 9Mar92 - wb - modify for gs24b4 */
+/* generate SCO Xenix/Unix style memory mapped ioctl output */
+#include "memory_.h"
+#include "gx.h"
+#include "gserrors.h"
+#include "gxdevice.h"
+#include "gdevpcfb.h"
+#include <signal.h>
+
+#ifdef M_XENIX
+#include <sys/console.h> /* SCO Xenix and SCO UNIX */
+#ifndef CONSIO
+#include <sys/machdep.h> /* Xenix needs this also */
+#endif
+#else
+#include <sys/kd.h> /* AT&T SVR4 */
+#endif
+
+#if defined(__STDC__)
+#include "stdlib.h"
+#else
+extern char *getenv(P1(const char *));
+#endif
+
+#if defined(M_XENIX)
+#include "prototypes.h"
+#include "fcntl.h"
+#else
+extern int ioctl(P3(int, int, ...));
+extern int open(P3(const char *, int, ...));
+#endif
+
+private int console_fd = -1; /* file descriptor of console */
+fb_ptr fb_addr; /* address of frame buffer for unix */
+private int cur_mode = -1; /* current video mode */
+
+/* open the console */
+/* possible files to open:
+ * /dev/console = current system console
+ * /dev/vga = vga monitor
+ * /dev/tty = current terminal
+ */
+
+private void open_console(P1(void));
+
+private void
+open_console()
+{
+ const char *dev;
+ if (console_fd != -1) return;
+ dev = getenv("GSDEVICE");
+ if (dev == NULL || *dev == '\0')
+ dev = "/dev/tty";
+ console_fd = open(dev, 0);
+ if (console_fd == -1) {
+ ega_close((gx_device *)NULL);
+ eprintf1("unable to map display '%s'\n", dev);
+ perror("open_console");
+ exit(1);
+ }
+}
+
+#if defined(__GNUC__)
+ /* Done with inline assembly in gdevpcfb.h */
+#else
+/* Output to a port */
+void
+outportb(uint port, byte data)
+{
+ int i;
+ struct port_io_arg pio;
+
+ if (console_fd == -1) open_console();
+ pio.args[0].dir = OUT_ON_PORT;
+ pio.args[0].port = port;
+ pio.args[0].data = data;
+ pio.args[1].port = 0;
+ pio.args[2].port = 0;
+ pio.args[3].port = 0;
+ i = ioctl(console_fd, CONSIO, (long)(&pio));
+ if (i == -1) {
+ ega_close((gx_device *)NULL);
+ eprintf("error setting device register\n");
+ perror("outportb");
+ exit(1);
+ }
+}
+
+/* Output to 2 consecutive ports */
+void
+outport2(uint port, byte index, byte data)
+{
+ int i;
+ struct port_io_arg pio;
+
+ if (console_fd == -1) open_console();
+ pio.args[0].dir = OUT_ON_PORT;
+ pio.args[0].port = port;
+ pio.args[0].data = index;
+ pio.args[1].dir = OUT_ON_PORT;
+ pio.args[1].port = port + 1;
+ pio.args[1].data = data;
+ pio.args[2].port = 0;
+ pio.args[3].port = 0;
+ i = ioctl(console_fd, CONSIO, (long)(&pio));
+ if (i == -1) {
+ ega_close((gx_device *)NULL);
+ eprintf("error setting device register\n");
+ perror("outport2");
+ exit(1);
+ }
+}
+#endif
+
+/* interrupt signal handler */
+/* restore the video mode and exit */
+private void
+ega_int_handler(int sig)
+{
+ ega_close((gx_device *)NULL);
+ eprintf("GS exiting...\n");
+ exit(1);
+}
+
+/*
+ * FIXME to make this work, the SIGCONT handler must restore the
+ * the video state, including all the registers.
+ * For now, I made the SIGSTOP handler exit just call the SIGINT handler
+ */
+
+#ifdef SIGTSTP
+/* user tried to stop us. restore video and stop */
+private void
+ega_tstp_handler(int sig)
+{
+#if 1
+ ega_int_handler(sig);
+#else
+ /* Preferable, but sco does not restore the monitor corretly */
+ signal(SIGTSTP, ega_tstp_handler);
+ ega_close((gx_device *)NULL);
+ eprintf("GS stopping...\n");
+ signal(SIGSTOP,SIG_DFL);
+ kill(getpid(), SIGSTOP);
+#endif
+}
+#endif /* SIGTSTP */
+
+#ifdef SIGCONT
+/* we were unstopped. reopen video */
+private void
+ega_cont_handler(int sig)
+{
+#if 1
+ ega_int_handler(sig);
+#else
+ signal(SIGCONT, ega_cont_handler);
+ ega_set_mode(cur_mode);
+#endif
+}
+#endif /* SIGCONT */
+
+/* ------ Internal routines ------ */
+
+/* Catch signals so we can restore the video mode on exit. */
+void
+pcfb_set_signals(gx_device *dev)
+{ signal(SIGINT, ega_int_handler);
+ signal(SIGTERM, ega_int_handler);
+#ifdef SIGTSTP
+ signal(SIGTSTP, ega_tstp_handler);
+#endif
+#ifdef SIGCONT
+ signal(SIGCONT, ega_cont_handler);
+#endif
+}
+
+/* Read the device mode */
+void
+pcfb_get_state(pcfb_bios_state *pbs)
+{ int mode;
+ open_console();
+ mode = ioctl(console_fd, CONS_CURRENT, 0L);
+ if (mode == -1) {
+#ifdef __linux__
+ mode = M_ENH_C80x25;
+#else
+ ega_close((gx_device *)NULL);
+ eprintf("unable to get current console mode\n");
+ perror("pcfb_get_state");
+ exit(1);
+#endif
+ }
+ pbs->display_mode =
+ (mode == M_ENH_CG640 || mode == M_CG640x350 ? 0x10 :
+#ifdef M_VGA12
+ mode == M_VGA12 ? 0x12 :
+#endif
+ 0x03);
+}
+
+/* Set the device mode */
+void
+pcfb_set_mode(int mode)
+{ int i, mode1;
+ open_console();
+ cur_mode = mode;
+ mode1 = -1;
+ if (mode == 0x10) mode = SW_ENH_CG640;
+#ifdef SW_VGA12
+ else if (mode == 0x12) mode = SW_VGA12;
+#endif
+ else if (mode == 0x03) {
+#ifdef SW_VGA80x25
+ mode = SW_VGA80x25; mode1 = SW_ENHC80x25;
+#else
+ mode = SW_ENHC80x25;
+#endif
+ } else {
+ eprintf1("can not set to video mode %d\n", mode);
+ exit(1);
+ }
+ i = ioctl(console_fd, mode, 0L);
+ if (i == -1 && mode1 != -1)
+ i = ioctl(console_fd, mode1, 0L);
+ if (i == -1) {
+ ega_close((gx_device *)NULL);
+ eprintf("unable to set console mode\n");
+ perror("pcfb_set_mode");
+ exit(1);
+ }
+#ifdef VGA_IOPRIVL
+ if (ioctl(console_fd, VGA_IOPRIVL, 1) == -1) {
+ ega_close((gx_device *)NULL);
+ eprintf("unable to get I/O privilege\n");
+ perror("pcfb_set_mode");
+ exit(1);
+ }
+#endif
+ i = ioctl(console_fd, MAPCONS, 0L);
+ if (i == -1) {
+ ega_close((gx_device *)NULL);
+ eprintf("unable to map console adaptor's display memory\n");
+ perror("pcfb_set_mode");
+ exit(1);
+ }
+ fb_addr = (fb_ptr) (i);
+}
+
+/* Restore the device state */
+void
+pcfb_set_state(const pcfb_bios_state *pbs)
+{ pcfb_set_mode(pbs->display_mode);
+}