Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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