1 /* VGAlib version 1.2 - (c) 1993 Tommy Frandsen                    */
2 /*                                                                 */
3 /* This library is free software; you can redistribute it and/or   */
4 /* modify it without any restrictions. This library is distributed */
5 /* in the hope that it will be useful, but without any warranty.   */
6 
7 /* Multi-chipset support Copyright (C) 1993 Harm Hanemaayer */
8 /* partially copyrighted (C) 1993 by Hartmut Schirmer */
9 /* Changes by Michael Weller. */
10 /* Modified by Don Secrest to include Tseng ET6000 handling */
11 /* Changes around the config things by 101 (Attila Lendvai) */
12 
13 /* The code is a bit of a mess; also note that the drawing functions */
14 /* are not speed optimized (the gl functions are much faster). */
15 #define _GNU_SOURCE
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <fcntl.h>
19 #include <signal.h>
20 #include <termios.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <stdarg.h>
24 #include <sys/mman.h>
25 #include <sys/kbio.h>
26 #include <sys/ioctl.h>
27 #include <sys/stat.h>
28 #include <sys/consio.h>
29 #include <sys/wait.h>
30 #include <errno.h>
31 #include <ctype.h>
32 #include "vga.h"
33 #include "libvga.h"
34 #include "driver.h"
35 #include "vgapci.h"
36 #include "mouse/vgamouse.h"
37 #include "keyboard/vgakeyboard.h"
38 #include "vgaregs.h"
39 #include "vgaversion.h"
40 
41 int permfd = -1;
ioperm(unsigned long from,unsigned long num,int on)42 int ioperm(unsigned long from, unsigned long num, int on)
43 {
44 	if (permfd == -1)
45 		permfd = open("/dev/io", O_RDONLY);
46 	if (permfd != -1)
47 		return 0;
48 	else
49 		return 1;
50 }
51 
iopl(int level)52 int iopl(int level)
53 {
54 	return ioperm(0, 0, 0);
55 }
56 
57 #ifdef BACKGROUND
58 #include "vgabg.h"
59 
60 /* ugly check to prevent usage on kernel versions < 2.0.36 and < 2.1.123
61  * should this also be runtime checked?
62  *
63  * Why not earlier kernels?
64  * The following sequence of mmap() calls is deadly in these versions
65  * due to a kernel bug:
66  * #define MAP_ADDR 0xfd000000  // high mem area, eg. framebuf
67  * #define MAP_SIZE 0x200000
68  * map_a=mmap(0,MAP_SIZE,PROT_READ|PROT_WRITE,
69  *            MAP_PRIVATE|MAP_ANONYMOUS,-1,0);
70  * map_b=mmap(0,MAP_SIZE,PROT_READ | PROT_WRITE,
71  *            MAP_SHARED,dev_mem_fd,MAP_ADDR);
72  * map_c=mmap(map_a,MAP_SIZE,PROT_READ | PROT_WRITE,
73  *           MAP_SHARED | MAP_FIXED,proc_self_mem_fd,
74  *           map_b);
75  * The map_c mmapping will destroy random kernel data. A similar
76  * mmap sequence is done when calling __svgalib_map_virtual_screen()
77  * to map the linear framebuffer virtual address to the final
78  * virtual address (which then can mapped to backing storage on VC switch,
79  * transparently for the application).
80  */
81 #include <linux/version.h>
82 #define LNX_MAJ_VER ((LINUX_VERSION_CODE >> 16) & 255)
83 #define LNX_MED_VER ((LINUX_VERSION_CODE >> 8) & 255)
84 #define LNX_MIN_VER (LINUX_VERSION_CODE & 255)
85 #if (LNX_MAJ_VER < 2) || \
86     ( (LNX_MAJ_VER == 2) && (LNX_MED_VER == 0) && (LNX_MIN_VER < 36) ) || \
87     ( (LNX_MAJ_VER == 2) && (LNX_MED_VER == 1) && (LNX_MIN_VER < 123) ) || \
88     ( (LNX_MAJ_VER == 2) && (LNX_MED_VER == 3) && (LNX_MIN_VER > 26) )
89 #warning BACKGROUND *not* supported on kernel versions < 2.0.36 or < 2.1.123,
90 #warning or version>2.3.26. Compile without BACKGROUND.
91 #endif
92 #endif /* #ifdef BACKGROUND */
93 
94 /* Delay in microseconds after a mode is set (screen is blanked during this */
95 /* time), allows video signals to stabilize */
96 #define MODESWITCHDELAY 150000
97 
98 /* Define this to disable video output during mode switches, in addition to */
99 /* 'turning off the screen', which is always done. */
100 /* Doesn't look very nice on my Cirrus. */
101 /* #define DISABLE_VIDEO_OUTPUT */
102 
103 /* #define DONT_WAIT_VC_ACTIVE */
104 
105 /* Use /dev/tty instead of /dev/tty0 (the previous behaviour may have been
106  * silly). */
107 #define USE_DEVTTY
108 
109 #define SETSIG(sa, sig, fun) {\
110 	sa.sa_handler = fun; \
111 	sa.sa_flags = SA_RESTART; \
112 	zero_sa_mask(&(sa.sa_mask)); \
113 	sigaction(sig, &sa, NULL); \
114 }
115 
116 #ifdef INCLUDE_VESA_DRIVER
117 extern int __svgalib_lrmi_cpu_type;
118 #endif
119 
120 /* variables used to shift between monchrome and color emulation */
121 
122 int __svgalib_CRT_I;			/* current CRT index register address */
123 int __svgalib_CRT_D;			/* current CRT data register address */
124 int __svgalib_IS1_R;			/* current input status register address */
125 static int color_text;		/* true if color text emulation */
126 
127 unsigned char * BANKED_MEM_POINTER=NULL, * LINEAR_MEM_POINTER, *MMIO_POINTER;
128 unsigned char * B8000_MEM_POINTER=NULL;
129 unsigned long int __svgalib_banked_mem_base, __svgalib_banked_mem_size;
130 unsigned long int __svgalib_mmio_base, __svgalib_mmio_size=0;
131 unsigned long int __svgalib_linear_mem_base=0, __svgalib_linear_mem_size=0;
132 
133 /* If == 0 then nothing is defined by the user... */
134 int __svgalib_default_mode = 0;
135 
136 struct info infotable[] =
137 {
138     {80, 25, 16, 160, 0},	/* VGAlib VGA modes */
139     {320, 200, 16, 40, 0},
140     {640, 200, 16, 80, 0},
141     {640, 350, 16, 80, 0},
142     {640, 480, 16, 80, 0},
143     {320, 200, 256, 320, 1},
144     {320, 240, 256, 80, 0},
145     {320, 400, 256, 80, 0},
146     {360, 480, 256, 90, 0},
147     {640, 480, 2, 80, 0},
148 
149     {640, 480, 256, 640, 1},	/* VGAlib SVGA modes */
150     {800, 600, 256, 800, 1},
151     {1024, 768, 256, 1024, 1},
152     {1280, 1024, 256, 1280, 1},
153 
154     {320, 200, 1 << 15, 640, 2},	/* Hicolor/truecolor modes */
155     {320, 200, 1 << 16, 640, 2},
156     {320, 200, 1 << 24, 320 * 3, 3},
157     {640, 480, 1 << 15, 640 * 2, 2},
158     {640, 480, 1 << 16, 640 * 2, 2},
159     {640, 480, 1 << 24, 640 * 3, 3},
160     {800, 600, 1 << 15, 800 * 2, 2},
161     {800, 600, 1 << 16, 800 * 2, 2},
162     {800, 600, 1 << 24, 800 * 3, 3},
163     {1024, 768, 1 << 15, 1024 * 2, 2},
164     {1024, 768, 1 << 16, 1024 * 2, 2},
165     {1024, 768, 1 << 24, 1024 * 3, 3},
166     {1280, 1024, 1 << 15, 1280 * 2, 2},
167     {1280, 1024, 1 << 16, 1280 * 2, 2},
168     {1280, 1024, 1 << 24, 1280 * 3, 3},
169 
170     {800, 600, 16, 100, 0},	/* SVGA 16-color modes */
171     {1024, 768, 16, 128, 0},
172     {1280, 1024, 16, 160, 0},
173 
174     {720, 348, 2, 90, 0},	/* Hercules emulation mode */
175 
176     {320, 200, 1 << 24, 320 * 4, 4},
177     {640, 480, 1 << 24, 640 * 4, 4},
178     {800, 600, 1 << 24, 800 * 4, 4},
179     {1024, 768, 1 << 24, 1024 * 4, 4},
180     {1280, 1024, 1 << 24, 1280 * 4, 4},
181 
182     {1152, 864, 16, 144, 0},
183     {1152, 864, 256, 1152, 1},
184     {1152, 864, 1 << 15, 1152 * 2, 2},
185     {1152, 864, 1 << 16, 1152 * 2, 2},
186     {1152, 864, 1 << 24, 1152 * 3, 3},
187     {1152, 864, 1 << 24, 1152 * 4, 4},
188 
189     {1600, 1200, 16, 200, 0},
190     {1600, 1200, 256, 1600, 1},
191     {1600, 1200, 1 << 15, 1600 * 2, 2},
192     {1600, 1200, 1 << 16, 1600 * 2, 2},
193     {1600, 1200, 1 << 24, 1600 * 3, 3},
194     {1600, 1200, 1 << 24, 1600 * 4, 4},
195 
196     {320, 240, 256, 320, 1},
197     {320, 240, 1<<15, 320*2, 2},
198     {320, 240, 1<<16, 320*2, 2},
199     {320, 240, 1<<24, 320*3, 3},
200     {320, 240, 1<<24, 320*4, 4},
201 
202     {400, 300, 256, 400, 1},
203     {400, 300, 1<<15, 400*2, 2},
204     {400, 300, 1<<16, 400*2, 2},
205     {400, 300, 1<<24, 400*3, 3},
206     {400, 300, 1<<24, 400*4, 4},
207 
208     {512, 384, 256, 512, 1},
209     {512, 384, 1<<15, 512*2, 2},
210     {512, 384, 1<<16, 512*2, 2},
211     {512, 384, 1<<24, 512*3, 3},
212     {512, 384, 1<<24, 512*4, 4},
213 
214     {960, 720, 256, 960, 1},
215     {960, 720, 1<<15, 960*2, 2},
216     {960, 720, 1<<16, 960*2, 2},
217     {960, 720, 1<<24, 960*3, 3},
218     {960, 720, 1<<24, 960*4, 4},
219 
220     {1920, 1440, 256, 1920, 1},
221     {1920, 1440, 1<<15, 1920*2, 2},
222     {1920, 1440, 1<<16, 1920*2, 2},
223     {1920, 1440, 1<<24, 1920*3, 3},
224     {1920, 1440, 1<<24, 1920*4, 4},
225 
226     {320, 400, 1<<8,  320,   1},
227     {320, 400, 1<<15, 320*2, 2},
228     {320, 400, 1<<16, 320*2, 2},
229     {320, 400, 1<<24, 320*3, 3},
230     {320, 400, 1<<24, 320*4, 4},
231 
232     {640, 400, 256, 640, 1},
233     {640, 400, 1<<15, 640*2, 2},
234     {640, 400, 1<<16, 640*2, 2},
235     {640, 400, 1<<24, 640*3, 3},
236     {640, 400, 1<<24, 640*4, 4},
237 
238     {320, 480, 256, 320, 1},
239     {320, 480, 1<<15, 320*2, 2},
240     {320, 480, 1<<16, 320*2, 2},
241     {320, 480, 1<<24, 320*3, 3},
242     {320, 480, 1<<24, 320*4, 4},
243 
244     {720, 540, 256, 720, 1},
245     {720, 540, 1<<15, 720*2, 2},
246     {720, 540, 1<<16, 720*2, 2},
247     {720, 540, 1<<24, 720*3, 3},
248     {720, 540, 1<<24, 720*4, 4},
249 
250     {848, 480, 256, 848, 1},
251     {848, 480, 1<<15, 848*2, 2},
252     {848, 480, 1<<16, 848*2, 2},
253     {848, 480, 1<<24, 848*3, 3},
254     {848, 480, 1<<24, 848*4, 4},
255 
256     {1072, 600, 256, 1072, 1},
257     {1072, 600, 1<<15, 1072*2, 2},
258     {1072, 600, 1<<16, 1072*2, 2},
259     {1072, 600, 1<<24, 1072*3, 3},
260     {1072, 600, 1<<24, 1072*4, 4},
261 
262     {1280, 720, 256, 1280, 1},
263     {1280, 720, 1<<15, 1280*2, 2},
264     {1280, 720, 1<<16, 1280*2, 2},
265     {1280, 720, 1<<24, 1280*3, 3},
266     {1280, 720, 1<<24, 1280*4, 4},
267 
268     {1360, 768, 256, 1360, 1},
269     {1360, 768, 1<<15, 1360*2, 2},
270     {1360, 768, 1<<16, 1360*2, 2},
271     {1360, 768, 1<<24, 1360*3, 3},
272     {1360, 768, 1<<24, 1360*4, 4},
273 
274     {1800, 1012, 256, 1800, 1},
275     {1800, 1012, 1<<15, 1800*2, 2},
276     {1800, 1012, 1<<16, 1800*2, 2},
277     {1800, 1012, 1<<24, 1800*3, 3},
278     {1800, 1012, 1<<24, 1800*4, 4},
279 
280     {1920, 1080, 256, 1920, 1},
281     {1920, 1080, 1<<15, 1920*2, 2},
282     {1920, 1080, 1<<16, 1920*2, 2},
283     {1920, 1080, 1<<24, 1920*3, 3},
284     {1920, 1080, 1<<24, 1920*4, 4},
285 
286     {2048, 1152, 256, 2048, 1},
287     {2048, 1152, 1<<15, 2048*2, 2},
288     {2048, 1152, 1<<16, 2048*2, 2},
289     {2048, 1152, 1<<24, 2048*3, 3},
290     {2048, 1152, 1<<24, 2048*4, 4},
291 
292     {2048, 1536, 256, 2048, 1},
293     {2048, 1536, 1<<15, 2048*2, 2},
294     {2048, 1536, 1<<16, 2048*2, 2},
295     {2048, 1536, 1<<24, 2048*3, 3},
296     {2048, 1536, 1<<24, 2048*4, 4},
297 
298     {512, 480, 256, 512, 1},
299     {512, 480, 1<<15, 512*2, 2},
300     {512, 480, 1<<16, 512*2, 2},
301     {512, 480, 1<<24, 512*3, 3},
302     {512, 480, 1<<24, 512*4, 4},
303 
304     {400, 600, 256, 400, 1},
305     {400, 600, 1<<15, 400*2, 2},
306     {400, 600, 1<<16, 400*2, 2},
307     {400, 600, 1<<24, 400*3, 3},
308     {400, 600, 1<<24, 400*4, 4},
309 
310     {0, 0, 0, 0, 0},
311     {0, 0, 0, 0, 0},
312     {0, 0, 0, 0, 0},
313     {0, 0, 0, 0, 0},
314     {0, 0, 0, 0, 0},
315     {0, 0, 0, 0, 0},
316     {0, 0, 0, 0, 0},
317     {0, 0, 0, 0, 0},
318     {0, 0, 0, 0, 0},
319     {0, 0, 0, 0, 0},
320     {0, 0, 0, 0, 0},
321     {0, 0, 0, 0, 0},
322     {0, 0, 0, 0, 0},
323     {0, 0, 0, 0, 0},
324     {0, 0, 0, 0, 0},
325     {0, 0, 0, 0, 0},
326     {0, 0, 0, 0, 0}
327 };
328 
329 #define MAX_MODES (sizeof(infotable) / sizeof(struct info))
330 
331 #ifndef BACKGROUND
332 void (*__svgalib_go_to_background) (void) = 0;
333 void (*__svgalib_come_from_background) (void) = 0;
334 static int release_acquire=0;
335 #endif /* BACKGROUND */
336 
337 unsigned long __svgalib_graph_base = GRAPH_BASE;
338 
339 unsigned char __svgalib_novga = 0;     /* Does not have VGA circuitry on board */
340 unsigned char __svgalib_vesatext = 0;
341 unsigned char __svgalib_textprog = 0;  /* run a program when returning to text mode */
342 unsigned char __svgalib_secondary = 0; /* this is not the main card with VC'S (not yet supported) */
343 unsigned char __svgalib_novccontrol = 0; /* this is not the main card with VC'S (not yet supported) */
344 unsigned char __svgalib_simple = 0;
345 unsigned char __svgalib_ragedoubleclock = 0;
346 
347 /* default palette values */
348 static const unsigned char default_red[256]
349 =
350 {0, 0, 0, 0, 42, 42, 42, 42, 21, 21, 21, 21, 63, 63, 63, 63,
351  0, 5, 8, 11, 14, 17, 20, 24, 28, 32, 36, 40, 45, 50, 56, 63,
352  0, 16, 31, 47, 63, 63, 63, 63, 63, 63, 63, 63, 63, 47, 31, 16,
353  0, 0, 0, 0, 0, 0, 0, 0, 31, 39, 47, 55, 63, 63, 63, 63,
354  63, 63, 63, 63, 63, 55, 47, 39, 31, 31, 31, 31, 31, 31, 31, 31,
355  45, 49, 54, 58, 63, 63, 63, 63, 63, 63, 63, 63, 63, 58, 54, 49,
356  45, 45, 45, 45, 45, 45, 45, 45, 0, 7, 14, 21, 28, 28, 28, 28,
357  28, 28, 28, 28, 28, 21, 14, 7, 0, 0, 0, 0, 0, 0, 0, 0,
358  14, 17, 21, 24, 28, 28, 28, 28, 28, 28, 28, 28, 28, 24, 21, 17,
359  14, 14, 14, 14, 14, 14, 14, 14, 20, 22, 24, 26, 28, 28, 28, 28,
360  28, 28, 28, 28, 28, 26, 24, 22, 20, 20, 20, 20, 20, 20, 20, 20,
361  0, 4, 8, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 12, 8, 4,
362  0, 0, 0, 0, 0, 0, 0, 0, 8, 10, 12, 14, 16, 16, 16, 16,
363  16, 16, 16, 16, 16, 14, 12, 10, 8, 8, 8, 8, 8, 8, 8, 8,
364  11, 12, 13, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 13, 12,
365  11, 11, 11, 11, 11, 11, 11, 11, 0, 0, 0, 0, 0, 0, 0, 0};
366 static const unsigned char default_green[256]
367 =
368 {0, 0, 42, 42, 0, 0, 21, 42, 21, 21, 63, 63, 21, 21, 63, 63,
369  0, 5, 8, 11, 14, 17, 20, 24, 28, 32, 36, 40, 45, 50, 56, 63,
370  0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 31, 47, 63, 63, 63, 63,
371  63, 63, 63, 63, 63, 47, 31, 16, 31, 31, 31, 31, 31, 31, 31, 31,
372  31, 39, 47, 55, 63, 63, 63, 63, 63, 63, 63, 63, 63, 55, 47, 39,
373  45, 45, 45, 45, 45, 45, 45, 45, 45, 49, 54, 58, 63, 63, 63, 63,
374  63, 63, 63, 63, 63, 58, 54, 49, 0, 0, 0, 0, 0, 0, 0, 0,
375  0, 7, 14, 21, 29, 28, 28, 28, 28, 28, 28, 28, 28, 21, 14, 7,
376  14, 14, 14, 14, 14, 14, 14, 14, 14, 17, 21, 24, 28, 28, 28, 28,
377  28, 28, 28, 28, 28, 24, 21, 17, 20, 20, 20, 20, 20, 20, 20, 20,
378  20, 22, 24, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 26, 24, 22,
379  0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 8, 12, 16, 16, 16, 16,
380  16, 16, 16, 16, 16, 12, 8, 4, 8, 8, 8, 8, 8, 8, 8, 8,
381  8, 10, 12, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 12, 10,
382  11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 13, 15, 16, 16, 16, 16,
383  16, 16, 16, 16, 16, 15, 13, 12, 0, 0, 0, 0, 0, 0, 0, 0};
384 static const unsigned char default_blue[256]
385 =
386 {0, 42, 0, 42, 0, 42, 0, 42, 21, 63, 21, 63, 21, 63, 21, 63,
387  0, 5, 8, 11, 14, 17, 20, 24, 28, 32, 36, 40, 45, 50, 56, 63,
388  63, 63, 63, 63, 63, 47, 31, 16, 0, 0, 0, 0, 0, 0, 0, 0,
389  0, 16, 31, 47, 63, 63, 63, 63, 63, 63, 63, 63, 63, 55, 47, 39,
390  31, 31, 31, 31, 31, 31, 31, 31, 31, 39, 47, 55, 63, 63, 63, 63,
391  63, 63, 63, 63, 63, 58, 54, 49, 45, 45, 45, 45, 45, 45, 45, 45,
392  45, 49, 54, 58, 63, 63, 63, 63, 28, 28, 28, 28, 28, 21, 14, 7,
393  0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 14, 21, 28, 28, 28, 28,
394  28, 28, 28, 28, 28, 24, 21, 17, 14, 14, 14, 14, 14, 14, 14, 14,
395  14, 17, 21, 24, 28, 28, 28, 28, 28, 28, 28, 28, 28, 26, 24, 22,
396  20, 20, 20, 20, 20, 20, 20, 20, 20, 22, 24, 26, 28, 28, 28, 28,
397  16, 16, 16, 16, 16, 12, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0,
398  0, 4, 8, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 12, 10,
399  8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 12, 14, 16, 16, 16, 16,
400  16, 16, 16, 16, 16, 15, 13, 12, 11, 11, 11, 11, 11, 11, 11, 11,
401  11, 12, 13, 15, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0};
402 
403 
404 static unsigned char text_regs[MAX_REGS];	/* VGA registers for saved text mode */
405 static unsigned char graph_regs[MAX_REGS];	/* VGA registers for svgalib mode */
406 
407 char *__svgalib_TextProg_argv[16]; /* should be enough */
408 char *__svgalib_TextProg;
409 
410 /* saved text mode palette values */
411 static unsigned char text_red[256];
412 static unsigned char text_green[256];
413 static unsigned char text_blue[256];
414 
415 /* saved graphics mode palette values */
416 static unsigned char graph_red[256];
417 static unsigned char graph_green[256];
418 static unsigned char graph_blue[256];
419 
420 static int prv_mode = TEXT;	/* previous video mode      */
421 static int flip_mode = TEXT;	/* flipped video mode       */
422 
423 int CM = TEXT;			/* current video mode       */
424 struct info CI;			/* current video parameters */
425 int COL;			/* current color            */
426 
427 
428 static int initialized = 0;	/* flag: initialize() called ?  */
429 static int flip = 0;		/* flag: executing vga_flip() ? */
430 
431 /* svgalib additions: */
432 
433 int __svgalib_chipset = UNDEFINED;
434 int __svgalib_driver_report = 1;
435 	/* report driver used after chipset detection */
436 int __svgalib_videomemoryused = -1;
437 int __svgalib_modeX = 0;	/* true after vga_setmodeX() */
438 int __svgalib_modeflags = 0;	/* copy of flags for current mode */
439 int __svgalib_critical = 0;	/* indicates blitter is busy */
440 int __svgalib_screenon = 1;	/* screen visible if != 0 */
441 RefreshRange __svgalib_horizsync =
442 {31500U, 0U};			/* horz. refresh (Hz) min, max */
443 RefreshRange __svgalib_vertrefresh =
444 {50U, 70U};			/* vert. refresh (Hz) min, max */
445 int __svgalib_bandwidth=50000;  /* monitor maximum bandwidth (kHz) */
446 int __svgalib_grayscale = 0;	/* grayscale vs. color mode */
447 int __svgalib_modeinfo_linearset = 0;	/* IS_LINEAR handled via extended vga_modeinfo */
448 const int __svgalib_max_modes = MAX_MODES;	/* Needed for dynamical allocated tables in mach32.c */
449 
450 static unsigned __svgalib_maxhsync[] =
451 {
452     31500, 35100, 35500, 37900, 48300, 56000, 60000
453 };
454 
455 static int lastmodenumber = __GLASTMODE;	/* Last defined mode */
456 static int my_pid = 0;		/* process PID, used with atexit() */
457 #ifndef BACKGROUND
458 static int __svgalib_currentpage;
459 #endif
460 static int vga_page_offset;	/* offset to add to all vga_set*page() calls */
461 static int currentlogicalwidth;
462 static int currentdisplaystart;
463 static int mouse_support = 0;
464 int mouse_open = 0;
465 static int mouse_mode = 0;
466 static int mouse_type = -1;
467 static int mouse_modem_ctl = 0;
468 static char *mouse_device = "/dev/mouse";
469 #ifndef BACKGROUND
470 static int __svgalib_oktowrite = 1;
471 #endif
472 static int modeinfo_mask = ~0;
473 
474 int __svgalib_mem_fd = -1;	/* /dev/mem file descriptor  */
475 int __svgalib_tty_fd = -1;	/* /dev/tty file descriptor */
476 int __svgalib_nosigint = 0;	/* Don't generate SIGINT in graphics mode */
477 int __svgalib_runinbackground = 0;
478 static int svgalib_vc = -1, startup_vc = -1;
479 static int __svgalib_security_revokeallprivs = 1;
480 static unsigned fontbufsize = 8192; /* compatibility */
481 
482 /* Dummy buffer for mmapping grahics memory; points to 64K VGA framebuffer. */
483 unsigned char *__svgalib_graph_mem;
484 /* Exported variable (read-only) is shadowed from internal variable, for */
485 /* better shared library performance. */
486 unsigned char *graph_mem;
487 
488 /* static unsigned char saved_text[32768]; */
489 
490 /* Some new organisation for backgrund running. */
491 /* Alpha do not have ability to run in background (yet). */
492 /* Bg runnin has two different methods 1 and (2). */
493 
494 
495 #ifdef BACKGROUND
496 
497 static unsigned char *__svgalib_graph_mem_orginal;
498 static unsigned char *__svgalib_graph_mem_check;
499 unsigned char *__svgalib_graph_mem_linear_orginal;
500 unsigned char *__svgalib_graph_mem_linear_check;
501 static int __svgalib_linear_is_background=0;
502 int __svgalib_oktowrite=1;
503 
504 /* __svgalib_oktowrite tells if it is safe to write registers. */
505 
506 int __svgalib_currentpage;
507 int __svgalib_virtual_mem_fd=-1;
508 static int __svgalib_processnumber=-1;
509 static unsigned char *graph_buf2 = NULL;	/* saves linear graphics data during flip */
510 
511 #endif
512 
513 void *__svgalib_physaddr;
514 int __svgalib_linear_memory_size;
515 
516 
517 #ifdef __alpha__
518 
519 /* same as graph mem, but mapped through sparse memory: */
520 unsigned char *__svgalib_sparse_mem;
521 
522 #endif
523 
524 static unsigned char *graph_buf = NULL;		/* saves graphics data during flip */
525 
526 static unsigned char *font_buf1;	/* saved font data - plane 2 */
527 static unsigned char *font_buf2;	/* saved font data - plane 3 */
528 static unsigned char *text_buf1;	/* saved text data - plane 0 */
529 static unsigned char *text_buf2;	/* saved text data - plane 1 */
530 
531 static struct termios text_termio;	/* text mode termio parameters     */
532 static struct termios graph_termio;	/* graphics mode termio parameters */
533 
534 int __svgalib_flipchar = '\x1b';		/* flip character - initially  ESCAPE */
535 
536 /* Chipset specific functions */
537 
538 DriverSpecs *__svgalib_driverspecs = &__svgalib_vga_driverspecs;
539 
540 #ifndef BACKGROUND
541 static void (*__svgalib_setpage) (int);	/* gives little faster vga_setpage() */
542 static void (*__svgalib_setrdpage) (int);
543 static void (*__svgalib_setwrpage) (int);
544 #endif
545 #ifdef BACKGROUND
546 void (*__svgalib_setpage) (int);
547 void (*__svgalib_setrdpage) (int);
548 void (*__svgalib_setwrpage) (int);
549 #endif
550 
551 static void readconfigfile(void);
552 
553 DriverSpecs *__svgalib_driverspecslist[] =
554 {
555     NULL,			/* chipset undefined */
556     &__svgalib_vga_driverspecs,
557 #ifdef INCLUDE_ET4000_DRIVER
558     &__svgalib_et4000_driverspecs,
559 #else
560     NULL,
561 #endif
562 #ifdef INCLUDE_CIRRUS_DRIVER
563     &__svgalib_cirrus_driverspecs,
564 #else
565     NULL,
566 #endif
567 #ifdef INCLUDE_TVGA_DRIVER
568     &__svgalib_tvga8900_driverspecs,
569 #else
570     NULL,
571 #endif
572 #ifdef INCLUDE_OAK_DRIVER
573     &__svgalib_oak_driverspecs,
574 #else
575     NULL,
576 #endif
577 #ifdef INCLUDE_EGA_DRIVER
578     &__svgalib_ega_driverspecs,
579 #else
580     NULL,
581 #endif
582 #ifdef INCLUDE_S3_DRIVER
583     &__svgalib_s3_driverspecs,
584 #else
585     NULL,
586 #endif
587 #ifdef INCLUDE_ET3000_DRIVER
588     &__svgalib_et3000_driverspecs,
589 #else
590     NULL,
591 #endif
592 #ifdef INCLUDE_MACH32_DRIVER
593     &__svgalib_mach32_driverspecs,
594 #else
595     NULL,
596 #endif
597 #ifdef INCLUDE_GVGA6400_DRIVER
598     &__svgalib_gvga6400_driverspecs,
599 #else
600     NULL,
601 #endif
602 #ifdef INCLUDE_ARK_DRIVER
603     &__svgalib_ark_driverspecs,
604 #else
605     NULL,
606 #endif
607 #ifdef INCLUDE_ATI_DRIVER
608     &__svgalib_ati_driverspecs,
609 #else
610     NULL,
611 #endif
612 #ifdef INCLUDE_ALI_DRIVER
613     &__svgalib_ali_driverspecs,
614 #else
615     NULL,
616 #endif
617 #ifdef INCLUDE_MACH64_DRIVER
618     &__svgalib_mach64_driverspecs,
619 #else
620     NULL,
621 #endif
622 #ifdef INCLUDE_CHIPS_DRIVER
623     &__svgalib_chips_driverspecs,
624 #else
625     NULL,
626 #endif
627 #ifdef INCLUDE_APM_DRIVER
628     &__svgalib_apm_driverspecs,
629 #else
630     NULL,
631 #endif
632 #ifdef INCLUDE_NV3_DRIVER
633     &__svgalib_nv3_driverspecs,
634 #else
635     NULL,
636 #endif
637 #ifdef INCLUDE_ET6000_DRIVER
638     &__svgalib_et6000_driverspecs,
639 #else
640     NULL,
641 #endif
642 #ifdef INCLUDE_VESA_DRIVER
643     &__svgalib_vesa_driverspecs,
644 #else
645     NULL,
646 #endif
647 #ifdef INCLUDE_MX_DRIVER
648     &__svgalib_mx_driverspecs,
649 #else
650     NULL,
651 #endif
652 #ifdef INCLUDE_PARADISE_DRIVER
653     &__svgalib_paradise_driverspecs,
654 #else
655     NULL,
656 #endif
657 #ifdef INCLUDE_RAGE_DRIVER
658     &__svgalib_rage_driverspecs,
659 #else
660     NULL,
661 #endif
662 #ifdef INCLUDE_BANSHEE_DRIVER
663     &__svgalib_banshee_driverspecs,
664 #else
665     NULL,
666 #endif
667 #ifdef INCLUDE_SIS_DRIVER
668     &__svgalib_sis_driverspecs,
669 #else
670     NULL,
671 #endif
672 #ifdef INCLUDE_I740_DRIVER
673     &__svgalib_i740_driverspecs,
674 #else
675     NULL,
676 #endif
677 #ifdef INCLUDE_NEO_DRIVER
678     &__svgalib_neo_driverspecs,
679 #else
680     NULL,
681 #endif
682 #ifdef INCLUDE_LAGUNA_DRIVER
683     &__svgalib_laguna_driverspecs,
684 #else
685     NULL,
686 #endif
687 #ifdef INCLUDE_FBDEV_DRIVER
688      &__svgalib_fbdev_driverspecs,
689 #else
690      NULL,
691 #endif
692 #ifdef INCLUDE_G400_DRIVER
693      &__svgalib_g400_driverspecs,
694 #else
695      NULL,
696 #endif
697 #ifdef INCLUDE_R128_DRIVER
698      &__svgalib_r128_driverspecs,
699 #else
700      NULL,
701 #endif
702 #ifdef INCLUDE_SAVAGE_DRIVER
703      &__svgalib_savage_driverspecs,
704 #else
705      NULL,
706 #endif
707 };
708 
709 static char *driver_names[] =
710 {
711 "",
712 "VGA",
713 "ET4000",
714 "Cirrus",
715 "TVGA",
716 "Oak",
717 "EGA",
718 "S3",
719 "ET3000",
720 "Mach32",
721 "GVGA6400",
722 "ARK",
723 "ATI",
724 "ALI",
725 "Mach64",
726 "C&T",
727 "APM",
728 "NV3",
729 "ET6000",
730 "VESA",
731 "MX",
732 "PARADISE",
733 "RAGE",
734 "BANSHEE",
735 "SIS",
736 "I740",
737 "NEOMAGIC",
738 "LAGUNA",
739 "FBDev",
740 "G400",
741 "R128",
742 "Savage",
743  NULL};
744 
745 /* Chipset drivers */
746 
747 /* vgadrv       Standard VGA (also used by drivers below) */
748 /* et4000       Tseng ET4000 (from original vgalib) */
749 /* cirrus       Cirrus Logic GD542x */
750 /* tvga8900     Trident TVGA 8900/9000 (derived from tvgalib) */
751 /* oak          Oak Technologies 037/067/077 */
752 /* egadrv       IBM EGA (subset of VGA) */
753 /* s3           S3 911 */
754 /* mach32       ATI MACH32 */
755 /* ark          ARK Logic */
756 /* gvga6400     Genoa 6400 (old SVGA) */
757 /* ati          ATI */
758 /* ali          ALI2301 */
759 /* mach64	ATI MACH64 */
760 /* chips	chips & technologies*/
761 /* et6000       Tseng ET6000 */         /* DS */
762 
763 /*#define DEBUG */
764 
765 /* Debug config file parsing.. */
766 /*#define DEBUG_CONF */
767 
768 #ifdef DEBUG
_DEBUG(int dnr)769 static void _DEBUG(int dnr)
770 {
771     static int first = 1;
772     FILE *dfile;
773 
774     dfile = fopen("svgalib.debug", (first ? "w" : "a"));
775     first = 0;
776     if (dfile == NULL)
777 	exit(1);
778     fprintf(dfile, "debug #%d\n", dnr);
779     fclose(dfile);
780     sync();
781 }
782 #else
783 #define _DEBUG(d)
784 #endif
785 
set_graphtermio(void)786 static void set_graphtermio(void)
787 {
788     /* Leave keyboard alone when rawkeyboard is enabled! */
789     if (__svgalib_kbd_fd < 0) {
790 	/* set graphics mode termio parameters */
791 	ioctl(0, TIOCSETAW, &graph_termio);
792     }
793 }
794 
795 
set_texttermio(void)796 static void set_texttermio(void)
797 {
798     /* Leave keyboard alone when rawkeyboard is enabled! */
799     if (__svgalib_kbd_fd < 0) {
800 	/* restore text mode termio parameters */
801 	ioctl(0, TIOCSETAW, &text_termio);
802     }
803 }
804 
805 
disable_interrupt(void)806 static void disable_interrupt(void)
807 {
808     struct termios cur_termio;
809 
810     /* Well, one could argue that sigint is not enabled at all when in __svgalib_nosigint
811        but sometimes they *still* are enabled b4 graph_termio is set.. */
812     ioctl(0, TIOCGETA, &cur_termio);
813     cur_termio.c_lflag &= ~ISIG;
814     ioctl(0, TIOCSETAW, &cur_termio);
815 }
816 
817 
enable_interrupt(void)818 static void enable_interrupt(void)
819 {
820     struct termios cur_termio;
821 
822     if (__svgalib_nosigint) /* do not reenable, they are often reenabled by text_termio */
823 	return;
824     ioctl(0, TIOCGETA, &cur_termio);
825     cur_termio.c_lflag |= ISIG;
826     ioctl(0, TIOCSETAW, &cur_termio);
827 }
828 
829 /* The following is rather messy and inelegant. The only solution I can */
830 /* see is getting a extra free VT for graphics like XFree86 does. */
831 
__svgalib_waitvtactive(void)832 void __svgalib_waitvtactive(void)
833 {
834     if (__svgalib_tty_fd < 0)
835 	return; /* Not yet initialized */
836 
837     while (ioctl(__svgalib_tty_fd, VT_WAITACTIVE, svgalib_vc) < 0) {
838 	if ((errno != EAGAIN) && (errno != EINTR)) {
839 	    perror("ioctl(VT_WAITACTIVE)");
840 	    exit(1);
841 	}
842 	usleep(150000);
843     }
844 }
845 
846 
847 /* open /dev/mem */
open_mem(void)848 static void open_mem(void)
849 {
850 #ifdef BACKGROUND
851 #if BACKGROUND == 1
852  char tmp[40];
853 #endif
854 #endif
855 
856     if (CHIPSET == FBDEV)
857 	return;
858 
859     /*  Ensure that the open will get a file descriptor greater
860      *  than 2, else problems can occur with stdio functions
861      *  under certain strange conditions:  */
862     if (fcntl(0,F_GETFD) < 0) open("/dev/null", O_RDONLY);
863     if (fcntl(1,F_GETFD) < 0) open("/dev/null", O_WRONLY);
864     if (fcntl(2,F_GETFD) < 0) open("/dev/null", O_WRONLY);
865 
866     if (__svgalib_mem_fd < 0)
867 	if ((__svgalib_mem_fd = open("/dev/mem", O_RDWR)) < 0) {
868 	    printf("svgalib: Cannot open /dev/mem.\n");
869 	    exit(1);
870 	}
871 #ifdef BACKGROUND
872 #if BACKGROUND == 1
873 
874     /* Needs proc-fs. */
875     /* printf("procc\n"); */
876     /* char tmp[40];*/
877     if (__svgalib_virtual_mem_fd<0)
878         {
879 	 __svgalib_processnumber=getpid();
880 	 sprintf(tmp,"/proc/%d/mem",__svgalib_processnumber);
881 	 if ((__svgalib_virtual_mem_fd = open(tmp,O_RDWR)) < 0)
882 	     {
883 	      printf("svgalib: Cannot open /proc/%d/mem.\n",
884 	          __svgalib_processnumber);
885 	      exit(-1);
886 	     }
887 	}
888 #endif
889 #endif
890 }
891 
check_owner(int vc)892 static int check_owner(int vc)
893 {
894     struct stat sbuf;
895     char fname[30];
896 
897 #ifdef ROOT_VC_SHORTCUT
898     if (!getuid())
899         return 1;               /* root can do it always */
900 #endif
901     sprintf(fname, "/dev/ttyv%x", vc - 1);
902     if ((stat(fname, &sbuf) >= 0) && (getuid() == sbuf.st_uid)) {
903         return 1;
904     }
905     printf("You must be the owner of the current console to use svgalib.\n");
906     return 0;
907 }
908 
__svgalib_open_devconsole(void)909 void __svgalib_open_devconsole(void)
910 {
911     struct vt_mode vtm;
912     int vts;
913     struct stat sbuf;
914     char fname[30];
915 
916     if(__svgalib_novccontrol)return;
917 
918     if (__svgalib_tty_fd >= 0)
919         return;
920 
921     /*  The code below assumes file descriptors 0, 1, and 2
922      *  are already open; make sure that's true.  */
923     if (fcntl(0,F_GETFD) < 0) open("/dev/null", O_RDONLY);
924     if (fcntl(1,F_GETFD) < 0) open("/dev/null", O_WRONLY);
925     if (fcntl(2,F_GETFD) < 0) open("/dev/null", O_WRONLY);
926 
927     /*
928      * Now, it would be great if we could use /dev/tty and see what it is connected to.
929      * Alas, we cannot find out reliably what VC /dev/tty is bound to. Thus we parse
930      * stdin through stderr for a reliable VC
931      */
932     for (__svgalib_tty_fd = 0; __svgalib_tty_fd < 3; __svgalib_tty_fd++) {
933         if (fstat(__svgalib_tty_fd, &sbuf) < 0)
934             continue;
935         if (ioctl(__svgalib_tty_fd, VT_GETMODE, &vtm) < 0)
936             continue;
937         if ((sbuf.st_rdev & 0xff00) != 0x400)
938             continue;
939         if (!(sbuf.st_rdev & 0xff))
940             continue;
941         svgalib_vc = sbuf.st_rdev & 0xff;
942         return;                 /* perfect */
943     }
944 
945     if ((__svgalib_tty_fd = open("/dev/console", O_RDWR)) < 0) {
946         printf("svgalib: can't open /dev/console \n");
947         exit(1);
948     }
949     if (ioctl(__svgalib_tty_fd, VT_OPENQRY, &svgalib_vc) < 0)
950         goto error;
951     if (svgalib_vc <= 0)
952         goto error;
953     sprintf(fname, "/dev/ttyv%x", svgalib_vc - 1);
954     close(__svgalib_tty_fd);
955     /* change our control terminal: */
956     setpgid(0,getppid());
957     setsid();
958     /* We must use RDWR to allow for output... */
959     if (((__svgalib_tty_fd = open(fname, O_RDWR)) >= 0) &&
960         (ioctl(__svgalib_tty_fd, VT_GETACTIVE, &vts) >= 0)) {
961         if (!check_owner(vts))
962             goto error;
963         /* success, redirect all stdios */
964         if (DREP)
965             printf("[svgalib: allocated virtual console #%d]\n", svgalib_vc);
966         fflush(stdin);
967         fflush(stdout);
968         fflush(stderr);
969         close(0);
970         close(1);
971         close(2);
972         dup(__svgalib_tty_fd);
973         dup(__svgalib_tty_fd);
974         dup(__svgalib_tty_fd);
975         /* clear screen and switch to it */
976         fwrite("\e[H\e[J", 6, 1, stderr);
977         fflush(stderr);
978         if (svgalib_vc != vts) {
979             startup_vc = vts;
980 	    ioctl(__svgalib_tty_fd, VT_ACTIVATE, svgalib_vc);
981             __svgalib_waitvtactive();
982 	}
983     } else {
984 error:
985     if (__svgalib_tty_fd > 2)
986 	close(__svgalib_tty_fd);
987     __svgalib_tty_fd = - 1;
988     printf("Not running in a graphics capable console,\n"
989 	 "and unable to find one.\n");
990     }
991 }
992 
__svgalib_get_perm(void)993 void __svgalib_get_perm(void)
994 {
995     static int done = 0;
996 
997     /* Only do this once. */
998     if (done)
999 	return;
1000     done = 1;
1001 
1002     /* Get I/O permissions for VGA registers. */
1003     /* If IOPERM is set, assume permissions have already been obtained */
1004     /* by a calling (exec-ing) process, e.g. ioperm(1). */
1005 
1006     if (CHIPSET != FBDEV && getenv("IOPERM") == NULL)
1007 #ifdef __alpha__
1008 	if (ioperm(0x0000, 0x10000, 1)) {
1009 	    printf("svgalib: Cannot get I/O permissions.\n");
1010 	    exit(1);
1011 	}
1012 #else
1013 	if (ioperm(0x3b4, 0x3df - 0x3b4 + 1, 1)) {
1014 	    printf("svgalib: Cannot get I/O permissions.\n");
1015 	    exit(1);
1016 	}
1017 #endif
1018 
1019     /* Open /dev/mem (also needs supervisor rights; ioperm(1) can be */
1020     /* used together with a special group that has r/w access on */
1021     /* /dev/mem to facilitate this). */
1022     open_mem();
1023 
1024     __svgalib_open_devconsole();
1025 
1026     /* color or monochrome text emulation? */
1027     if (CHIPSET != EGA && CHIPSET != FBDEV && !__svgalib_novga)
1028 	color_text = port_in(MIS_R) & 0x01;
1029     else
1030 	color_text = 1;		/* EGA is assumed color */
1031 
1032     /* chose registers for color/monochrome emulation */
1033     if (color_text) {
1034 	__svgalib_CRT_I = CRT_IC;
1035 	__svgalib_CRT_D = CRT_DC;
1036 	__svgalib_IS1_R = IS1_RC;
1037     } else {
1038 	__svgalib_CRT_I = CRT_IM;
1039 	__svgalib_CRT_D = CRT_DM;
1040 	__svgalib_IS1_R = IS1_RM;
1041     }
1042 }
1043 
1044 
__svgalib_delay(void)1045 void __svgalib_delay(void)
1046 {
1047     int i;
1048     for (i = 0; i < 10; i++);
1049 }
1050 
1051 /* The Xfree server uses a slow copy, may help us too ... */
1052 #if defined(CONFIG_ALPHA_JENSEN)
1053 extern unsigned long vga_readl(unsigned long base, unsigned long off);
1054 extern void vga_writel(unsigned long b, unsigned long base, unsigned long off);
slowcpy_from_sm(unsigned char * dest,unsigned char * src,unsigned bytes)1055 static void slowcpy_from_sm(unsigned char *dest, unsigned char *src, unsigned bytes)
1056 {
1057     long i;
1058     if (((long) dest & 7) || ((long) src & 7) || bytes & 7) {
1059 	printf("svgalib: unaligned slowcpy()!\n");
1060 	exit(1);
1061     }
1062     for (i = 0; i < bytes; i++) {
1063 	*(dest + i) = (*(unsigned long *) (src + (i << 7)) >> ((i & 0x03) * 8))
1064 	    & 0xffUL;
1065     }
1066 }
slowcpy_to_sm(unsigned char * dest,unsigned char * src,unsigned bytes)1067 static void slowcpy_to_sm(unsigned char *dest, unsigned char *src, unsigned bytes)
1068 {
1069     long i;
1070     if (((long) dest & 7) || ((long) src & 7) || bytes & 7) {
1071 	printf("svgalib: unaligned slowcpy()!\n");
1072 	exit(1);
1073     }
1074     for (i = 0; i < bytes; i++) {
1075 	*(unsigned long *) (dest + (i << 7)) =
1076 	    (*(unsigned char *) (src + i)) * 0x01010101UL;
1077     }
1078 }
1079 
1080 #else
slowcpy(unsigned char * dest,unsigned char * src,unsigned bytes)1081 static void slowcpy(unsigned char *dest, unsigned char *src, unsigned bytes)
1082 {
1083 #ifdef __alpha__
1084     if (((long) dest & 7) || ((long) src & 7) || bytes & 7) {
1085 	printf("svgalib: unaligned slowcpy()!\n");
1086 	exit(1);
1087     }
1088     while (bytes > 0) {
1089 	*(long *) dest = *(long *) src;
1090 	dest += 8;
1091 	src += 8;
1092 	bytes -= 8;
1093     }
1094 #else
1095     while (bytes-- > 0)
1096 	*(dest++) = *(src++);
1097 #endif
1098 }
1099 #endif
1100 
1101 #define TEXT_SIZE 65536
1102 
restore_text(void)1103 static void restore_text(void)
1104 {
1105 
1106           __svgalib_outseq(0x02,0x01);
1107 
1108 #ifdef __alpha__
1109 	  port_out(0x06, GRA_I);
1110 	  port_out(0x00, GRA_D);
1111 #endif
1112 
1113 #ifdef BACKGROUND
1114           if (-1 == mprotect(text_buf1,TEXT_SIZE*2,PROT_READ|PROT_WRITE))
1115           {
1116 	   printf("svgalib: Memory protect error\n");
1117 	   exit(-1);
1118 	  }
1119 #endif
1120 
1121 #if defined(CONFIG_ALPHA_JENSEN)
1122 	  slowcpy_to_sm(SM, text_buf1, TEXT_SIZE);
1123 #else
1124 	  slowcpy(GM, text_buf1, TEXT_SIZE);
1125 #endif
1126 
1127           __svgalib_outseq(0x02,0x02);
1128 #if defined(CONFIG_ALPHA_JENSEN)
1129 	  slowcpy_to_sm(SM, text_buf2, TEXT_SIZE);
1130 #else
1131 	  slowcpy(GM, text_buf2, TEXT_SIZE);
1132 #endif
1133 #ifdef BACKGROUND
1134           if (-1 == mprotect(text_buf1,TEXT_SIZE*2,PROT_READ))
1135           {
1136 	   printf("svgalib: Memory protect error\n");
1137 	   exit(1);
1138 	  }
1139 #endif
1140 };
1141 
save_text(void)1142 static void save_text(void)
1143 {
1144 
1145 #ifndef BACKGROUND
1146    	text_buf1 = malloc(TEXT_SIZE * 2);
1147 #endif
1148 #ifdef BACKGROUND
1149         text_buf1 = valloc(TEXT_SIZE * 2);
1150 #endif
1151         text_buf2 = text_buf1 + TEXT_SIZE;
1152 
1153         port_out(0x04, GRA_I);
1154         port_out(0x00, GRA_D);
1155 #ifdef __alpha__
1156         port_out(0x06, GRA_I);
1157         port_out(0x00, GRA_D);
1158 #endif
1159 #if defined(CONFIG_ALPHA_JENSEN)
1160         slowcpy_from_sm(text_buf1, SM, TEXT_SIZE);
1161 #else
1162         slowcpy(text_buf1, GM, TEXT_SIZE);
1163 #endif
1164 
1165         /* save font data in plane 3 */
1166         port_out(0x04, GRA_I);
1167         port_out(0x01, GRA_D);
1168 #if defined(CONFIG_ALPHA_JENSEN)
1169         slowcpy_from_sm(text_buf2, SM, TEXT_SIZE);
1170 #else
1171         slowcpy(text_buf2, GM, TEXT_SIZE);
1172 #endif
1173 
1174 #ifdef BACKGROUND
1175         /* Let's protect font. */
1176         /* Read only */
1177         if (-1 == mprotect(text_buf1,TEXT_SIZE*2,PROT_READ))
1178             {
1179 	     printf("svgalib: Memory protect error\n");
1180 	     exit(-1);
1181 	    }
1182 #endif
1183 
1184 };
1185 
__svgalib_saveregs(unsigned char * regs)1186 int __svgalib_saveregs(unsigned char *regs)
1187 {
1188     int i;
1189 
1190     if (__svgalib_chipset == EGA || __svgalib_novga) {
1191 	/* Special case: Don't save standard VGA registers. */
1192 	return chipset_saveregs(regs);
1193     }
1194     /* save VGA registers */
1195     for (i = 0; i < CRT_C; i++) {
1196         regs[CRT + i] = __svgalib_incrtc(i);
1197     }
1198     for (i = 0; i < ATT_C; i++) {
1199 	port_in(__svgalib_IS1_R);
1200 	__svgalib_delay();
1201 	port_out(i, ATT_IW);
1202 	__svgalib_delay();
1203 	regs[ATT + i] = port_in(ATT_R);
1204 	__svgalib_delay();
1205     }
1206     for (i = 0; i < GRA_C; i++) {
1207 	port_out(i, GRA_I);
1208 	regs[GRA + i] = port_in(GRA_D);
1209     }
1210     for (i = 0; i < SEQ_C; i++) {
1211 	port_out(i, SEQ_I);
1212 	regs[SEQ + i] = port_in(SEQ_D);
1213     }
1214     regs[MIS] = __svgalib_inmisc();
1215 
1216     i = chipset_saveregs(regs);	/* save chipset-specific registers */
1217     /* i : additional registers */
1218     if (!SCREENON) {		/* We turned off the screen */
1219 	port_in(__svgalib_IS1_R);
1220 	__svgalib_delay();
1221 	port_out(0x20, ATT_IW);
1222     }
1223     return CRT_C + ATT_C + GRA_C + SEQ_C + 1 + i;
1224 }
1225 
1226 
__svgalib_setregs(const unsigned char * regs)1227 int __svgalib_setregs(const unsigned char *regs)
1228 {
1229     int i;
1230 
1231     if(__svgalib_novga) return 1;
1232 
1233     if (__svgalib_chipset == EGA) {
1234 	/* Enable graphics register modification */
1235 	port_out(0x00, GRA_E0);
1236 	port_out(0x01, GRA_E1);
1237     }
1238     /* update misc output register */
1239     __svgalib_outmisc(regs[MIS]);
1240 
1241     /* synchronous reset on */
1242     __svgalib_outseq(0x00,0x01);
1243 
1244     /* write sequencer registers */
1245     __svgalib_outseq(0x01,regs[SEQ + 1] | 0x20);
1246     port_out(1, SEQ_I);
1247     port_out(regs[SEQ + 1] | 0x20, SEQ_D);
1248     for (i = 2; i < SEQ_C; i++) {
1249        __svgalib_outseq(i,regs[SEQ + i]);
1250     }
1251 
1252     /* synchronous reset off */
1253     __svgalib_outseq(0x00,0x03);
1254 
1255     if (__svgalib_chipset != EGA) {
1256 	/* deprotect CRT registers 0-7 */
1257         __svgalib_outcrtc(0x11,__svgalib_incrtc(0x11)&0x7f);
1258     }
1259     /* write CRT registers */
1260     for (i = 0; i < CRT_C; i++) {
1261         __svgalib_outcrtc(i,regs[CRT + i]);
1262     }
1263 
1264     /* write graphics controller registers */
1265     for (i = 0; i < GRA_C; i++) {
1266 	port_out(i, GRA_I);
1267 	port_out(regs[GRA + i], GRA_D);
1268     }
1269 
1270     /* write attribute controller registers */
1271     for (i = 0; i < ATT_C; i++) {
1272 	port_in(__svgalib_IS1_R);		/* reset flip-flop */
1273 	__svgalib_delay();
1274 	port_out(i, ATT_IW);
1275 	__svgalib_delay();
1276 	port_out(regs[ATT + i], ATT_IW);
1277 	__svgalib_delay();
1278     }
1279 
1280     return 0;
1281 }
1282 
1283 /* We invoke the old interrupt handler after setting text mode */
1284 /* We catch all signals that cause an exit by default (aka almost all) */
1285 static char sig2catch[] =
1286 {SIGHUP, SIGINT, SIGQUIT, SIGILL,
1287  SIGTRAP, SIGIOT, SIGBUS, SIGFPE,
1288  SIGSEGV, SIGPIPE, SIGALRM, SIGTERM,
1289  SIGXCPU, SIGXFSZ, SIGVTALRM,
1290 /* SIGPROF ,*/ SIGUSR1};
1291 static struct sigaction old_signal_handler[sizeof(sig2catch)];
1292 
1293 struct vt_mode __svgalib_oldvtmode;
1294 
restoretextmode(void)1295 static void restoretextmode(void)
1296 {
1297     /* handle unexpected interrupts - restore text mode and exit */
1298     keyboard_close();
1299     /* Restore a setting screwed by keyboard_close (if opened in graphicsmode) */
1300     set_texttermio();
1301     if (CM != TEXT)
1302 	vga_setmode(TEXT);
1303     if (!__svgalib_screenon)
1304 	vga_screenon();
1305     if (__svgalib_tty_fd >= 0) {
1306         if (!__svgalib_secondary) {
1307 	    ioctl(__svgalib_tty_fd, KDSETMODE, KD_TEXT);
1308             ioctl(__svgalib_tty_fd, VT_SETMODE, &__svgalib_oldvtmode);
1309 	}
1310     }
1311     if((__svgalib_textprog&3)==3){
1312        pid_t child;
1313        if((child=fork())==0){
1314        execv(__svgalib_TextProg,__svgalib_TextProg_argv);
1315        } else {
1316        waitpid(child,NULL,0);
1317        };
1318     };
1319 }
1320 
idle_accel(void)1321 static void idle_accel(void) {
1322     /* wait for the accel to finish, we assume one of the both interfaces suffices */
1323     if (vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_ACCEL) & ACCELFLAG_SYNC)
1324         vga_accel(ACCEL_SYNC);
1325     else if (vga_getmodeinfo(CM)->haveblit & HAVE_BLITWAIT)
1326 	vga_blitwait();
1327 }
1328 
signal_handler(int v)1329 static void signal_handler(int v)
1330 {
1331     int i;
1332 
1333     /* If we have accelerated functions, possibly wait for the
1334      * blitter to finish. I hope the PutBitmap functions disable
1335      * interrupts while writing data to the screen, otherwise
1336      * this will cause an infinite loop.
1337      */
1338     idle_accel();
1339 
1340     restoretextmode();
1341     printf("svgalib: Signal %d: %s received%s.\n", v, strsignal(v),
1342 	   (v == SIGINT) ? " (ctrl-c pressed)" : "");
1343 
1344     for (i = 0; i < sizeof(sig2catch); i++)
1345 	if (sig2catch[i] == v) {
1346 	    sigaction(v, old_signal_handler + i, NULL);
1347 	    raise(v);
1348 	    break;
1349 	}
1350     if (i >= sizeof(sig2catch)) {
1351 	printf("svgalib: Aieeee! Illegal call to signal_handler, raising segfault.\n");
1352 	raise(SIGSEGV);
1353     }
1354 }
1355 
__svgalib_getchipset(void)1356 int __svgalib_getchipset(void)
1357 {
1358     readconfigfile();		/* Make sure the config file is read. */
1359 
1360 /* Unlike the others, the FBDev test needs to be before __svgalib_get_perm() */
1361 
1362 #ifdef INCLUDE_FBDEV_DRIVER_TEST
1363     if (CHIPSET == UNDEFINED && __svgalib_fbdev_driverspecs.test())
1364     {
1365 	CHIPSET = FBDEV;
1366 	__svgalib_setpage = __svgalib_driverspecs->__svgalib_setpage;
1367 	__svgalib_setrdpage = __svgalib_driverspecs->__svgalib_setrdpage;
1368 	__svgalib_setwrpage = __svgalib_driverspecs->__svgalib_setwrpage;
1369     }
1370 #endif
1371     __svgalib_get_perm();
1372     if (CHIPSET == UNDEFINED) {
1373 	CHIPSET = VGA;		/* Protect against recursion */
1374 #ifdef INCLUDE_NV3_DRIVER_TEST
1375 	if (__svgalib_nv3_driverspecs.test())
1376 	    CHIPSET = NV3;
1377 	else
1378 #endif
1379 #ifdef INCLUDE_G400_DRIVER_TEST
1380 	if (__svgalib_g400_driverspecs.test())
1381 	    CHIPSET = G400;
1382 	else
1383 #endif
1384 #ifdef INCLUDE_R128_DRIVER_TEST
1385 	if (__svgalib_r128_driverspecs.test())
1386 	    CHIPSET = R128;
1387 	else
1388 #endif
1389 #ifdef INCLUDE_BANSHEE_DRIVER_TEST
1390 	if (__svgalib_banshee_driverspecs.test())
1391 	    CHIPSET = BANSHEE;
1392 	else
1393 #endif
1394 #ifdef INCLUDE_SIS_DRIVER_TEST
1395 	if (__svgalib_sis_driverspecs.test())
1396 	    CHIPSET = SIS;
1397 	else
1398 #endif
1399 #ifdef INCLUDE_I740_DRIVER_TEST
1400 	if (__svgalib_i740_driverspecs.test())
1401 	    CHIPSET = I740;
1402 	else
1403 #endif
1404 #ifdef INCLUDE_LAGUNA_DRIVER_TEST
1405 	if (__svgalib_laguna_driverspecs.test())
1406 	    CHIPSET = LAGUNA;
1407 	else
1408 #endif
1409 #ifdef INCLUDE_RAGE_DRIVER_TEST
1410 	if (__svgalib_rage_driverspecs.test())
1411 	    CHIPSET = RAGE;
1412 	else
1413 #endif
1414 #ifdef INCLUDE_MX_DRIVER_TEST
1415 	if (__svgalib_mx_driverspecs.test())
1416 	    CHIPSET = MX;
1417 	else
1418 #endif
1419 #ifdef INCLUDE_SAVAGE_DRIVER_TEST
1420 	if (__svgalib_savage_driverspecs.test())
1421 	    CHIPSET = SAVAGE;
1422 	else
1423 #endif
1424 #ifdef INCLUDE_NEO_DRIVER_TEST
1425 	if (__svgalib_neo_driverspecs.test())
1426 	    CHIPSET = NEOMAGIC;
1427 	else
1428 #endif
1429 #ifdef INCLUDE_CHIPS_DRIVER_TEST
1430 	if (__svgalib_chips_driverspecs.test())
1431 	    CHIPSET = CHIPS;
1432 	else
1433 #endif
1434 #ifdef INCLUDE_MACH64_DRIVER_TEST
1435 	if (__svgalib_mach64_driverspecs.test())
1436 	    CHIPSET = MACH64;
1437 	else
1438 #endif
1439 #ifdef INCLUDE_MACH32_DRIVER_TEST
1440 	if (__svgalib_mach32_driverspecs.test())
1441 	    CHIPSET = MACH32;
1442 	else
1443 #endif
1444 #ifdef INCLUDE_EGA_DRIVER_TEST
1445 	if (__svgalib_ega_driverspecs.test())
1446 	    CHIPSET = EGA;
1447 	else
1448 #endif
1449 #ifdef INCLUDE_ET6000_DRIVER_TEST                   /* DS */
1450 	if (__svgalib_et6000_driverspecs.test())    /* This must be before */
1451 	    CHIPSET = ET6000;                       /* ET4000 or the card  */
1452 	else                                        /* will be called et4k */
1453 #endif
1454 #ifdef INCLUDE_ET4000_DRIVER_TEST
1455 	if (__svgalib_et4000_driverspecs.test())
1456 	    CHIPSET = ET4000;
1457 	else
1458 #endif
1459 #ifdef INCLUDE_TVGA_DRIVER_TEST
1460 	if (__svgalib_tvga8900_driverspecs.test())
1461 	    CHIPSET = TVGA8900;
1462 	else
1463 #endif
1464 #ifdef INCLUDE_CIRRUS_DRIVER_TEST
1465 	    /* The Cirrus detection is not very clean. */
1466 	if (__svgalib_cirrus_driverspecs.test())
1467 	    CHIPSET = CIRRUS;
1468 	else
1469 #endif
1470 #ifdef INCLUDE_OAK_DRIVER_TEST
1471 	if (__svgalib_oak_driverspecs.test())
1472 	    CHIPSET = OAK;
1473 	else
1474 #endif
1475 #ifdef INCLUDE_PARADISE_DRIVER_TEST
1476 	if (__svgalib_paradise_driverspecs.test())
1477 	    CHIPSET = PARADISE;
1478 	else
1479 #endif
1480 #ifdef INCLUDE_S3_DRIVER_TEST
1481 	if (__svgalib_s3_driverspecs.test())
1482 	    CHIPSET = S3;
1483 	else
1484 #endif
1485 #ifdef INCLUDE_ET3000_DRIVER_TEST
1486 	if (__svgalib_et3000_driverspecs.test())
1487 	    CHIPSET = ET3000;
1488 	else
1489 #endif
1490 #ifdef INCLUDE_ARK_DRIVER_TEST
1491 	if (__svgalib_ark_driverspecs.test())
1492 	    CHIPSET = ARK;
1493 	else
1494 #endif
1495 #ifdef INCLUDE_GVGA6400_DRIVER_TEST
1496 	if (__svgalib_gvga6400_driverspecs.test())
1497 	    CHIPSET = GVGA6400;
1498 	else
1499 #endif
1500 #ifdef INCLUDE_ATI_DRIVER_TEST
1501 	if (__svgalib_ati_driverspecs.test())
1502 	    CHIPSET = ATI;
1503 	else
1504 #endif
1505 #ifdef INCLUDE_ALI_DRIVER_TEST
1506 	if (__svgalib_ali_driverspecs.test())
1507 	    CHIPSET = ALI;
1508 	else
1509 #endif
1510 #ifdef INCLUDE_APM_DRIVER_TEST
1511 /* Note: On certain cards this may toggle the video signal on/off which
1512    is ugly. Hence we test this last. */
1513 	if (__svgalib_apm_driverspecs.test())
1514 	    CHIPSET = APM;
1515 	else
1516 #endif
1517 #ifdef INCLUDE_VESA_DRIVER_TEST
1518 	if (__svgalib_vesa_driverspecs.test())
1519 	    CHIPSET = VESA;
1520 	else
1521 #endif
1522 
1523 	if (__svgalib_vga_driverspecs.test())
1524 	    CHIPSET = VGA;
1525 	else
1526 	    /* else */
1527 	{
1528 	    fprintf(stderr, "svgalib: Cannot find EGA or VGA graphics device.\n");
1529 	    exit(1);
1530 	}
1531 	__svgalib_setpage = __svgalib_driverspecs->__svgalib_setpage;
1532 	__svgalib_setrdpage = __svgalib_driverspecs->__svgalib_setrdpage;
1533 	__svgalib_setwrpage = __svgalib_driverspecs->__svgalib_setwrpage;
1534     }
1535     return CHIPSET;
1536 }
1537 
vga_setchipset(int c)1538 void vga_setchipset(int c)
1539 {
1540     CHIPSET = c;
1541 #ifdef DEBUG
1542     printf("Setting chipset\n");
1543 #endif
1544     if (c == UNDEFINED)
1545 	return;
1546     if (__svgalib_driverspecslist[c] == NULL) {
1547 	printf("svgalib: Invalid chipset. The driver may not be compiled in.\n");
1548 	CHIPSET = UNDEFINED;
1549 	return;
1550     }
1551     __svgalib_get_perm();
1552     __svgalib_driverspecslist[c]->init(0, 0, 0);
1553     __svgalib_setpage = __svgalib_driverspecs->__svgalib_setpage;
1554     __svgalib_setrdpage = __svgalib_driverspecs->__svgalib_setrdpage;
1555     __svgalib_setwrpage = __svgalib_driverspecs->__svgalib_setwrpage;
1556 }
1557 
vga_setchipsetandfeatures(int c,int par1,int par2)1558 void vga_setchipsetandfeatures(int c, int par1, int par2)
1559 {
1560     CHIPSET = c;
1561 #ifdef DEBUG
1562     printf("Forcing chipset and features\n");
1563 #endif
1564     __svgalib_get_perm();
1565     __svgalib_driverspecslist[c]->init(1, par1, par2);
1566 #ifdef DEBUG
1567     printf("Finished forcing chipset and features\n");
1568 #endif
1569     __svgalib_setpage = __svgalib_driverspecs->__svgalib_setpage;
1570     __svgalib_setrdpage = __svgalib_driverspecs->__svgalib_setrdpage;
1571     __svgalib_setwrpage = __svgalib_driverspecs->__svgalib_setwrpage;
1572 }
1573 
1574 
savepalette(unsigned char * red,unsigned char * green,unsigned char * blue)1575 static void savepalette(unsigned char *red, unsigned char *green,
1576 			unsigned char *blue)
1577 {
1578     int i;
1579 
1580     if (__svgalib_driverspecs->emul && __svgalib_driverspecs->emul->savepalette)
1581         return (__svgalib_driverspecs->emul->savepalette(red, green, blue));
1582 
1583     if (CHIPSET == EGA || __svgalib_novga)
1584 	return;
1585 
1586     /* save graphics mode palette - first select palette index 0 */
1587     port_out(0, PEL_IR);
1588 
1589     /* read RGB components - index is autoincremented */
1590     for (i = 0; i < 256; i++) {
1591 	__svgalib_delay();
1592 	*(red++) = port_in(PEL_D);
1593 	__svgalib_delay();
1594 	*(green++) = port_in(PEL_D);
1595 	__svgalib_delay();
1596 	*(blue++) = port_in(PEL_D);
1597     }
1598 }
1599 
restorepalette(const unsigned char * red,const unsigned char * green,const unsigned char * blue)1600 static void restorepalette(const unsigned char *red,
1601 		   const unsigned char *green, const unsigned char *blue)
1602 {
1603     int i;
1604 
1605     if (__svgalib_driverspecs->emul && __svgalib_driverspecs->emul->restorepalette)
1606         return (__svgalib_driverspecs->emul->restorepalette(red, green, blue));
1607 
1608     if (CHIPSET == EGA || __svgalib_novga)
1609 	return;
1610 
1611     /* restore saved palette */
1612     port_out(0, PEL_IW);
1613 
1614     /* read RGB components - index is autoincremented */
1615     for (i = 0; i < 256; i++) {
1616 	__svgalib_delay();
1617 	port_out(*(red++), PEL_D);
1618 	__svgalib_delay();
1619 	port_out(*(green++), PEL_D);
1620 	__svgalib_delay();
1621 	port_out(*(blue++), PEL_D);
1622     }
1623 }
1624 
1625 #ifndef BACKGROUND
1626 
1627 /* Virtual console switching */
1628 
1629 static int forbidvtrelease = 0;
1630 static int forbidvtacquire = 0;
1631 static int lock_count = 0;
1632 static int release_flag = 0;
1633 
1634 static void __svgalib_takevtcontrol(void);
1635 
1636 void __svgalib_flipaway(void);
1637 static void __svgalib_flipback(void);
1638 
__svgalib_releasevt_signal(int n)1639 static void __svgalib_releasevt_signal(int n)
1640 {
1641     if (lock_count) {
1642 	release_flag = 1;
1643 	return;
1644     }
1645 #ifdef DEBUG
1646     printf("Release request.\n");
1647 #endif
1648     forbidvtacquire = 1;
1649     if (forbidvtrelease) {
1650 	forbidvtacquire = 0;
1651 	ioctl(__svgalib_tty_fd, VT_RELDISP, 0);
1652 	return;
1653     }
1654     if (__svgalib_go_to_background)
1655 	(__svgalib_go_to_background) ();
1656     __svgalib_flipaway();
1657         if((__svgalib_textprog&3)==3){
1658            pid_t child;
1659            if((child=fork())==0){
1660            execv(__svgalib_TextProg,__svgalib_TextProg_argv);
1661            } else {
1662            waitpid(child,NULL,0);
1663            };
1664         };
1665     ioctl(__svgalib_tty_fd, VT_RELDISP, 1);
1666 #ifdef DEBUG
1667     printf("Finished release.\n");
1668 #endif
1669     forbidvtacquire = 0;
1670 
1671     /* Suspend program until switched to again. */
1672 #ifdef DEBUG
1673     printf("Suspended.\n");
1674 #endif
1675 
1676     __svgalib_oktowrite = 0;
1677     if (!__svgalib_runinbackground)
1678 	__svgalib_waitvtactive();
1679 #ifdef DEBUG
1680     printf("Waked.\n");
1681 #endif
1682 }
1683 
__svgalib_acquirevt_signal(int n)1684 static void __svgalib_acquirevt_signal(int n)
1685 {
1686 #ifdef DEBUG
1687     printf("Acquisition request.\n");
1688 #endif
1689     forbidvtrelease = 1;
1690     if (forbidvtacquire) {
1691 	forbidvtrelease = 0;
1692 	return;
1693     }
1694     __svgalib_flipback();
1695     ioctl(__svgalib_tty_fd, VT_RELDISP, VT_ACKACQ);
1696 #ifdef DEBUG
1697     printf("Finished acquisition.\n");
1698 #endif
1699     forbidvtrelease = 0;
1700     if (__svgalib_come_from_background)
1701 	(__svgalib_come_from_background) ();
1702     __svgalib_oktowrite = 1;
1703 }
1704 
1705 #endif
1706 
1707 #ifndef BACKGROUND
1708 
__svgalib_takevtcontrol(void)1709 void __svgalib_takevtcontrol(void)
1710 {
1711     struct sigaction siga;
1712     struct vt_mode newvtmode;
1713 
1714     ioctl(__svgalib_tty_fd, VT_GETMODE, &__svgalib_oldvtmode);
1715     newvtmode = __svgalib_oldvtmode;
1716     newvtmode.mode = VT_PROCESS;	/* handle VT changes */
1717     newvtmode.relsig = SVGALIB_RELEASE_SIG;	/* I didn't find SIGUSR1/2 anywhere */
1718     newvtmode.acqsig = SVGALIB_ACQUIRE_SIG;	/* in the kernel sources, so I guess */
1719     /* they are free */
1720     SETSIG(siga, SVGALIB_RELEASE_SIG, __svgalib_releasevt_signal);
1721     SETSIG(siga, SVGALIB_ACQUIRE_SIG, __svgalib_acquirevt_signal);
1722     ioctl(__svgalib_tty_fd, VT_SETMODE, &newvtmode);
1723 }
1724 
1725 #endif
1726 
1727 #ifdef LINEAR_DEBUG
dump_mem(unsigned char * name)1728 void dump_mem(unsigned char *name)
1729 {
1730   unsigned char bu[128];
1731   sprintf(bu,"cat /proc/%d/maps > /tmp/%s",getpid(),name);
1732   system(bu);
1733 }
1734 #endif
1735 
1736 #ifdef BACKGROUND
1737 #if BACKGROUND == 1
__svgalib_map_virtual_screen(int page)1738 void __svgalib_map_virtual_screen(int page)
1739 {
1740  if (page==1000000)
1741      {
1742       __svgalib_graph_mem =
1743           (unsigned char *) mmap((caddr_t) GM, GRAPH_SIZE,
1744 				 PROT_READ | PROT_WRITE,
1745 				 MAP_SHARED | MAP_FIXED,
1746 				 __svgalib_virtual_mem_fd,
1747 				 (int)__svgalib_graph_mem_orginal);
1748       if (__svgalib_graph_mem!=__svgalib_graph_mem_check)
1749           {
1750 	   printf("svgalib: mmap error in paged screen memory.\n");
1751 	   exit(-1);
1752 	  }
1753       if (__svgalib_modeinfo_linearset&IS_LINEAR)
1754           {
1755            __svgalib_linearframebuffer =
1756            (unsigned char *) mmap((caddr_t) __svgalib_linearframebuffer,
1757 	                         __svgalib_linear_memory_size,
1758 				 PROT_READ | PROT_WRITE,
1759 				 MAP_SHARED | MAP_FIXED,
1760 				 __svgalib_virtual_mem_fd,
1761 				 (int)__svgalib_graph_mem_linear_orginal);
1762            if (__svgalib_linearframebuffer!=__svgalib_graph_mem_linear_check)
1763               {
1764 	       printf("svgalib: mmap error in linear screen memory.\n");
1765 	       exit(-1);
1766 	      }
1767 	   __svgalib_linear_is_background=0;
1768 	  }
1769      }
1770    else
1771      {
1772       /*  Program is now in the background. */
1773       __svgalib_graph_mem =
1774           (unsigned char *) mmap((caddr_t) GM, GRAPH_SIZE,
1775 				 PROT_READ | PROT_WRITE,
1776 				 MAP_SHARED | MAP_FIXED,
1777 				 __svgalib_virtual_mem_fd,
1778 				 (int)(graph_buf+(GRAPH_SIZE*page)));
1779       if (__svgalib_graph_mem!=__svgalib_graph_mem_check)
1780           {
1781 	   printf("svgalib: mmap error in paged background memory.\n");
1782 	   exit(-1);
1783 	  }
1784       if (!__svgalib_linear_is_background &&
1785           __svgalib_modeinfo_linearset&IS_LINEAR)
1786           {
1787 #ifdef LINEAR_DEBUG
1788            dump_mem("testmaps-before");
1789            printf("svgalib: trying to map regular mem at %p, size=0x%08x from %p\n",
1790                   __svgalib_linearframebuffer,__svgalib_linear_memory_size,graph_buf2);
1791 #endif
1792            munmap(__svgalib_linearframebuffer,__svgalib_linear_memory_size);
1793 #ifdef LINEAR_DEBUG
1794            dump_mem("testmaps-after");
1795 #endif
1796     __svgalib_linearframebuffer =
1797            (unsigned char *) mmap((caddr_t) __svgalib_linearframebuffer,
1798 	                         __svgalib_linear_memory_size,
1799 				 PROT_READ | PROT_WRITE,
1800 				 MAP_SHARED | MAP_FIXED,
1801 				 __svgalib_virtual_mem_fd,
1802 				 (int)(graph_buf2));
1803            if (__svgalib_linearframebuffer!=__svgalib_graph_mem_linear_check)
1804               {
1805 	       printf("svgalib: mmap error in linear background memory.\n");
1806 	       exit(-1);
1807 	      }
1808 	   __svgalib_linear_is_background=1;
1809           }
1810      }
1811  return;
1812 }
1813 
1814 #endif
1815 #if BACKGROUND == 2
1816 
1817 #endif
1818 #endif
1819 
1820 
__vga_mmap(void)1821 static void __vga_mmap(void)
1822 {
1823 #ifdef LINEAR_DEBUG
1824     printf("__vga_mmap() called, __svgalib_graph_base=0x%08lx\n",__svgalib_graph_base);
1825 #endif
1826     /* This assumes pl10+. */
1827     /* Still seems to waste 64K, so don't bother. */
1828 #ifndef BACKGROUND
1829     GM = (unsigned char *) BANKED_MEM_POINTER;
1830 #endif
1831 #ifdef BACKGROUND
1832 #if BACKGROUND == 1
1833     if ((__svgalib_graph_mem = valloc(GRAPH_SIZE)) == NULL) {
1834 	printf("svgalib: allocation error \n");
1835 	exit(-1);
1836     }
1837     __svgalib_graph_mem_check=__svgalib_graph_mem;
1838     __svgalib_graph_mem_orginal = (unsigned char *) BANKED_MEM_POINTER;
1839     __svgalib_map_virtual_screen(1000000); /* Video page */
1840 #endif
1841 #if BACKGROUND == 2
1842     GM = (unsigned char *) BANKED_MEM_POINTER;
1843     __svgalib_graph_mem_orginal=GM;
1844 #endif
1845 #endif
1846 
1847 #ifdef __alpha__
1848     SM = (unsigned char *) mmap(
1849 				   (caddr_t) 0,
1850 				   GRAPH_SIZE << MEM_SHIFT,
1851 				   PROT_READ | PROT_WRITE,
1852 				   MAP_SHARED,
1853 				   __svgalib_mem_fd,
1854 				   SPARSE_GRAPH_BASE
1855 	);
1856 #endif
1857     graph_mem = __svgalib_graph_mem;	/* Exported variable. */
1858 }
1859 
__vga_atexit(void)1860 static void __vga_atexit(void)
1861 {
1862     if (getpid() == my_pid)	/* protect against forked processes */
1863 	restoretextmode();
1864     if (__svgalib_tty_fd >= 0 && startup_vc > 0)
1865 	    ioctl(__svgalib_tty_fd, VT_ACTIVATE, startup_vc);
1866 }
1867 
setcoloremulation(void)1868 static void setcoloremulation(void)
1869 {
1870     /* shift to color emulation */
1871     __svgalib_CRT_I = CRT_IC;
1872     __svgalib_CRT_D = CRT_DC;
1873     __svgalib_IS1_R = IS1_RC;
1874     if (CHIPSET != EGA && !__svgalib_novga)
1875 	port_out(port_in(MIS_R) | 0x01, MIS_W);
1876 }
1877 
initialize(void)1878 static void initialize(void)
1879 {
1880     int i;
1881     struct sigaction siga;
1882 
1883     __svgalib_open_devconsole();
1884     if (__svgalib_tty_fd < 0) {
1885 	exit(1);
1886     }
1887 
1888     /* Make sure that textmode is restored at exit(). */
1889     if (my_pid == 0)
1890 	my_pid = getpid();
1891     atexit(__vga_atexit);
1892 
1893 #ifndef DONT_WAIT_VC_ACTIVE
1894     __svgalib_waitvtactive();
1895 #endif
1896 
1897     /* save text mode termio parameters */
1898     ioctl(0, TIOCGETA, &text_termio);
1899 
1900     graph_termio = text_termio;
1901 
1902     /* change termio parameters to allow our own I/O processing */
1903     graph_termio.c_iflag &= ~(BRKINT | PARMRK | INPCK | IXON | IXOFF);
1904     graph_termio.c_iflag |= (IGNBRK | IGNPAR);
1905 
1906 /*    graph_termio.c_oflag &= ~(ONOCR);*/
1907 
1908     graph_termio.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | NOFLSH);
1909     if (__svgalib_nosigint)
1910 	graph_termio.c_lflag &= ~ISIG;	/* disable interrupt */
1911     else
1912 	graph_termio.c_lflag |=  ISIG;	/* enable interrupt */
1913 
1914     graph_termio.c_cc[VMIN] = 1;
1915     graph_termio.c_cc[VTIME] = 0;
1916     graph_termio.c_cc[VSUSP] = 0;	/* disable suspend */
1917 
1918     disable_interrupt();	/* Is reenabled later by set_texttermio */
1919 
1920     __svgalib_getchipset();		/* make sure a chipset has been selected */
1921     chipset_unlock();
1922 
1923     /* disable text output to console */
1924     if (!__svgalib_secondary)
1925 	ioctl(__svgalib_tty_fd, KDSETMODE, KD_GRAPHICS);
1926 
1927     __svgalib_takevtcontrol();	/* HH: Take control over VT */
1928 
1929     /* open /dev/mem */
1930     open_mem();
1931 
1932     /* mmap graphics memory */
1933     if(B8000_MEM_POINTER==NULL){
1934         if(__svgalib_banked_mem_base==0)__svgalib_banked_mem_base=0xa0000;
1935         if(__svgalib_banked_mem_size==0)__svgalib_banked_mem_size=0x10000;
1936                       BANKED_MEM_POINTER=mmap((caddr_t) 0,
1937 			                      __svgalib_banked_mem_size,
1938 				              PROT_READ | PROT_WRITE,
1939 				              MAP_SHARED,
1940 				              __svgalib_mem_fd,
1941 				              __svgalib_banked_mem_base
1942 
1943                       );
1944         if(__svgalib_linear_mem_size) {
1945                       LINEAR_MEM_POINTER=mmap((caddr_t) 0,
1946 				              __svgalib_linear_mem_size,
1947 			                      PROT_READ | PROT_WRITE,
1948                                               MAP_SHARED,
1949 				              __svgalib_mem_fd,
1950                                               (off_t) __svgalib_linear_mem_base
1951                       );
1952         };/* else LINEAR_MEM_POINTER=NULL;*/
1953 
1954         if(__svgalib_mmio_size)
1955                       MMIO_POINTER=mmap((caddr_t) 0,
1956 				       __svgalib_mmio_size,
1957 				       PROT_READ | PROT_WRITE,
1958 				       MAP_SHARED,
1959 				       __svgalib_mem_fd,
1960                                        (off_t) __svgalib_mmio_base
1961                       ); else MMIO_POINTER=NULL;
1962 
1963         B8000_MEM_POINTER=mmap((caddr_t) 0,
1964        			        32768,
1965 			        PROT_READ | PROT_WRITE,
1966                                 MAP_SHARED,
1967                                 __svgalib_mem_fd,
1968                                 (off_t) 0xb8000);
1969     };
1970     __vga_mmap();
1971 
1972     if ((long) GM < 0) {
1973 	printf("svgalib: mmap error rrr\n");
1974 	exit(1);
1975     }
1976     /* disable video */
1977     vga_screenoff();
1978 
1979     /* Sanity check: (from painful experience) */
1980 
1981     i = __svgalib_saveregs(text_regs);
1982     if (i > MAX_REGS) {
1983 	puts("svgalib: FATAL internal error:");
1984 	printf("Set MAX_REGS at least to %d in src/driver.h and recompile everything.\n",
1985 	       i);
1986 	exit(1);
1987     }
1988     /* This appears to fix the Trident 8900 rebooting problem. */
1989     if (__svgalib_chipset == TVGA8900) {
1990 	port_out(0x0c, SEQ_I);	/* reg 12 */
1991 	text_regs[EXT + 11] = port_in(SEQ_D);
1992 	port_out(0x1f, __svgalib_CRT_I);
1993 	text_regs[EXT + 12] = port_in(__svgalib_CRT_D);
1994     }
1995     /* save text mode palette - first select palette index 0 */
1996     if(!__svgalib_novga)
1997 	port_out(0, PEL_IR);
1998 
1999     /* read RGB components - index is autoincremented */
2000     savepalette(text_red, text_green, text_blue);
2001 
2002     /* shift to color emulation */
2003     setcoloremulation();
2004 
2005     /* save font data - first select a 16 color graphics mode */
2006     if (__svgalib_driverspecs->emul && __svgalib_driverspecs->emul->savefont) {
2007 	 __svgalib_driverspecs->emul->savefont();
2008     } else if(!__svgalib_novga) {
2009         __svgalib_driverspecs->setmode(GPLANE16, prv_mode);
2010         save_text();
2011 
2012         /* Allocate space for textmode font. */
2013 #ifndef BACKGROUND
2014         font_buf1 = malloc(FONT_SIZE * 2);
2015 #endif
2016 #ifdef BACKGROUND
2017         font_buf1 = valloc(FONT_SIZE * 2);
2018 #endif
2019         font_buf2 = font_buf1 + FONT_SIZE;
2020 
2021     /* save font data in plane 2 */
2022         port_out(0x04, GRA_I);
2023         port_out(0x02, GRA_D);
2024 #ifdef __alpha__
2025         port_out(0x06, GRA_I);
2026         port_out(0x00, GRA_D);
2027 #endif
2028 #if defined(CONFIG_ALPHA_JENSEN)
2029         slowcpy_from_sm(font_buf1, SM, FONT_SIZE);
2030 #else
2031         slowcpy(font_buf1, GM, FONT_SIZE);
2032 #endif
2033 
2034         /* save font data in plane 3 */
2035         port_out(0x04, GRA_I);
2036         port_out(0x03, GRA_D);
2037 #if defined(CONFIG_ALPHA_JENSEN)
2038         slowcpy_from_sm(font_buf2, SM, FONT_SIZE);
2039 #else
2040         slowcpy(font_buf2, GM, FONT_SIZE);
2041 #endif
2042 
2043 #ifdef BACKGROUND
2044         /* Let's protect font. */
2045         /* Read only */
2046         if (-1 == mprotect(font_buf1,FONT_SIZE*2,PROT_READ))
2047             {
2048 	     printf("svgalib: Memory protect error\n");
2049 	     exit(-1);
2050 	    }
2051 #endif
2052     }
2053     initialized = 1;
2054 
2055     /* do our own interrupt handling */
2056     for (i = 0; i < sizeof(sig2catch); i++) {
2057 	siga.sa_handler = signal_handler;
2058 	siga.sa_flags = 0;
2059 	zero_sa_mask(&(siga.sa_mask));
2060 	sigaction((int) sig2catch[i], &siga, old_signal_handler + i);
2061     }
2062 
2063     /* vga_unlockvc(); */
2064 }
2065 
2066 #ifndef BACKGROUND
2067 
vga_setpage(int p)2068 inline void vga_setpage(int p)
2069 {
2070     p += vga_page_offset;
2071     if (p == __svgalib_currentpage && !__svgalib_simple)
2072 	return;
2073     (*__svgalib_setpage) (p);
2074     __svgalib_currentpage = p;
2075 }
2076 
2077 
vga_setreadpage(int p)2078 void vga_setreadpage(int p)
2079 {
2080     p += vga_page_offset;
2081     if (p == __svgalib_currentpage)
2082 	return;
2083     (*__svgalib_setrdpage) (p);
2084     __svgalib_currentpage = -1;
2085 }
2086 
2087 
vga_setwritepage(int p)2088 void vga_setwritepage(int p)
2089 {
2090     p += vga_page_offset;
2091     if (p == __svgalib_currentpage)
2092 	return;
2093     (*__svgalib_setwrpage) (p);
2094     __svgalib_currentpage = -1;
2095 }
2096 
2097 #endif
2098 
vga_safety_fork(void (* shutdown_routine)(void))2099 void vga_safety_fork(void (*shutdown_routine) (void))
2100 {
2101     pid_t childpid;
2102     int child_status, oldkbmode;
2103 
2104     if (initialized) {
2105 	printf("svgalib: warning: vga_safety_fork() called when already initialized\n");
2106 	goto no_fork;
2107     }
2108     initialize();
2109 
2110     /*
2111      * get current keyboard mode:
2112      *  If this didn't suffice we claim we are on an old system and just don't
2113      *  need to restore it.
2114      */
2115     ioctl(__svgalib_tty_fd, KDGKBMODE, &oldkbmode);
2116 
2117     childpid = fork();
2118     if (childpid < 0) {
2119       no_fork:
2120 	printf("svgalib: warning: can't fork to enhance reliability; proceeding anyway");
2121 	return;
2122     }
2123     if (childpid) {
2124 	ioctl(__svgalib_tty_fd, (int) TIOCNOTTY, (char *)0);
2125 	for (;;) {
2126 	    while (waitpid(childpid, &child_status, WUNTRACED) != childpid);
2127 
2128 	    if (shutdown_routine)
2129 		shutdown_routine();
2130 
2131 	    vga_setmode(TEXT);	/* resets termios as well */
2132 	    ioctl(__svgalib_tty_fd, KDSKBMODE, oldkbmode);
2133 
2134 	    if (WIFEXITED(child_status))
2135 		exit(WEXITSTATUS(child_status));
2136 
2137 	    if (WCOREDUMP(child_status))
2138 		puts("svgalib:vga_safety_fork: Core dumped!");
2139 
2140 	    if (WIFSIGNALED(child_status)) {
2141 		printf("svgalib:vga_safety_fork: Killed by signal %d, %s.\n",
2142 		       WTERMSIG(child_status),
2143 		       strsignal(WTERMSIG(child_status)));
2144 		exit(1);
2145 	    }
2146 	    if (WIFSTOPPED(child_status)) {
2147 		printf("svgalib:vga_safety_fork: Stopped by signal %d, %s.\n",
2148 		       WSTOPSIG(child_status),
2149 		       strsignal(WSTOPSIG(child_status)));
2150 		puts("\aWARNING! Continue stopped svgalib application at own risk. You are better\n"
2151 		     "off killing it NOW!");
2152 		continue;
2153 	    }
2154 	}
2155     }
2156     /* These need to be done again because the child doesn't inherit them.  */
2157     __svgalib_get_perm();
2158 
2159 #ifdef BACKGROUND
2160     if (__svgalib_virtual_mem_fd>0)close(__svgalib_virtual_mem_fd);
2161     {
2162     char tmp[50];
2163     __svgalib_processnumber=getpid();
2164     sprintf(tmp,"/proc/%d/mem",__svgalib_processnumber);
2165     if ((__svgalib_virtual_mem_fd = open(tmp,O_RDWR)) < 0)
2166        {
2167           printf("svgalib: Cannot open /proc/%d/mem.\n",
2168 	         __svgalib_processnumber);
2169           exit(-1);
2170        }
2171     };
2172 #endif
2173     /*
2174      * But alas. That doesn't suffice. We raise the iopl here what merely makes
2175      * the previous call pointless.
2176      *
2177      * If IOPERM is set, assume permissions have already been set by Olaf Titz'
2178      * ioperm(1).
2179      */
2180 
2181     if (CHIPSET != FBDEV && getenv("IOPERM") == NULL) {
2182 	if (iopl(3) < 0) {
2183 	    printf("svgalib(vga_safety_fork): Cannot get I/O permissions.\n");
2184 	    exit(1);
2185 	}
2186     }
2187     /*
2188      * Actually the mmap's are inherited anyway (and not all are remade here),
2189      * but it does not really harm.
2190      */
2191 #ifdef BACKGROUND
2192     /*
2193      *  __vga_mmap() call is now really dangerous. You can only call
2194      *  mmap once. Once virtual screen has been allocated its better
2195      *  stay in one place. At least for now. Anyway this works now.
2196      */
2197 #else
2198     __vga_mmap();
2199 #endif
2200 
2201 
2202     /*
2203      * We might still want to do vc switches.
2204      */
2205 
2206     __svgalib_takevtcontrol();
2207 }
2208 
prepareforfontloading(void)2209 static void prepareforfontloading(void)
2210 {
2211     if (__svgalib_chipset == CIRRUS) {
2212 	outb(SEQ_I, 0x0f);
2213 	/* Disable CRT FIFO Fast-Page mode. */
2214 	outb(SEQ_D, inb(SEQ_D) | 0x40);
2215     }
2216 }
2217 
fontloadingcomplete(void)2218 static void fontloadingcomplete(void)
2219 {
2220     if (__svgalib_chipset == CIRRUS) {
2221 	outb(SEQ_I, 0x0f);
2222 	/* Re-enable CRT FIFO Fast-Page mode. */
2223 	outb(SEQ_D, inb(SEQ_D) & 0xbf);
2224     }
2225 }
2226 
2227 
vga_setmode(int mode)2228 int vga_setmode(int mode)
2229 {
2230     int modeflags=mode&0xfffff000;
2231 
2232     if(mode==-1)return vga_version;
2233 
2234     mode&=0xfff;
2235 #ifdef BACKGROUND
2236     __svgalib_dont_switch_vt_yet();
2237     /* Can't initialize if screen is flipped. */
2238     if (__svgalib_oktowrite)
2239 #endif
2240     if (!initialized)
2241 	initialize();
2242 
2243     if (mode != TEXT && !chipset_modeavailable(mode))
2244        {
2245 #ifdef BACKGROUND
2246          __svgalib_is_vt_switching_needed();
2247 #endif
2248 	return -1;
2249        }
2250 
2251 #ifdef BACKGROUND
2252     if (!__svgalib_oktowrite)
2253         {
2254 	 prv_mode=CM;
2255 	 CM=mode;
2256 	 vga_setpage(0);
2257 	 __svgalib_is_vt_switching_needed();
2258 	 return(0);
2259 	 /* propably this was enough. */
2260 	 /* hmm.. there... virtual screen... */
2261 	}
2262 #endif
2263 
2264 /*    if (!flip)
2265    vga_lockvc(); */
2266     disable_interrupt();
2267 
2268     prv_mode = CM;
2269     CM = mode;
2270 
2271     /* disable video */
2272     vga_screenoff();
2273 
2274     if(!__svgalib_novga) {
2275     /* Should be more robust (eg. grabbed X modes) */
2276 	if (__svgalib_getchipset() == ET4000
2277 	     && prv_mode != G640x480x256
2278 	     && SVGAMODE(prv_mode))
2279 	    chipset_setmode(G640x480x256, prv_mode);
2280 
2281 	/* This is a hack to get around the fact that some C&T chips
2282 	 * are programmed to ignore syncronous resets. So if we are
2283 	 * a C&T wait for retrace start
2284 	 */
2285 	if (__svgalib_getchipset() == CHIPS) {
2286 	   while (((port_in(__svgalib_IS1_R)) & 0x08) == 0x08 );/* wait VSync off */
2287 	   while (((port_in(__svgalib_IS1_R)) & 0x08) == 0 );   /* wait VSync on  */
2288 	   port_outw(0x07,SEQ_I);         /* reset hsync - just in case...  */
2289 	}
2290     }
2291 
2292     if (mode == TEXT) {
2293 	/* Returning to textmode. */
2294 
2295 	if (SVGAMODE(prv_mode))
2296 	    vga_setpage(0);
2297 
2298 	/* The extended registers are restored either by the */
2299 	/* chipset setregs function, or the chipset setmode function. */
2300 
2301 	/* restore font data - first select a 16 color graphics mode */
2302 	/* Note: this should restore the old extended registers if */
2303 	/* setregs is not defined for the chipset. */
2304         if(__svgalib_novga) __svgalib_driverspecs->setmode(TEXT, prv_mode);
2305         if (__svgalib_driverspecs->emul && __svgalib_driverspecs->emul->restorefont) {
2306            __svgalib_driverspecs->emul->restorefont();
2307 	   chipset_setregs(text_regs, mode);
2308         } else if(!__svgalib_novga) {
2309 	  __svgalib_driverspecs->setmode(GPLANE16, prv_mode);
2310 
2311 	  if (CHIPSET != EGA)
2312 	      /* restore old extended regs */
2313 	      chipset_setregs(text_regs, mode);
2314 
2315 	  /* disable Set/Reset Register */
2316 	  port_out(0x01, GRA_I);
2317 	  port_out(0x00, GRA_D);
2318 
2319 	  prepareforfontloading();
2320           restore_text();
2321 
2322 	  /* restore font data in plane 2 - necessary for all VGA's */
2323 	  port_out(0x02, SEQ_I);
2324 	  port_out(0x04, SEQ_D);
2325 #ifdef __alpha__
2326 	  port_out(0x06, GRA_I);
2327 	  port_out(0x00, GRA_D);
2328 #endif
2329 
2330 #ifdef BACKGROUND
2331           if (-1 == mprotect(font_buf1,FONT_SIZE*2,PROT_READ|PROT_WRITE))
2332           {
2333 	   printf("svgalib: Memory protect error\n");
2334 	   exit(-1);
2335 	  }
2336 #endif
2337 
2338 #if defined(CONFIG_ALPHA_JENSEN)
2339 	  slowcpy_to_sm(SM, font_buf1, FONT_SIZE);
2340 #else
2341 	  slowcpy(GM, font_buf1, FONT_SIZE);
2342 #endif
2343 
2344 	  /* restore font data in plane 3 - necessary for Trident VGA's */
2345 	  port_out(0x02, SEQ_I);
2346 	  port_out(0x08, SEQ_D);
2347 #if defined(CONFIG_ALPHA_JENSEN)
2348 	  slowcpy_to_sm(SM, font_buf2, FONT_SIZE);
2349 #else
2350 	  slowcpy(GM, font_buf2, FONT_SIZE);
2351 #endif
2352 #ifdef BACKGROUND
2353           if (-1 == mprotect(font_buf1,FONT_SIZE*2,PROT_READ))
2354           {
2355 	   printf("svgalib: Memory protect error\n");
2356 	   exit(1);
2357 	  }
2358 #endif
2359 	  fontloadingcomplete();
2360 
2361 	  /* change register adresses if monochrome text mode */
2362 	  /* EGA is assumed to use color emulation. */
2363 	  if (!color_text) {
2364 	      __svgalib_CRT_I = CRT_IM;
2365 	      __svgalib_CRT_D = CRT_DM;
2366 	      __svgalib_IS1_R = IS1_RM;
2367 	      port_out(port_in(MIS_R) & 0xFE, MIS_W);
2368 	  }
2369         } else chipset_setregs(text_regs, mode);
2370 	/* restore saved palette */
2371 	restorepalette(text_red, text_green, text_blue);
2372 
2373 	/* restore text mode VGA registers */
2374 	__svgalib_setregs(text_regs);
2375 
2376 	/* Set VMEM to some minimum value .. probably pointless.. */
2377 	{
2378 	    vga_claimvideomemory(12);
2379 	}
2380 
2381 /*      if (!flip) */
2382 	/* enable text output - restores the screen contents */
2383         if (!__svgalib_secondary)
2384 	    ioctl(__svgalib_tty_fd, KDSETMODE, KD_TEXT);
2385 
2386         /* now wait for signal to stabilize, but don't do it on C&T chips. */
2387         /* This is needed to restore correct text mode stretching.         */
2388 	if (__svgalib_chipset != CHIPS)
2389 	    usleep(MODESWITCHDELAY);
2390 
2391 	/* enable video */
2392 	vga_screenon();
2393 
2394 	if (!flip)
2395 	    /* restore text mode termio */
2396 	    set_texttermio();
2397     } else {
2398 	/* Setting a graphics mode. */
2399 
2400 	/* disable text output */
2401         if (!__svgalib_secondary)
2402 	    ioctl(__svgalib_tty_fd, KDSETMODE, KD_GRAPHICS);
2403 
2404 	if (SVGAMODE(prv_mode)) {
2405 	    /* The current mode is an SVGA mode, and we now want to */
2406 	    /* set a standard VGA mode. Make sure the extended regs */
2407 	    /* are restored. */
2408 	    /* Also used when setting another SVGA mode to hopefully */
2409 	    /* eliminate lock-ups. */
2410 	    vga_setpage(0);
2411 	    chipset_setregs(text_regs, mode);
2412 	    /* restore old extended regs */
2413 	}
2414 	/* shift to color emulation */
2415 	setcoloremulation();
2416 
2417 	CI.xdim = infotable[mode].xdim;
2418 	CI.ydim = infotable[mode].ydim;
2419 	CI.colors = infotable[mode].colors;
2420 	CI.xbytes = infotable[mode].xbytes;
2421 	CI.bytesperpixel = infotable[mode].bytesperpixel;
2422 
2423 	chipset_setmode(mode, prv_mode);
2424 	MODEX = 0;
2425 
2426 	/* Set default claimed memory (moved here from initialize - Michael.) */
2427 	if (mode == G320x200x256)
2428 	    VMEM = 65536;
2429 	else if (STDVGAMODE(mode))
2430 	    VMEM = 256 * 1024;	/* Why always 256K ??? - Michael */
2431 	else {
2432 	    vga_modeinfo *modeinfo;
2433 
2434 	    modeinfo = vga_getmodeinfo(mode);
2435 	    VMEM = modeinfo->linewidth * modeinfo->height;
2436             CI.xbytes = modeinfo->linewidth;
2437 	}
2438 
2439 	if (!flip) {
2440 	    /* set default palette */
2441 	    if (CI.colors <= 256)
2442 		restorepalette(default_red, default_green, default_blue);
2443 
2444 	    /* clear screen (sets current color to 15) */
2445 	    __svgalib_currentpage = -1;
2446             if(!(modeflags&0x8000))vga_clear();
2447 
2448 	    if (SVGAMODE(__svgalib_cur_mode))
2449 		vga_setpage(0);
2450 	}
2451 	__svgalib_currentpage = -1;
2452 	currentlogicalwidth = CI.xbytes;
2453 	currentdisplaystart = 0;
2454 
2455 	usleep(MODESWITCHDELAY);	/* wait for signal to stabilize */
2456 
2457 	/* enable video */
2458 	if (!flip)
2459 	    vga_screenon();
2460 
2461 	if (mouse_support && mouse_open) {
2462 		/* vga_lockvc(); */
2463 		mouse_setxrange(0, CI.xdim - 1);
2464 		mouse_setyrange(0, CI.ydim - 1);
2465 		mouse_setwrap(MOUSE_NOWRAP);
2466 		mouse_mode = mode;
2467 	} {
2468 	    vga_modeinfo *modeinfo;
2469 	    modeinfo = vga_getmodeinfo(mode);
2470 	    MODEX = ((MODEFLAGS = modeinfo->flags) & IS_MODEX);
2471 	}
2472 
2473 	if (!flip)
2474 	    /* set graphics mode termio */
2475 	    set_graphtermio();
2476 	else if (__svgalib_kbd_fd < 0)
2477 	    enable_interrupt();
2478     }
2479 
2480 /*    if (!flip)
2481    vga_unlockvc(); */
2482 #ifdef BACKGROUND
2483  __svgalib_is_vt_switching_needed();
2484 #endif
2485     return 0;
2486 }
2487 
vga_gettextfont(void * font)2488 void vga_gettextfont(void *font)
2489 {
2490     unsigned int getsize;
2491 
2492     getsize = fontbufsize;
2493     if (getsize > FONT_SIZE)
2494 	getsize = FONT_SIZE;
2495     memcpy(font, font_buf1, getsize);
2496     if (fontbufsize > getsize)
2497 	memset(((char *)font) + getsize, 0, (size_t)(fontbufsize - getsize));
2498 }
2499 
vga_puttextfont(void * font)2500 void vga_puttextfont(void *font)
2501 {
2502     unsigned int putsize;
2503 
2504 #ifdef BACKGROUND
2505         if (-1 == mprotect(font_buf1,FONT_SIZE*2,PROT_READ|PROT_WRITE))
2506         {
2507 	 printf("svgalib: Memory protect error\n");
2508 	 exit(-1);
2509 	}
2510 #endif
2511 
2512     putsize = fontbufsize;
2513     if (putsize > FONT_SIZE)
2514 	putsize = FONT_SIZE;
2515     memcpy(font_buf1, font, putsize);
2516     memcpy(font_buf2, font, putsize);
2517     if (putsize < FONT_SIZE) {
2518 	memset(font_buf1 + putsize, 0, (size_t)(FONT_SIZE - putsize));
2519 	memset(font_buf2 + putsize, 0, (size_t)(FONT_SIZE - putsize));
2520     }
2521 
2522 #ifdef BACKGROUND
2523         if (-1 == mprotect(font_buf1,FONT_SIZE*2,PROT_READ))
2524         {
2525 	 printf("svgalib: Memory protect error\n");
2526 	 exit(-1);
2527 	}
2528 #endif
2529 }
2530 
vga_gettextmoderegs(void * regs)2531 void vga_gettextmoderegs(void *regs)
2532 {
2533     memcpy(regs, text_regs, MAX_REGS);
2534 }
2535 
vga_settextmoderegs(void * regs)2536 void vga_settextmoderegs(void *regs)
2537 {
2538     memcpy(text_regs, regs, MAX_REGS);
2539 }
2540 
vga_getcurrentmode(void)2541 int vga_getcurrentmode(void)
2542 {
2543     return CM;
2544 }
2545 
vga_getcurrentchipset(void)2546 int vga_getcurrentchipset(void)
2547 {
2548     return __svgalib_getchipset();
2549 }
2550 
vga_disabledriverreport(void)2551 void vga_disabledriverreport(void)
2552 {
2553     DREP = 0;
2554 }
2555 
vga_getmodeinfo(int mode)2556 vga_modeinfo *vga_getmodeinfo(int mode)
2557 {
2558     static vga_modeinfo modeinfo;
2559     int is_modeX = (CM == mode) && MODEX;
2560 
2561     modeinfo.linewidth = infotable[mode].xbytes;
2562     __svgalib_getchipset();
2563     if (mode > vga_lastmodenumber())
2564 	return NULL;
2565     modeinfo.width = infotable[mode].xdim;
2566     modeinfo.height = infotable[mode].ydim;
2567     modeinfo.bytesperpixel = infotable[mode].bytesperpixel;
2568     modeinfo.colors = infotable[mode].colors;
2569     if (is_modeX) {
2570 	modeinfo.linewidth = modeinfo.width / 4;
2571 	modeinfo.bytesperpixel = 0;
2572     }
2573     if (mode == TEXT) {
2574 	modeinfo.flags = HAVE_EXT_SET;
2575 	return &modeinfo;
2576     }
2577     modeinfo.flags = 0;
2578     if ((STDVGAMODE(mode) && mode != G320x200x256) || is_modeX)
2579 	__svgalib_vga_driverspecs.getmodeinfo(mode, &modeinfo);
2580     else
2581 	/* Get chipset specific info for SVGA modes and */
2582 	/* 320x200x256 (chipsets may support more pages) */
2583 	chipset_getmodeinfo(mode, &modeinfo);
2584 
2585     if (modeinfo.colors == 256 && modeinfo.bytesperpixel == 0)
2586 	modeinfo.flags |= IS_MODEX;
2587     if (mode > __GLASTMODE)
2588 	modeinfo.flags |= IS_DYNAMICMODE;
2589 
2590     /* Maskout CAPABLE_LINEAR if requested by config file */
2591     modeinfo.flags &= modeinfo_mask;
2592 
2593     /* Many cards have problems with linear 320x200x256 mode */
2594     if(mode==G320x200x256)modeinfo.flags &= (~CAPABLE_LINEAR) & (~IS_LINEAR) ;
2595 
2596     /* If all needed info is here, signal if linear support has been enabled */
2597     if ((modeinfo.flags & (CAPABLE_LINEAR | EXT_INFO_AVAILABLE)) ==
2598 	(CAPABLE_LINEAR | EXT_INFO_AVAILABLE)) {
2599 	modeinfo.flags |= __svgalib_modeinfo_linearset;
2600     }
2601 
2602 #ifdef BACKGROUND
2603 #if 0 /* vga_set[rw]page() don't work if compile for background, even when in foreground. */
2604     if (__svgalib_runinbackground) /* these cannot be provided if we are really in background */
2605 #endif
2606 	modeinfo.flags &= ~HAVE_RWPAGE;
2607 #endif
2608 
2609     return &modeinfo;
2610 }
2611 
vga_hasmode(int mode)2612 int vga_hasmode(int mode)
2613 {
2614     __svgalib_getchipset();		/* Make sure the chipset is known. */
2615     if (mode == TEXT)
2616 	return 1;
2617     if (mode < 0 || mode > lastmodenumber)
2618 	return 0;
2619     return (chipset_modeavailable(mode) != 0);
2620 }
2621 
2622 
vga_lastmodenumber(void)2623 int vga_lastmodenumber(void)
2624 {
2625     __svgalib_getchipset();
2626     return lastmodenumber;
2627 }
2628 
2629 
__svgalib_addmode(int xdim,int ydim,int cols,int xbytes,int bytespp)2630 int __svgalib_addmode(int xdim, int ydim, int cols, int xbytes, int bytespp)
2631 {
2632     int i;
2633 
2634     for (i = 0; i <= lastmodenumber; ++i)
2635 	if (infotable[i].xdim == xdim &&
2636 	    infotable[i].ydim == ydim &&
2637 	    infotable[i].colors == cols &&
2638 	    infotable[i].bytesperpixel == bytespp &&
2639 	    infotable[i].xbytes == xbytes)
2640 	    return i;
2641     if (lastmodenumber >= MAX_MODES - 1)
2642 	return -1;		/* no more space available */
2643     ++lastmodenumber;
2644     infotable[lastmodenumber].xdim = xdim;
2645     infotable[lastmodenumber].ydim = ydim;
2646     infotable[lastmodenumber].colors = cols;
2647     infotable[lastmodenumber].xbytes = xbytes;
2648     infotable[lastmodenumber].bytesperpixel = bytespp;
2649 
2650     return lastmodenumber;
2651 }
2652 
vga_getcrtcregs(unsigned char * regs)2653 int vga_getcrtcregs(unsigned char *regs) {
2654     int i;
2655 
2656     for (i = 0; i < CRT_C; i++) {
2657         regs[i] = __svgalib_incrtc(i);
2658     }
2659     return 0;
2660 }
2661 
vga_setcrtcregs(unsigned char * regs)2662 int vga_setcrtcregs(unsigned char *regs) {
2663     int i;
2664 
2665     if(CM>9) return -1;
2666 
2667     __svgalib_outcrtc(0x11,__svgalib_incrtc(0x11)&0x7f);
2668     for (i = 0; i < CRT_C; i++) {
2669         __svgalib_outcrtc(i,regs[i]);
2670     }
2671 
2672     return 0;
2673 }
2674 
vga_setcolor(int color)2675 int vga_setcolor(int color)
2676 {
2677     switch (CI.colors) {
2678     case 2:
2679 	if (color != 0)
2680 	    color = 15;
2681     case 16:			/* update set/reset register */
2682 #ifdef BACKGROUND
2683         __svgalib_dont_switch_vt_yet();
2684         if (!__svgalib_oktowrite)
2685            {
2686             color=color & 15;
2687             COL = color;
2688            }
2689 	 else
2690 	   {
2691 #endif
2692 	port_out(0x00, GRA_I);
2693 	port_out((color & 15), GRA_D);
2694 #ifdef BACKGROUND
2695            }
2696         __svgalib_is_vt_switching_needed();
2697 #endif
2698 	break;
2699     default:
2700 	COL = color;
2701 	break;
2702     }
2703     return 0;
2704 }
2705 
2706 
vga_screenoff(void)2707 int vga_screenoff(void)
2708 {
2709     int tmp = 0;
2710 
2711     SCREENON = 0;
2712 
2713     if(__svgalib_novga) return 0;
2714 #ifdef BACKGROUND
2715     __svgalib_dont_switch_vt_yet();
2716     if (!__svgalib_oktowrite) {
2717 	__svgalib_is_vt_switching_needed();
2718 	return(0);
2719     }
2720 #endif
2721 
2722     if (__svgalib_driverspecs->emul && __svgalib_driverspecs->emul->screenoff) {
2723 	tmp = __svgalib_driverspecs->emul->screenoff();
2724     } else {
2725 	/* turn off screen for faster VGA memory acces */
2726 	if (CHIPSET != EGA) {
2727 	    port_out(0x01, SEQ_I);
2728 	    port_out(port_in(SEQ_D) | 0x20, SEQ_D);
2729 	}
2730 	/* Disable video output */
2731 #ifdef DISABLE_VIDEO_OUTPUT
2732 	port_in(__svgalib_IS1_R);
2733 	__svgalib_delay();
2734 	port_out(0x00, ATT_IW);
2735 #endif
2736     }
2737 
2738 #ifdef BACKGROUND
2739     __svgalib_is_vt_switching_needed();
2740 #endif
2741     return tmp;
2742 }
2743 
2744 
vga_screenon(void)2745 int vga_screenon(void)
2746 {
2747     int tmp = 0;
2748 
2749     SCREENON = 1;
2750     if(__svgalib_novga) return 0;
2751 #ifdef BACKGROUND
2752     __svgalib_dont_switch_vt_yet();
2753     if (!__svgalib_oktowrite) {
2754 	__svgalib_is_vt_switching_needed();
2755 	return(0);
2756     }
2757 #endif
2758     if (__svgalib_driverspecs->emul && __svgalib_driverspecs->emul->screenon) {
2759 	tmp = __svgalib_driverspecs->emul->screenon();
2760     } else {
2761 	/* turn screen back on */
2762 	if (CHIPSET != EGA) {
2763 	    port_out(0x01, SEQ_I);
2764 	    port_out(port_in(SEQ_D) & 0xDF, SEQ_D);
2765 	}
2766 /* #ifdef DISABLE_VIDEO_OUTPUT */
2767 	/* enable video output */
2768 	port_in(__svgalib_IS1_R);
2769 	__svgalib_delay();
2770 	port_out(0x20, ATT_IW);
2771 /* #endif */
2772     }
2773 
2774 #ifdef BACKGROUND
2775     __svgalib_is_vt_switching_needed();
2776 #endif
2777     return 0;
2778 }
2779 
2780 
vga_getxdim(void)2781 int vga_getxdim(void)
2782 {
2783     return CI.xdim;
2784 }
2785 
2786 
vga_getydim(void)2787 int vga_getydim(void)
2788 {
2789     return CI.ydim;
2790 }
2791 
2792 
vga_getcolors(void)2793 int vga_getcolors(void)
2794 {
2795     return CI.colors;
2796 }
2797 
vga_white(void)2798 int vga_white(void)
2799 {
2800     switch (CI.colors) {
2801     case 2:
2802     case 16:
2803     case 256:
2804 	return 15;
2805     case 1 << 15:
2806 	return 32767;
2807     case 1 << 16:
2808 	return 65535;
2809     case 1 << 24:
2810 	return (1 << 24) - 1;
2811     }
2812     return CI.colors - 1;
2813 }
2814 
vga_claimvideomemory(int m)2815 int vga_claimvideomemory(int m)
2816 {
2817     vga_modeinfo *modeinfo;
2818     int cardmemory;
2819 
2820     modeinfo = vga_getmodeinfo(CM);
2821     if (m < VMEM)
2822 	return 0;
2823     if (modeinfo->colors == 16)
2824 	cardmemory = modeinfo->maxpixels / 2;
2825     else
2826 	cardmemory = (modeinfo->maxpixels * modeinfo->bytesperpixel
2827 		      + 2) & 0xffff0000;
2828     /* maxpixels * bytesperpixel can be 2 less than video memory in */
2829     /* 3 byte-per-pixel modes; assume memory is multiple of 64K */
2830     if (m > cardmemory)
2831 	return -1;
2832     VMEM = m;
2833     return 0;
2834 }
2835 
vga_setmodeX(void)2836 int vga_setmodeX(void)
2837 {
2838     switch (CM) {
2839     case TEXT:
2840 /*    case G320x200x256: */
2841     case G320x240x256:
2842     case G320x400x256:
2843     case G360x480x256:
2844 	return 0;
2845     }
2846     if (CI.colors == 256 && VMEM < 256 * 1024) {
2847 	port_out(4, SEQ_I);	/* switch from linear to plane memory */
2848 	port_out((port_in(SEQ_D) & 0xF7) | 0x04, SEQ_D);
2849 	port_out(0x14, __svgalib_CRT_I);	/* switch double word mode off */
2850 	port_out((port_in(__svgalib_CRT_D) & 0xBF), __svgalib_CRT_D);
2851 	port_out(0x17, __svgalib_CRT_I);
2852 	port_out((port_in(__svgalib_CRT_D) | 0x40), __svgalib_CRT_D);
2853 	CI.xbytes = CI.xdim / 4;
2854 	vga_setpage(0);
2855 	MODEX = 1;
2856 	return 1;
2857     }
2858     return 0;
2859 }
2860 
2861 
2862 static int saved_page;
2863 static int saved_logicalwidth;
2864 static int saved_displaystart;
2865 static int saved_modeX;
2866 #ifdef BACKGROUND
2867 static int saved_linearset;
2868 #endif
2869 
savestate(void)2870 static void savestate(void)
2871 {
2872     int i;
2873 
2874     vga_screenoff();
2875 
2876     savepalette(graph_red, graph_green, graph_blue);
2877 
2878     saved_page = __svgalib_currentpage;
2879     saved_logicalwidth = currentlogicalwidth;
2880     saved_displaystart = currentdisplaystart;
2881     saved_modeX = MODEX;
2882 #ifdef BACKGROUND
2883     saved_linearset = __svgalib_modeinfo_linearset;
2884 #endif
2885 
2886     if (CM == G320x200x256 && VMEM <= 65536) {
2887 #ifndef BACKGROUND
2888 	/* 320x200x256 is a special case; only 64K is addressable */
2889 	/* (unless more has been claimed, in which case we assume */
2890 	/* SVGA bank-switching) */
2891 	if ((graph_buf = malloc(GRAPH_SIZE)) == NULL) {
2892 #endif
2893 #ifdef BACKGROUND
2894 #if BACKGROUND == 1
2895         if ((graph_buf = valloc(GRAPH_SIZE)) == NULL)
2896 	    {
2897 #endif
2898 #if BACKGROUND == 2
2899 	if ((graph_buf = malloc(GRAPH_SIZE)) == NULL) {
2900 #endif
2901 #endif
2902 	    printf("Cannot allocate memory for VGA state\n");
2903 	    vga_setmode(TEXT);
2904 	    exit(1);
2905 	}
2906 	memcpy(graph_buf, GM, GRAPH_SIZE);
2907     } else if (MODEX || CM == G800x600x16 || (STDVGAMODE(CM) && CM != G320x200x256)) {
2908 	/* for planar VGA modes, save the full 256K */
2909 	__svgalib_vga_driverspecs.setmode(GPLANE16, prv_mode);
2910 #ifndef BACKGROUND
2911 	if ((graph_buf = malloc(4 * GRAPH_SIZE)) == NULL) {
2912 #endif
2913 #ifdef BACKGROUND
2914 #if BACKGROUND == 1
2915         if ((graph_buf = valloc(4 * GRAPH_SIZE)) == NULL)
2916 	    {
2917 #endif
2918 #if BACKGROUND == 2
2919         if ((graph_buf = malloc(4 * GRAPH_SIZE)) == NULL) {
2920 #endif
2921 #endif
2922 	    printf("Cannot allocate memory for VGA state\n");
2923 	    vga_setmode(TEXT);
2924 	    exit(1);
2925 	}
2926 	for (i = 0; i < 4; i++) {
2927 	    /* save plane i */
2928 	    port_out(0x04, GRA_I);
2929 	    port_out(i, GRA_D);
2930 	    memcpy(graph_buf + i * GRAPH_SIZE, GM, GRAPH_SIZE);
2931 	}
2932     } else if (CI.colors == 16) {
2933 	int page, size, sbytes;
2934 	unsigned char *sp;
2935 
2936 	size = VMEM;
2937 #ifndef BACKGROUND
2938 	if ((graph_buf = malloc(4 * size)) == NULL) {
2939 #endif
2940 #ifdef BACKGROUND
2941 #if BACKGROUND == 1
2942 	if ((graph_buf = valloc(4 * size)) == NULL) {
2943 #endif
2944 #if BACKGROUND == 2
2945 	if ((graph_buf = malloc(4 * size)) == NULL) {
2946 #endif
2947 #endif
2948 	    printf("Cannot allocate memory for VGA state\n");
2949 	    vga_setmode(TEXT);
2950 	    exit(1);
2951 	}
2952 	sp = graph_buf;
2953 	for (page = 0; size > 0; ++page) {
2954 	    vga_setpage(page);
2955 	    sbytes = (size > GRAPH_SIZE) ? GRAPH_SIZE : size;
2956 	    for (i = 0; i < 4; i++) {
2957 		/* save plane i */
2958 		port_out(0x04, GRA_I);
2959 		port_out(i, GRA_D);
2960 		memcpy(sp, GM, sbytes);
2961 		sp += sbytes;
2962 	    }
2963 	    size -= sbytes;
2964 	}
2965 #ifdef BACKGROUND
2966     } else if (__svgalib_modeinfo_linearset & IS_LINEAR) {   /* linear modes */
2967         if (! graph_buf2) { /* graph_buf2 only gets allocated _once_, and then reused */
2968             int page_size=getpagesize();
2969             if (! (graph_buf2=malloc(__svgalib_linear_memory_size+page_size-1))) {
2970                 printf("Cannot allocate memory for linear state.\n");
2971                 vga_setmode(TEXT);
2972                 exit(1);
2973             }
2974 #ifdef LINEAR_DEBUG
2975             printf("Allocated %d bytes for background screen storage\n",
2976                    __svgalib_linear_memory_size);
2977 #endif
2978             graph_buf2 = (unsigned char *) /* make graph_buf2 page aligned */
2979                          (((unsigned long)graph_buf2 + page_size - 1) & ~(page_size-1));
2980         }
2981 
2982         if (! (graph_buf=malloc(GRAPH_SIZE/*__svgalib_linear_memory_size*/))) {
2983 	    printf("Cannot allocate memory for planar state.\n");
2984 	    vga_setmode(TEXT);
2985 	    exit(1);
2986         }
2987         memcpy(graph_buf2,__svgalib_linearframebuffer,__svgalib_linear_memory_size);
2988         /* cpg: the following memcpy is needed, else the mmap() call in     */
2989         /* __svgalib_map_virtual_screen() bombs out with "invalid argument" */
2990         /* (kernel 2.1.125) */
2991         memcpy(graph_buf,__svgalib_linearframebuffer,GRAPH_SIZE/*__svgalib_linear_memory_size*/);
2992 #endif
2993     } else {			/* SVGA, and SVGA 320x200x256 if videomemoryused > 65536 */
2994 	int size;
2995 	int page;
2996 
2997 	size = VMEM;
2998 
2999 #ifdef DEBUG
3000 	printf("Saving %dK of video memory.\n", (size + 2) / 1024);
3001 #endif
3002 #ifndef BACKGROUND
3003 	if ((graph_buf = malloc(size)) == NULL) {
3004 #endif
3005 #ifdef BACKGROUND
3006 #if BACKGROUND == 1
3007         /* Must allocate hole videopage. */
3008 	if ((graph_buf = valloc((size/GRAPH_SIZE+1)*GRAPH_SIZE)) == NULL) {
3009 #endif
3010 #if BACKGROUND == 2
3011 	if ((graph_buf = malloc(size)) == NULL) {
3012 #endif
3013 #endif
3014 	    printf("Cannot allocate memory for SVGA state.\n");
3015 	    vga_setmode(TEXT);
3016 	    exit(1);
3017 	}
3018 	page = 0;
3019 	while (size >= 65536) {
3020 	    vga_setpage(page);
3021 	    memcpy(graph_buf + page * 65536, GM, 65536);
3022 	    page++;
3023 	    size -= 65536;
3024 	}
3025 #ifdef BACKGROUND
3026 #if BACKGROUND == 1
3027         /* Whole page must be written for mmap(). */
3028 	if (size > 0) {
3029 	    vga_setpage(page);
3030 	    memcpy(graph_buf + page * 65536, GM, GRAPH_SIZE);
3031 	}
3032 #endif
3033 #if BACKGROUND == 2
3034 	if (size > 0) {
3035 	    vga_setpage(page);
3036 	    memcpy(graph_buf + page * 65536, GM, size);
3037 	}
3038 #endif
3039 #endif
3040 #ifndef BACKGROUND
3041 	if (size > 0) {
3042 	    vga_setpage(page);
3043 	    memcpy(graph_buf + page * 65536, GM, size);
3044 	}
3045 #endif
3046     }
3047 }
3048 
3049 static void restorestate(void)
3050 {
3051     int i;
3052 
3053     vga_screenoff();
3054 
3055     if (saved_modeX)
3056 	vga_setmodeX();
3057 
3058     restorepalette(graph_red, graph_green, graph_blue);
3059 
3060     if (CM == G320x200x256 && VMEM <= 65536) {
3061 	memcpy(GM, graph_buf, 65536);
3062     } else if (MODEX || CM == G800x600x16 || (STDVGAMODE(CM) && CM != G320x200x256)) {
3063 	int setresetreg, planereg;
3064 	/* disable Set/Reset Register */
3065 	port_out(0x01, GRA_I);
3066 	setresetreg = inb(GRA_D);
3067 	port_out(0x00, GRA_D);
3068 	outb(SEQ_I, 0x02);
3069 	planereg = inb(SEQ_D);
3070 
3071 	for (i = 0; i < 4; i++) {
3072 	    /* restore plane i */
3073 	    port_out(0x02, SEQ_I);
3074 	    port_out(1 << i, SEQ_D);
3075 	    memcpy(GM, graph_buf + i * GRAPH_SIZE, GRAPH_SIZE);
3076 	}
3077 	outb(GRA_I, 0x01);
3078 	outb(GRA_D, setresetreg);
3079 	outb(SEQ_I, 0x02);
3080 	outb(SEQ_D, planereg);
3081     } else if (CI.colors == 16) {
3082 	int page, size, rbytes;
3083 	unsigned char *rp;
3084 	int setresetreg, planereg;
3085 
3086 	/* disable Set/Reset Register */
3087 	port_out(0x01, GRA_I);
3088 	if (CHIPSET == EGA)
3089 	    setresetreg = 0;
3090 	else
3091 	    setresetreg = inb(GRA_D);
3092 	port_out(0x00, GRA_D);
3093 	port_out(0x02, SEQ_I);
3094 	if (CHIPSET == EGA)
3095 	    planereg = 0;
3096 	else
3097 	    planereg = inb(SEQ_D);
3098 
3099 	size = VMEM;
3100 	rp = graph_buf;
3101 	for (page = 0; size > 0; ++page) {
3102 	    vga_setpage(page);
3103 	    rbytes = (size > GRAPH_SIZE) ? GRAPH_SIZE : size;
3104 	    for (i = 0; i < 4; i++) {
3105 		/* save plane i */
3106 		port_out(0x02, SEQ_I);
3107 		port_out(1 << i, SEQ_D);
3108 		memcpy(GM, rp, rbytes);
3109 		rp += rbytes;
3110 	    }
3111 	    size -= rbytes;
3112 	}
3113 
3114 	outb(GRA_I, 0x01);
3115 	outb(GRA_D, setresetreg);
3116 	outb(SEQ_I, 0x02);
3117 	outb(SEQ_D, planereg);
3118 #ifdef BACKGROUND
3119     } else if (saved_linearset & IS_LINEAR) {
3120         memcpy(__svgalib_linearframebuffer,graph_buf2,__svgalib_linear_memory_size);
3121 #ifdef LINEAR_DEBUG
3122         dump_mem("restore-lin");
3123 #endif
3124 #endif
3125     } else {
3126 /*              vga_modeinfo *modeinfo; */
3127 	int size;
3128 	int page;
3129 	size = VMEM;
3130 
3131 #ifdef DEBUG
3132 	printf("Restoring %dK of video memory.\n", (size + 2) / 1024);
3133 #endif
3134 	page = 0;
3135 	while (size >= 65536) {
3136 	    vga_setpage(page);
3137 	    memcpy(GM, graph_buf + page * 65536, 65536);
3138 	    size -= 65536;
3139 	    page++;
3140 	}
3141 	if (size > 0) {
3142 	    vga_setpage(page);
3143 	    memcpy(GM, graph_buf + page * 65536, size);
3144 	}
3145     }
3146 
3147     if (saved_logicalwidth != CI.xbytes)
3148 	vga_setlogicalwidth(saved_logicalwidth);
3149     if (saved_page != 0)
3150 	vga_setpage(saved_page);
3151     if (saved_displaystart != 0)
3152 	vga_setdisplaystart(saved_displaystart);
3153 
3154     vga_screenon();
3155 
3156     free(graph_buf);
3157 }
3158 
3159 
3160 int vga_getch(void)
3161 {
3162     char c;
3163 
3164     if (CM == TEXT)
3165 	return -1;
3166 
3167     while ((read(__svgalib_tty_fd, &c, 1) < 0) && (errno == EINTR));
3168 
3169     return c;
3170 }
3171 
3172 #ifdef BACKGROUND
3173 int __svgalib_flip_status(void)
3174 
3175 {
3176  return(flip);
3177 }
3178 #endif
3179 
3180 /* I have kept the slightly funny 'flip' terminology. */
3181 
3182 void __svgalib_flipaway(void)
3183 {
3184     /* Leaving console. */
3185     flip_mode = CM;
3186 #ifndef SVGA_AOUT
3187     __joystick_flip_vc(0);
3188 #endif
3189     if (CM != TEXT) {
3190 	/* wait for any blitter operation to finish */
3191 	idle_accel();
3192 	/* Save state and go to textmode. */
3193         __svgalib_saveregs(graph_regs);
3194 	savestate();
3195 	flip = 1;
3196         if(!__svgalib_secondary)vga_setmode(TEXT);
3197 	flip = 0;
3198 
3199         if(!__svgalib_secondary){
3200 #ifdef BACKGROUND
3201 /* Let's put bg screen to right place */
3202 
3203 #if BACKGROUND == 1
3204           if (__svgalib_currentpage<0) __svgalib_currentpage=0;
3205           __svgalib_map_virtual_screen(__svgalib_currentpage);
3206 #endif
3207 #if BACKGROUND == 2
3208           __svgalib_graph_mem=graph_buf+(GRAPH_SIZE*__svgalib_currentpage);
3209 #endif
3210 	  __svgalib_oktowrite=0; /* screen is fliped, not __svgalib_oktowrite. */
3211 #endif
3212         }
3213     }
3214 }
3215 
3216 #ifndef BACKGROUND
3217 static void __svgalib_flipback(void)
3218 #endif
3219 #ifdef BACKGROUND
3220 void __svgalib_flipback(void)
3221 #endif
3222 {
3223 #ifdef BACKGROUND
3224  int tmp_page=__svgalib_currentpage;
3225 #endif
3226     /* Entering console. */
3227     /* Hmmm... and how about unlocking anything someone else locked? */
3228 #ifndef SVGA_AOUT
3229     __joystick_flip_vc(1);
3230 #endif
3231     chipset_unlock();
3232     if (flip_mode != TEXT) {
3233 	/* Restore graphics mode and state. */
3234         if(!__svgalib_secondary){
3235 #ifdef BACKGROUND
3236           __svgalib_oktowrite=1;
3237 #endif
3238   	  flip = 1;
3239 	  vga_setmode(flip_mode);
3240 	  flip = 0;
3241 #ifdef BACKGROUND
3242 #if BACKGROUND == 1
3243           __svgalib_map_virtual_screen(1000000);
3244 #endif
3245 #if BACKGROUND == 2
3246           __svgalib_graph_mem=__svgalib_graph_mem_orginal;
3247 #endif
3248         /* do we need to explicitly enable linear? */
3249           if ((saved_linearset & IS_LINEAR) &&   /* if old mode was linear */
3250               __svgalib_driverspecs->linear) {   /* and linear function present */
3251               __svgalib_driverspecs->linear(LINEAR_ENABLE, (long)__svgalib_physaddr);
3252           }
3253 #endif
3254           __svgalib_setregs(graph_regs);
3255 	  restorestate();
3256 #ifdef BACKGROUND
3257  /* Has to make sure right page is on. */
3258           vga_setpage(tmp_page);
3259 	  vga_setcolor(COL);
3260 #endif
3261         }
3262     }
3263 }
3264 
3265 int vga_flip(void)
3266 {
3267 #ifdef BACKGROUND
3268  int tmp_page=__svgalib_currentpage;
3269 #endif
3270     if (CM != TEXT) {		/* save state and go to textmode */
3271 	savestate();
3272 	flip_mode = CM;
3273 	flip = 1;
3274 	vga_setmode(TEXT);
3275 	flip = 0;
3276 #ifdef BACKGROUND
3277 /* Lets put bg screen to right place */
3278 
3279 #if BACKGROUND == 1
3280         if (__svgalib_currentpage<0) __svgalib_currentpage=0;
3281         __svgalib_map_virtual_screen(__svgalib_currentpage);
3282 #endif
3283 #if BACKGROUND == 2
3284         __svgalib_graph_mem=graph_buf+(GRAPH_SIZE*__svgalib_currentpage);;
3285 #endif
3286 	__svgalib_oktowrite=0; /* screen is fliped, not __svgalib_oktowrite. */
3287 #endif
3288     } else {			/* restore graphics mode and state */
3289 #ifdef BACKGROUND
3290         __svgalib_oktowrite=1;
3291 	/* Probably here too ...  */
3292 	chipset_unlock();
3293 #endif
3294 	flip = 1;
3295 	vga_setmode(flip_mode);
3296 	flip = 0;
3297 #ifdef BACKGROUND
3298 #if BACKGROUND == 1
3299         __svgalib_map_virtual_screen(1000000);
3300 #endif
3301 #if BACKGROUND == 2
3302         __svgalib_graph_mem=__svgalib_graph_mem_orginal;
3303 #endif
3304         if (__svgalib_modeinfo_linearset & IS_LINEAR) {
3305             int (*lfn) (int op, int param) = __svgalib_driverspecs->linear;
3306             if (lfn) (*lfn) (LINEAR_ENABLE, (long)__svgalib_physaddr);
3307         }
3308 #endif
3309 	restorestate();
3310 #ifdef BACKGROUND
3311  /* Has to make sure right page is on. */
3312         vga_setpage(tmp_page);
3313 	vga_setcolor(COL);
3314 #endif
3315     }
3316     return 0;
3317 }
3318 
3319 
3320 int vga_setflipchar(int c)
3321 /* This function is obsolete. Retained for VGAlib compatibility. */
3322 {
3323     __svgalib_flipchar = c;
3324 
3325     return 0;
3326 }
3327 
3328 void vga_setlogicalwidth(int w)
3329 {
3330     __svgalib_driverspecs->setlogicalwidth(w);
3331     currentlogicalwidth = w;
3332 }
3333 
3334 void vga_setdisplaystart(int a)
3335 {
3336     currentdisplaystart = a;
3337     if (CHIPSET != VGA && CHIPSET != EGA)
3338 	if (MODEX || CI.colors == 16) {
3339 	    /* We are currently using a Mode X-like mode on a */
3340 	    /* SVGA card, use the standard VGA function */
3341 	    /* that works properly for Mode X. */
3342 	    /* Same goes for 16 color modes. */
3343 	    __svgalib_vga_driverspecs.setdisplaystart(a);
3344 	    return;
3345 	}
3346     /* Call the regular display start function for the chipset */
3347     __svgalib_driverspecs->setdisplaystart(a);
3348 }
3349 
3350 void vga_bitblt(int srcaddr, int destaddr, int w, int h, int pitch)
3351 {
3352     __svgalib_driverspecs->bitblt(srcaddr, destaddr, w, h, pitch);
3353 }
3354 
3355 void vga_imageblt(void *srcaddr, int destaddr, int w, int h, int pitch)
3356 {
3357     __svgalib_driverspecs->imageblt(srcaddr, destaddr, w, h, pitch);
3358 }
3359 
3360 void vga_fillblt(int destaddr, int w, int h, int pitch, int c)
3361 {
3362     __svgalib_driverspecs->fillblt(destaddr, w, h, pitch, c);
3363 }
3364 
3365 void vga_hlinelistblt(int ymin, int n, int *xmin, int *xmax, int pitch,
3366 		      int c)
3367 {
3368     __svgalib_driverspecs->hlinelistblt(ymin, n, xmin, xmax, pitch, c);
3369 }
3370 
3371 void vga_blitwait(void)
3372 {
3373     __svgalib_driverspecs->bltwait();
3374 }
3375 
3376 int vga_ext_set(unsigned what,...)
3377 {
3378     va_list params;
3379     register int retval = 0;
3380 
3381     switch(what) {
3382 	case VGA_EXT_AVAILABLE:
3383 	    /* Does this use of the arglist corrupt non-AVAIL_ACCEL ext_set? */
3384 	    va_start(params, what);
3385 	    switch (va_arg(params, int)) {
3386 		case VGA_AVAIL_ACCEL:
3387 		if (__svgalib_driverspecs->accelspecs != NULL)
3388 		    retval = __svgalib_driverspecs->accelspecs->operations;
3389 		break;
3390 	    case VGA_AVAIL_ROP:
3391 		if (__svgalib_driverspecs->accelspecs != NULL)
3392 		    retval = __svgalib_driverspecs->accelspecs->ropOperations;
3393 		break;
3394 	    case VGA_AVAIL_TRANSPARENCY:
3395 		if (__svgalib_driverspecs->accelspecs != NULL)
3396 		    retval = __svgalib_driverspecs->accelspecs->transparencyOperations;
3397 		break;
3398 	    case VGA_AVAIL_ROPMODES:
3399 		if (__svgalib_driverspecs->accelspecs != NULL)
3400 		    retval = __svgalib_driverspecs->accelspecs->ropModes;
3401 		break;
3402 	    case VGA_AVAIL_TRANSMODES:
3403 		if (__svgalib_driverspecs->accelspecs != NULL)
3404 		    retval = __svgalib_driverspecs->accelspecs->transparencyModes;
3405 		break;
3406 	    case VGA_AVAIL_SET:
3407 		retval = (1 << VGA_EXT_PAGE_OFFSET) |
3408 			 (1 << VGA_EXT_FONT_SIZE);	/* These are handled by us */
3409 		break;
3410 	    }
3411 	    va_end(params);
3412 	    break;
3413 	case VGA_EXT_PAGE_OFFSET:
3414 	    /* Does this use of the arglist corrupt it? */
3415 	    va_start(params, what);
3416 	    retval = vga_page_offset;
3417 	    vga_page_offset = va_arg(params, int);
3418 	    va_end(params);
3419 	    return retval;
3420 	case VGA_EXT_FONT_SIZE:
3421 	    va_start(params, what);
3422 	    what = va_arg(params, unsigned int);
3423 	    va_end(params);
3424 	    if (!what)
3425 		return FONT_SIZE;
3426 	    retval = fontbufsize;
3427 	    fontbufsize = what;
3428 	    return retval;
3429     }
3430     if ((CM != TEXT) && (MODEFLAGS & HAVE_EXT_SET)) {
3431 	va_start(params, what);
3432 	retval |= __svgalib_driverspecs->ext_set(what, params);
3433 	va_end(params);
3434     }
3435     return retval;
3436 }
3437 
3438 /* Parse a string for options.. str is \0-terminated source,
3439    commands is an array of char ptrs (last one is NULL) containing commands
3440    to parse for. (if first char is ! case sensitive),
3441    func is called with ind the index of the detected command.
3442    func has to return the ptr to the next unhandled token returned by strtok(NULL," ").
3443    Use strtok(NULL," ") to get the next token from the file..
3444    mode is 1 when reading from conffile and 0 when parsing the env-vars. This is to
3445    allow disabling of dangerous (hardware damaging) options when reading the ENV-Vars
3446    of Joe user.
3447    Note: We use strtok, that is str is destroyed! */
3448 static void parse_string(char *str, char **commands, char *(*func) (int ind, int mode), int mode)
3449 {
3450     int index;
3451     register char *ptr, **curr;
3452 
3453     /*Pass one, delete comments,ensure only whitespace is ' ' */
3454     for (ptr = str; *ptr; ptr++) {
3455 	if (*ptr == '#') {
3456 	    while (*ptr && (*ptr != '\n')) {
3457 		*ptr++ = ' ';
3458 	    }
3459 	    if (*ptr)
3460 		*ptr = ' ';
3461 	} else if (isspace(*ptr)) {
3462 	    *ptr = ' ';
3463 	}
3464     }
3465     /*Pass two, parse commands */
3466     ptr = strtok(str, " ");
3467     while (ptr) {
3468 #ifdef DEBUG_CONF
3469 	printf("Parsing: %s\n", ptr);
3470 #endif
3471 	for (curr = commands, index = 0; *curr; curr++, index++) {
3472 #ifdef DEBUG_CONF
3473 	    printf("Checking: %s\n", *curr);
3474 #endif
3475 	    if (**curr == '!') {
3476 		if (!strcmp(*curr + 1, ptr)) {
3477 		    ptr = (*func) (index, mode);
3478 		    break;
3479 		}
3480 	    } else {
3481 		if (!strcasecmp(*curr, ptr)) {
3482 		    ptr = (*func) (index, mode);
3483 		    break;
3484 		}
3485 	    }
3486 	}
3487 	if (!*curr)		/*unknow command */
3488 	    ptr = strtok(NULL, " ");	/* skip silently til' next command */
3489     }
3490 }
3491 
3492 static int allowoverride = 0;	/* Allow dangerous options in ENV-Var or in */
3493 				/* the $HOME/.svgalibrc */
3494 
3495 static void process_config_file(FILE *file, int mode, char **commands,
3496 		 			char *(*func)(int ind, int mode)) {
3497  struct stat st;
3498  char *buf, *ptr;
3499  int i;
3500 
3501   fstat(fileno(file), &st);	/* Some error analysis may be fine here.. */
3502   if ( (buf = alloca(st.st_size + 1)) == 0) {	/* + a final \0 */
3503     puts("svgalib: out of mem while parsing config file !");
3504     return;
3505   }
3506   fread(buf, 1, st.st_size, file);
3507   for (i = 0, ptr = buf; i < st.st_size; i++, ptr++) {
3508     if (!*ptr)
3509       *ptr = ' ';			/* Erase any maybe embedded \0 */
3510     }
3511   *ptr = 0;					/* Trailing \0 */
3512   parse_string(buf, commands, func, mode);	/* parse config file */
3513 }
3514 
3515 /* This is a service function for drivers. Commands and func are as above.
3516    The following config files are parsed in this order:
3517     - /etc/vga/libvga.conf (#define SVGALIB_CONFIG_FILE)
3518     - ~/.svgalibrc
3519     - the file where env variavle SVGALIB_CONFIG_FILE points
3520     - the env variable SVGALIB_CONFIG (for compatibility, but I would remove
3521       it, we should be more flexible...  Opinions ?)
3522     - MW: I'd rather keep it, doesn't do too much harm and is sometimes nice
3523       to have.
3524 */
3525 void __svgalib_read_options(char **commands, char *(*func) (int ind, int mode)) {
3526     FILE *file;
3527     char *buf = NULL, *ptr;
3528     int i;
3529 
3530     if ( (file = fopen(SVGALIB_CONFIG_FILE, "r")) != 0) {
3531 #ifdef DEBUG_CONF
3532   printf("Processing config file \'%s\'\n", SVGALIB_CONFIG_FILE);
3533 #endif
3534       process_config_file(file, 1, commands, func);
3535       fclose(file);
3536     } else {
3537 	fprintf(stderr, "svgalib: Configuration file \'%s\' not found.\n", SVGALIB_CONFIG_FILE);
3538     }
3539 
3540     if ( (ptr = getenv("HOME")) != 0) {
3541       char *filename;
3542 
3543       filename = alloca(strlen(ptr) + 20);
3544       if (!filename) {
3545 	puts("svgalib: out of mem while parsing SVGALIB_CONFIG_FILE !");
3546       } else {
3547 	strcpy(filename, ptr);
3548 	strcat(filename, "/.svgalibrc");
3549 	if ( (file = fopen(filename, "r")) != 0) {
3550 #ifdef DEBUG_CONF
3551 	  printf("Processing config file \'%s\'\n", filename);
3552 #endif
3553 	  process_config_file(file, allowoverride, commands, func);
3554 	  fclose(file);
3555 	}
3556       }
3557     }
3558 
3559     if ( (ptr = getenv("SVGALIB_CONFIG_FILE")) != 0) {
3560       if ( (file = fopen(ptr, "r")) != 0) {
3561 #ifdef DEBUG_CONF
3562   printf("Processing config file \'%s\'\n", ptr);
3563 #endif
3564 	process_config_file(file, allowoverride, commands, func);
3565 	fclose(file);
3566       } else {
3567         fprintf(stderr, "svgalib: warning: config file \'%s\', pointed to by SVGALIB_CONFIG_FILE, not found !\n", ptr);
3568       }
3569     }
3570 
3571     if ( (ptr = getenv("SVGALIB_CONFIG")) != 0  &&  (i = strlen(ptr)) != 0) {
3572       buf = alloca(i + 1);
3573       if (!buf) {
3574 	puts("svgalib: out of mem while parsing SVGALIB_CONFIG !");
3575       } else {
3576 	strcpy(buf, ptr);		/* Copy for safety and strtok!! */
3577 #ifdef DEBUG_CONF
3578 	puts("Parsing env variable \'SVGALIB_CONFIG\'");
3579 #endif
3580 	parse_string(buf, commands, func, allowoverride);
3581       }
3582     }
3583 }
3584 
3585 /* Configuration file, mouse interface, initialization. */
3586 
3587 static int configfileread = 0;	/* Boolean. */
3588 
3589 /* What are these m0 m1 m... things ? Shouldn't they be removed ? */
3590 static char *vga_conf_commands[] = {
3591     "mouse", "monitor", "!m", "!M", "chipset", "overrideenable", "!m0", "!m1", "!m2", "!m3",
3592     "!m4", "!m9", "!M0", "!M1", "!M2", "!M3", "!M4", "!M5", "!M6", "nolinear",
3593     "linear", "!C0", "!C1", "!C2", "!C3", "!C4", "!C5", "!C6", "!C7", "!C8", "!C9",
3594     "!c0", "!c1", "monotext", "colortext", "!m5",
3595     "leavedtr", "cleardtr", "setdtr", "leaverts", "clearrts",
3596     "setrts", "grayscale", "horizsync", "vertrefresh", "modeline",
3597     "security","mdev", "default_mode", "nosigint", "sigint",
3598     "joystick0", "joystick1", "joystick2", "joystick3",
3599     "textprog", "vesatext", "vesasave", "secondary", "bandwidth",
3600     "novccontrol", "newmode", "noprocpci", "vesatextmode", "pcistart",
3601     "ragedoubleclock", "vesacputype",
3602     NULL};
3603 
3604 static char *conf_mousenames[] =
3605 {
3606   "Microsoft", "MouseSystems", "MMSeries", "Logitech", "Busmouse", "PS2",
3607     "MouseMan", "gpm", "Spaceball", "none", "IntelliMouse", "IMPS2", "pnp",
3608     "WacomGraphire", "DRMOUSE4DS", NULL};
3609 
3610 static int check_digit(char *ptr, char *digits)
3611 {
3612     if (ptr == NULL)
3613 	return 0;
3614     return strlen(ptr) == strspn(ptr, digits);
3615 }
3616 
3617 static char *process_option(int command, int mode)
3618 {
3619     static char digits[] = ".0123456789";
3620     char *ptr, **tabptr, *ptb;
3621     int i, j;
3622     float f;
3623 
3624 #ifdef DEBUG_CONF
3625     printf("command %d detected.\n", command);
3626 #endif
3627     switch (command) {
3628     case 5:
3629 #ifdef DEBUG_CONF
3630 	puts("Allow override");
3631 #endif
3632 	if (mode)
3633 	    allowoverride = 1;
3634 	else
3635 	    puts("Overrideenable denied. (Gee.. Do you think I'm that silly?)");
3636 	break;
3637     case 0:			/* mouse */
3638     case 2:			/* m */
3639 	ptr = strtok(NULL, " ");
3640 	if (ptr == NULL)
3641 	    goto inv_mouse;
3642 	if (check_digit(ptr, digits + 1)) {	/* It is a number.. */
3643 	    i = atoi(ptr);
3644 	    if ((i < 0) || (i > 9))
3645 		goto inv_mouse;
3646 	    mouse_type = i;
3647 	} else {		/* parse for symbolic name.. */
3648 	    for (i = 0, tabptr = conf_mousenames; *tabptr; tabptr++, i++) {
3649 		if (!strcasecmp(ptr, *tabptr)) {
3650 		    mouse_type = i;
3651 #ifdef DEBUG_DRMOUSE4DS
3652 	fprintf(stderr, "mouse type: %d: %s \n", i, conf_mousenames[i]);
3653 #endif
3654 		    goto leave;
3655 		}
3656 	    }
3657 	  inv_mouse:
3658 	    printf("svgalib: Illegal mouse setting: {mouse|m} %s\n"
3659 		   "Correct usage: {mouse|m} mousetype\n"
3660 		   "where mousetype is one of 0, 1, 2, 3, 4, 5, 6, 7, 9,\n",
3661 		   (ptr != NULL) ? ptr : "");
3662 	    for (tabptr = conf_mousenames, i = 0; *tabptr; tabptr++, i++) {
3663 		if (i == MOUSE_NONE)
3664 		    continue;
3665 		printf("%s, ", *tabptr);
3666 	    }
3667 	    puts("or none.");
3668 	    return ptr;		/* Allow a second parse of str */
3669 	}
3670 	break;
3671     case 1:			/* monitor */
3672     case 3:			/* M */
3673 	ptr = strtok(NULL, " ");
3674 	if (check_digit(ptr, digits + 1)) {	/* It is an int.. */
3675 	    i = atoi(ptr);
3676 	    if (i < 7) {
3677 		command = i + 12;
3678 		goto monnum;
3679 	    } else {
3680 		f = i;
3681 		goto monkhz;
3682 	    }
3683 	} else if (check_digit(ptr, digits)) {	/* It is a float.. */
3684 	    f = atof(ptr);
3685 	  monkhz:
3686 	    if (!mode)
3687 		goto mon_deny;
3688 	    __svgalib_horizsync.max = f * 1000.0f;
3689 	} else {
3690 	    printf("svgalib: Illegal monitor setting: {monitor|M} %s\n"
3691 		   "Correct usage: {monitor|M} monitortype\n"
3692 		   "where monitortype is one of 0, 1, 2, 3, 4, 5, 6, or\n"
3693 		   "maximal horz. scan frequency in khz.\n"
3694 		   "Example: monitor 36.5\n",
3695 		   (ptr != NULL) ? ptr : "");
3696 	    return ptr;		/* Allow a second parse of str */
3697 	}
3698 	break;
3699     case 4:			/* chipset */
3700 	ptr = strtok(NULL, " ");
3701 	if (ptr == NULL) {
3702 	    puts("svgalib: Illegal chipset setting: no chipset given");
3703 	    goto chip_us;
3704 	}
3705 	/*First param is chipset */
3706 	for (i = 0, tabptr = driver_names; *tabptr; tabptr++, i++) {
3707 	    if (!strcasecmp(ptr, *tabptr)) {
3708 		if (!__svgalib_driverspecslist[i]) {
3709 		    printf("svgalib: Illegal chipset setting: Driver for %s is NOT compiled in.\n",
3710 			ptr);
3711 		    continue; /* The for above will loop a few more times and fail */
3712 		}
3713 		ptr = strtok(NULL, " ");
3714 		if (check_digit(ptr, digits + 1)) {
3715 		    j = atoi(ptr);
3716 		    ptr = strtok(NULL, " ");
3717 		    if (check_digit(ptr, digits + 1)) {
3718 			if (mode)
3719 			    vga_setchipsetandfeatures(i, j, atoi(ptr));
3720 			else {
3721 			  chipdeny:
3722 			    puts("chipset override from environment denied.");
3723 			}
3724 			return strtok(NULL, " ");
3725 		    } else {
3726 			puts("svgalib: Illegal chipset setting: memory is not a number");
3727 			goto chip_us;
3728 		    }
3729 		}
3730 		if (mode)
3731 		    vga_setchipset(i);
3732 		else
3733 		    puts("chipset override from environment denied.");
3734 		return ptr;
3735 	    }
3736 	}
3737 	printf("svgalib: Illegal chipset setting: chipset %s\n", ptr);
3738       chip_us:
3739 	puts("Correct usage: chipset driver [par1 par2]\n"
3740 	     "where driver is one of:");
3741 	ptb = "%s";
3742 	for (i = 0, tabptr = driver_names; *tabptr; tabptr++, i++) {
3743 	    if (__svgalib_driverspecslist[i] != NULL) {
3744 		printf(ptb, *tabptr);
3745 		ptb = ", %s";
3746 	    }
3747 	}
3748 	puts("\npar1 and par2 are river dependant integers.\n"
3749 	     "Example: Chipset VGA    or\n"
3750 	     "Chipset VGA 0 512");
3751 	return ptr;
3752     case 6:			/* oldstyle config: m0-m4 */
3753     case 7:
3754     case 8:
3755     case 9:
3756     case 10:
3757 	mouse_type = command - 6;
3758 	break;
3759     case 11:			/* m9 */
3760 	mouse_type = MOUSE_NONE;
3761 	break;
3762     case 12:			/* oldstyle config: M0-M6 */
3763     case 13:
3764     case 14:
3765     case 15:
3766     case 16:
3767     case 17:
3768     case 18:
3769       monnum:
3770 	if (!mode) {
3771 	  mon_deny:
3772 	    puts("Monitor setting from environment denied.");
3773 	    break;
3774 	} else {
3775 	    __svgalib_horizsync.max = __svgalib_maxhsync[command - 12];
3776 	}
3777 	break;
3778     case 19:			/*nolinear */
3779 	modeinfo_mask &= ~CAPABLE_LINEAR;
3780 	break;
3781     case 20:			/*linear */
3782 	modeinfo_mask |= CAPABLE_LINEAR;
3783 	break;
3784     case 21:			/* oldstyle chipset C0 - C9 */
3785     case 22:
3786     case 23:
3787     case 24:
3788     case 25:
3789     case 26:
3790     case 27:
3791     case 28:
3792     case 29:
3793     case 30:
3794 	if (!mode)
3795 	    goto chipdeny;
3796 	vga_setchipset(command - 21);
3797 	break;
3798     case 31:			/* c0-c1 color-text selection */
3799 	if (!mode) {
3800 	  coltexdeny:
3801 	    puts("Color/mono text selection from environment denied.");
3802 	    break;
3803 	}
3804 	color_text = 0;
3805 	break;
3806     case 32:
3807 	if (!mode) {
3808 	    puts("Color/mono text selection from environment denied.");
3809 	    break;
3810 	}
3811 	color_text = 1;
3812 	break;
3813     case 33:
3814     case 34:
3815 	if (!mode)
3816 	    goto coltexdeny;
3817 	color_text = command - 32;
3818 	break;
3819     case 35:			/* Mouse type 5 - "PS2". */
3820 	mouse_type = 5;
3821 	break;
3822     case 36:
3823 	mouse_modem_ctl &= ~(MOUSE_CHG_DTR | MOUSE_DTR_HIGH);
3824 	break;
3825     case 37:
3826 	mouse_modem_ctl &= ~MOUSE_DTR_HIGH;
3827 	mouse_modem_ctl |= MOUSE_CHG_DTR;
3828 	break;
3829     case 38:
3830 	mouse_modem_ctl |= (MOUSE_CHG_RTS | MOUSE_RTS_HIGH);
3831 	break;
3832     case 39:
3833 	mouse_modem_ctl &= ~(MOUSE_CHG_RTS | MOUSE_RTS_HIGH);
3834 	break;
3835     case 40:
3836 	mouse_modem_ctl &= ~MOUSE_RTS_HIGH;
3837 	mouse_modem_ctl |= MOUSE_CHG_RTS;
3838 	break;
3839     case 41:
3840 	mouse_modem_ctl |= (MOUSE_CHG_RTS | MOUSE_RTS_HIGH);
3841 	break;
3842     case 42:			/* grayscale */
3843 	__svgalib_grayscale = 1;
3844 	break;
3845     case 43:			/* horizsync */
3846 	ptr = strtok(NULL, " ");
3847 	if (check_digit(ptr, digits)) {		/* It is a float.. */
3848 	    f = atof(ptr);
3849 	    if (!mode)
3850 		goto mon_deny;
3851 	    __svgalib_horizsync.min = f * 1000;
3852 	} else
3853 	    goto hs_bad;
3854 
3855 	ptr = strtok(NULL, " ");
3856 	if (check_digit(ptr, digits)) {		/* It is a float.. */
3857 	    f = atof(ptr);
3858 	    if (!mode)
3859 		goto mon_deny;
3860 	    __svgalib_horizsync.max = f * 1000;
3861 	} else {
3862 	  hs_bad:
3863 	    printf("svgalib: Illegal HorizSync setting.\n"
3864 		   "Correct usage: HorizSync min_kHz max_kHz\n"
3865 		   "Example: HorizSync 31.5 36.5\n");
3866 	}
3867 	break;
3868     case 44:			/* vertrefresh */
3869 	ptr = strtok(NULL, " ");
3870 	if (check_digit(ptr, digits)) {		/* It is a float.. */
3871 	    f = atof(ptr);
3872 	    if (!mode)
3873 		goto mon_deny;
3874 	    __svgalib_vertrefresh.min = f;
3875 	} else
3876 	    goto vr_bad;
3877 
3878 	ptr = strtok(NULL, " ");
3879 	if (check_digit(ptr, digits)) {		/* It is a float.. */
3880 	    f = atof(ptr);
3881 	    if (!mode)
3882 		goto mon_deny;
3883 	    __svgalib_vertrefresh.max = f;
3884 	} else {
3885 	  vr_bad:
3886 	    printf("svgalib: Illegal VertRefresh setting.\n"
3887 		   "Correct usage: VertRefresh min_Hz max_Hz\n"
3888 		   "Example: VertRefresh 50 70\n");
3889 	}
3890 	break;
3891     case 45:{			/* modeline */
3892 	    MonitorModeTiming mmt;
3893 	    const struct {
3894 		char *name;
3895 		int val;
3896 	    } options[] = {
3897 		{
3898 		    "-hsync", NHSYNC
3899 		},
3900 		{
3901 		    "+hsync", PHSYNC
3902 		},
3903 		{
3904 		    "-vsync", NVSYNC
3905 		},
3906 		{
3907 		    "+vsync", PVSYNC
3908 		},
3909 		{
3910 		    "interlace", INTERLACED
3911 		},
3912 		{
3913 		    "interlaced", INTERLACED
3914 		},
3915 		{
3916 		    "doublescan", DOUBLESCAN
3917 		}
3918 	    };
3919 #define ML_NR_OPTS (sizeof(options)/sizeof(*options))
3920 
3921 	    /* Skip the name of the mode */
3922 	    ptr = strtok(NULL, " ");
3923 	    if (!ptr)
3924 		break;
3925 
3926 	    ptr = strtok(NULL, " ");
3927 	    if (!ptr)
3928 		break;
3929 	    mmt.pixelClock = atof(ptr) * 1000;
3930 
3931 #define ML_GETINT(x) \
3932 	ptr = strtok(NULL, " "); if(!ptr) break; \
3933 	mmt.x = atoi(ptr);
3934 
3935 	    ML_GETINT(HDisplay);
3936 	    ML_GETINT(HSyncStart);
3937 	    ML_GETINT(HSyncEnd);
3938 	    ML_GETINT(HTotal);
3939 	    ML_GETINT(VDisplay);
3940 	    ML_GETINT(VSyncStart);
3941 	    ML_GETINT(VSyncEnd);
3942 	    ML_GETINT(VTotal);
3943 	    mmt.flags = 0;
3944 	    while ((ptr = strtok(NULL, " "))) {
3945 		for (i = 0; i < ML_NR_OPTS; i++)
3946 		    if (!strcasecmp(ptr, options[i].name))
3947                       {
3948                         mmt.flags |= options[i].val;
3949                         break;
3950                       }
3951 		if (i == ML_NR_OPTS)
3952 		    break;
3953 	    }
3954 #undef ML_GETINT
3955 #undef ML_NR_OPTS
3956 
3957 	    __svgalib_addusertiming(&mmt);
3958 	    return ptr;
3959 
3960 	}
3961     case 46:
3962 	if (!mode) {
3963 	    puts("Security setting from environment denied.");
3964 	    break;
3965 	}
3966 	if ( (ptr = strtok( NULL, " ")) ) {
3967 	    if (!strcasecmp("revoke-all-privs", ptr)) {
3968 		 __svgalib_security_revokeallprivs = 1;
3969 		 break;
3970 	    } else if (!strcasecmp("compat", ptr)) {
3971 		 __svgalib_security_revokeallprivs = 0;
3972 		 break;
3973 	    }
3974 	}
3975 	puts("svgalib: Unknown security options\n");
3976 	break;
3977     case 47:
3978 	ptr = strtok(NULL," ");
3979 	if (ptr) {
3980 	    mouse_device = strdup(ptr);
3981 	    if (mouse_device == NULL) {
3982 	      nomem:
3983 		puts("svgalib: Fatal error: out of memory.");
3984 		exit(1);
3985 	    }
3986 	} else
3987 	    goto param_needed;
3988 	break;
3989     case 48:		/* default_mode */
3990 	if ( (ptr = strtok(NULL, " ")) != 0) {
3991 	 int mode = vga_getmodenumber(ptr);
3992 	  if (mode != -1) {
3993 	    __svgalib_default_mode = mode;
3994 	  } else {
3995 	    printf("svgalib: config: illegal mode \'%s\' for \'%s\'\n",
3996 	   			  ptr, vga_conf_commands[command]);
3997 	  }
3998 	} else {
3999   param_needed:
4000   	  printf("svgalib: config: \'%s\' requires parameter(s)",
4001   	  				vga_conf_commands[command]);
4002 	  break;
4003 	}
4004 	break;
4005     case 49: /* nosigint */
4006 	__svgalib_nosigint = 1;
4007 	break;
4008     case 50: /* sigint */
4009 	__svgalib_nosigint = 0;
4010 	break;
4011     case 51: /* joystick0 */
4012     case 52: /* joystick1 */
4013     case 53: /* joystick2 */
4014     case 54: /* joystick3 */
4015 	if (! (ptr = strtok(NULL, " ")) )
4016 		goto param_needed;
4017 #ifndef SVGA_AOUT
4018 	if (__joystick_devicenames[command - 51])
4019 	    free(__joystick_devicenames[command - 51]);
4020 	__joystick_devicenames[command - 51] = strdup(ptr);
4021 	if (!__joystick_devicenames[command - 51])
4022 	    goto nomem;
4023 #else
4024 	printf("svgalib: No joystick support in a.out version.\n");
4025 #endif
4026 	break;
4027     case 55: /* TextProg */
4028 	ptr = strtok(NULL," ");
4029         if(ptr==NULL)break;
4030         __svgalib_textprog|=2;
4031 	__svgalib_TextProg = strdup(ptr);
4032 	if (!__svgalib_TextProg)
4033 	    goto nomem;
4034         i=1;
4035         while(((ptr=strtok(NULL," "))!=NULL) &&
4036 	       (i< ((sizeof(__svgalib_TextProg_argv) / sizeof(char *)) + 1)) &&
4037 	       strcmp(ptr,"END")){
4038 	   __svgalib_TextProg_argv[i]=strdup(ptr);
4039 	   if (!__svgalib_TextProg_argv[i])
4040 	       goto nomem;
4041 	   i++;
4042         };
4043         __svgalib_TextProg_argv[i]=NULL;
4044         ptb=strrchr(__svgalib_TextProg,'/');
4045         __svgalib_TextProg_argv[0]=ptb?ptb + 1:__svgalib_TextProg;
4046         break;
4047     case 56:
4048 #ifdef INCLUDE_VESA_DRIVER
4049         __svgalib_vesatext=1;
4050         break;
4051 #else
4052        printf("svgalib: Warning: VESA support not enabled!\n");
4053 #endif
4054     case 57: /* Vesa save bitmap */
4055 #ifdef INCLUDE_VESA_DRIVER
4056        ptr = strtok(NULL, " ");
4057        if(ptr!=NULL){
4058          j = atoi(ptr);
4059          __svgalib_VESA_savebitmap=j;
4060        };
4061 #else
4062        printf("svgalib: Warning: VESA support not enabled!\n");
4063 #endif
4064        break;
4065     case 58:
4066         __svgalib_secondary=1;
4067         break;
4068     case 59:		/* max bandwidth */
4069 	if ( (ptr = strtok(NULL, " ")) != 0) {
4070 	    if (check_digit(ptr, digits)) {
4071 	        int f = atoi(ptr);
4072 	        if (f<31000)f=31000;
4073 	        __svgalib_bandwidth = f;
4074 	    }
4075 	} else {
4076   	    printf("svgalib: config: \'%s\' requires parameter(s)",
4077   	  				vga_conf_commands[command]);
4078 	    break;
4079 	}
4080 	break;
4081     case 60:
4082         __svgalib_novccontrol=1;
4083         break;
4084     case 61: {
4085         int x,y,c,p,b;
4086 
4087     	ptr = strtok(NULL, " ");
4088         if(!ptr) break;
4089         x = atoi(ptr);
4090     	ptr = strtok(NULL, " ");
4091         if(!ptr) break;
4092         y = atoi(ptr);
4093     	ptr = strtok(NULL, " ");
4094         if(!ptr) break;
4095         c = atoi(ptr);
4096     	ptr = strtok(NULL, " ");
4097         if(!ptr) break;
4098         p = atoi(ptr);
4099     	ptr = strtok(NULL, " ");
4100         if(!ptr) break;
4101         b = atoi(ptr);
4102 
4103         vga_addmode(x,y,c,p,b);
4104         };
4105         break;
4106     case 62:
4107         __svgalib_use_procpci=0;
4108         break;
4109     case 63: /* Vesa text mode number */
4110 #ifdef INCLUDE_VESA_DRIVER
4111        ptr = strtok(NULL, " ");
4112        if(ptr!=NULL){
4113          j = atoi(ptr);
4114          __svgalib_VESA_textmode=j;
4115        };
4116 #else
4117        printf("svgalib: Warning: VESA support not enabled!\n");
4118 #endif
4119        break;
4120     case 64:			/* pci initial values */
4121 	ptr = strtok(NULL, " ");
4122 	if (check_digit(ptr, digits)) {
4123             j = atoi(ptr);
4124 	    if((j<16)&&(j>=0))__svgalib_pci_ibus = j;
4125 	} else
4126 	    goto ps_bad;
4127 
4128 	ptr = strtok(NULL, " ");
4129 	if (check_digit(ptr, digits)) {
4130             j = atoi(ptr);
4131 	    if((j<256)&&(j>=0))__svgalib_pci_idev = j;
4132 	} else {
4133         ps_bad:
4134 	    printf("svgalib: Illegal PCI initial values setting.\n"
4135 		   "Correct usage: PCIStart initial_bus initial_dev"
4136 		   "Example: PCIStart 1 0\n");
4137 	}
4138 	break;
4139     case 65:
4140         __svgalib_ragedoubleclock=1;
4141         break;
4142     case 66: /* cpu type */
4143         ptr = strtok(NULL, " ");
4144 #ifdef INCLUDE_VESA_DRIVER
4145         if(ptr!=NULL){
4146             j = atoi(ptr);
4147             __svgalib_lrmi_cpu_type=j;
4148         };
4149 #endif
4150         break;
4151   }
4152   leave:
4153     return strtok(NULL, " ");
4154 }
4155 
4156 static void readconfigfile(void)
4157 {
4158     if (configfileread)
4159 	return;
4160     configfileread = 1;
4161     mouse_type = -1;
4162 
4163     {
4164         struct stat buf;
4165 
4166         if(!stat("/proc/bus/pci",&buf))__svgalib_use_procpci=1;
4167           else __svgalib_use_procpci=0;
4168     }
4169 
4170     __svgalib_read_options(vga_conf_commands, process_option);
4171     if (mouse_type == -1) {
4172 	mouse_type = MOUSE_MICROSOFT;	/* Default. */
4173 	puts("svgalib: Assuming Microsoft mouse.");
4174     }
4175     if (__svgalib_horizsync.max == 0U) {
4176 	/* Default monitor is low end SVGA/8514. */
4177 	__svgalib_horizsync.min = 31500U;
4178 	__svgalib_horizsync.max = 35500U;
4179 	puts("svgalib: Assuming low end SVGA/8514 monitor (35.5 KHz).");
4180     }
4181 #ifdef DEBUG_CONF
4182     printf("Mouse is: %d Monitor is: H(%5.1f, %5.1f) V(%u,%u)\n", mouse_type,
4183       __svgalib_horizsync.min / 1000.0, __svgalib_horizsync.max / 1000.0,
4184 	   __svgalib_vertrefresh.min, __svgalib_vertrefresh.max);
4185     printf("Mouse device is: %s",mouse_device);
4186 #endif
4187 }
4188 
4189 int vga_getmousetype(void)
4190 {
4191     readconfigfile();
4192     return mouse_type | mouse_modem_ctl;
4193 }
4194 
4195 int vga_getmonitortype(void)
4196 {				/* obsolete */
4197     int i;
4198     readconfigfile();
4199     for (i = 1; i <= MON1024_72; i++)
4200 	if (__svgalib_horizsync.max < __svgalib_maxhsync[i])
4201 	    return i - 1;
4202 
4203     return MON1024_72;
4204 }
4205 
4206 void vga_setmousesupport(int s)
4207 {
4208     mouse_support = s;
4209 }
4210 
4211 #ifndef BACKGROUND
4212 
4213 void vga_lockvc(void)
4214 {
4215     lock_count++;
4216     if (flip)
4217 	__svgalib_waitvtactive();
4218 }
4219 
4220 void vga_unlockvc(void)
4221 {
4222     if (--lock_count <= 0) {
4223 	lock_count = 0;
4224 	if (release_flag) {
4225 	    release_flag = 0;
4226 	    __svgalib_releasevt_signal(SVGALIB_RELEASE_SIG);
4227 	}
4228     }
4229 }
4230 
4231 void vga_runinbackground(int stat, ...)
4232 {
4233     va_list params;
4234 
4235     va_start(params,stat);
4236 
4237     switch (stat) {
4238     case VGA_GOTOBACK:
4239 	__svgalib_go_to_background = va_arg(params, void *);
4240 	break;
4241     case VGA_COMEFROMBACK:
4242 	__svgalib_come_from_background = va_arg(params, void *);
4243 	break;
4244     default:
4245         __svgalib_runinbackground = stat;
4246         break;
4247     };
4248 }
4249 
4250 #endif
4251 
4252 int vga_runinbackground_version(void)
4253 
4254 /*  Program can check, if it is safe to in background. */
4255 
4256 {
4257  int version=0;
4258 
4259 #ifdef BACKGROUND
4260 #if BACKGROUND == 1
4261  version=1;
4262 #endif
4263 #if BACKGROUND == 2
4264  version=2;
4265 #endif
4266 #endif
4267  return(version);
4268 }
4269 
4270 #ifdef BACKGROUND
4271 
4272 unsigned char *__svgalib_give_graph_red(void)
4273 
4274 {
4275  return(graph_red);
4276 }
4277 
4278 unsigned char *__svgalib_give_graph_green(void)
4279 
4280 {
4281  return(graph_green);
4282 }
4283 
4284 unsigned char *__svgalib_give_graph_blue(void)
4285 
4286 {
4287  return(graph_blue);
4288 }
4289 
4290 #endif
4291 
4292 int vga_oktowrite(void)
4293 {
4294     if(__svgalib_secondary)return 1;
4295     return __svgalib_oktowrite;
4296 }
4297 
4298 void vga_chipset_setregs(unsigned char regs[])
4299 {
4300     chipset_setregs(regs, TEXT); /* Why TEXT? Can't think of smthg else*/
4301 }
4302 
4303 void vga_chipset_saveregs(unsigned char regs[])
4304 {
4305     chipset_saveregs(regs);
4306 }
4307 
4308 int vga_simple_init(void)
4309 {
4310     __svgalib_simple = 1;
4311     __svgalib_novccontrol = 1;
4312     __svgalib_driver_report = 0;
4313     readconfigfile();
4314     vga_hasmode(TEXT);
4315     if(__svgalib_mmio_size)
4316                   MMIO_POINTER=mmap((caddr_t) 0,
4317 				   __svgalib_mmio_size,
4318 				   PROT_READ | PROT_WRITE,
4319 				   MAP_SHARED,
4320 				   __svgalib_mem_fd,
4321                                    (off_t) __svgalib_mmio_base
4322                   ); else MMIO_POINTER=NULL;
4323     close(__svgalib_mem_fd);
4324     return 0;
4325 }
4326 
4327 int vga_initf(int flags) {
4328     if(flags&1)
4329         __svgalib_novccontrol=2;
4330     if(flags&2)
4331         __svgalib_secondary=2;
4332     return vga_init();
4333 }
4334 
4335 
4336 int vga_init(void)
4337 {
4338     int retval = 0;
4339 
4340 #if 0
4341     __svgalib_open_devconsole();
4342     if (__svgalib_tty_fd < 0) {
4343 	/* Return with error code. */
4344 	/* Since the configuration file hasnt been read yet, security will
4345 	   only be set to 1 if it has been compiled into the program */
4346 	retval = -1;
4347     } else {
4348 	readconfigfile();
4349 	vga_hasmode(TEXT); /* Force driver message and initialization. */
4350     }
4351 #else
4352     readconfigfile();
4353     vga_hasmode(TEXT);
4354     if(__svgalib_driver_report) {
4355         printf("svgalib %s\n", versionstr);
4356     }
4357     if(!__svgalib_novccontrol)__svgalib_open_devconsole();
4358 #endif
4359 
4360 if(B8000_MEM_POINTER==NULL){
4361     if(__svgalib_banked_mem_base==0)__svgalib_banked_mem_base=0xa0000;
4362     if(__svgalib_banked_mem_size==0)__svgalib_banked_mem_size=0x10000;
4363                   BANKED_MEM_POINTER=mmap((caddr_t) 0,
4364 			                  __svgalib_banked_mem_size,
4365 				          PROT_READ | PROT_WRITE,
4366 				          MAP_SHARED,
4367 				          __svgalib_mem_fd,
4368 				          __svgalib_banked_mem_base
4369 
4370                   );
4371     if(__svgalib_linear_mem_size) {
4372                   LINEAR_MEM_POINTER=mmap((caddr_t) 0,
4373 				          __svgalib_linear_mem_size,
4374 			                  PROT_READ | PROT_WRITE,
4375                                           MAP_SHARED,
4376 				          __svgalib_mem_fd,
4377                                           (off_t) __svgalib_linear_mem_base
4378                   );
4379     };/* else LINEAR_MEM_POINTER=NULL;*/
4380 
4381     if(__svgalib_mmio_size)
4382                   MMIO_POINTER=mmap((caddr_t) 0,
4383 				   __svgalib_mmio_size,
4384 				   PROT_READ | PROT_WRITE,
4385 				   MAP_SHARED,
4386 				   __svgalib_mem_fd,
4387                                    (off_t) __svgalib_mmio_base
4388                   ); else MMIO_POINTER=NULL;
4389 
4390     B8000_MEM_POINTER=mmap((caddr_t) 0,
4391        			    32768,
4392 			    PROT_READ | PROT_WRITE,
4393                             MAP_SHARED,
4394                             __svgalib_mem_fd,
4395                             (off_t) 0xb8000);
4396 };
4397 
4398     close(__svgalib_mem_fd);
4399 
4400 #ifdef DEBUG
4401 	    printf("svgalib: Opening mouse (type = %x).\n", mouse_type | mouse_modem_ctl);
4402 #endif
4403 	    if (mouse_init(mouse_device, mouse_type | mouse_modem_ctl, MOUSE_DEFAULTSAMPLERATE))
4404 		printf("svgalib: Failed to initialize mouse.\n");
4405 	    else
4406 		mouse_open = 1;
4407 
4408     /* Michael: I assume this is a misunderstanding, when svgalib was developed,
4409        there were no saved uids, thus setting effective uid sufficed... */
4410     if ( __svgalib_security_revokeallprivs == 1 ) {
4411 	setuid(getuid());
4412 	setgid(getgid());
4413     }
4414     seteuid(getuid());
4415     setegid(getgid());
4416     return retval;
4417 }
4418 
4419 int vga_addtiming( int pixelClock,
4420    		   int HDisplay,
4421                    int HSyncStart,
4422                    int HSyncEnd,
4423                    int HTotal,
4424                    int VDisplay,
4425                    int VSyncStart,
4426                    int VSyncEnd,
4427                    int VTotal,
4428                    int flags) {
4429 
4430    MonitorModeTiming mmt;
4431 
4432    mmt.pixelClock=pixelClock;
4433    mmt.HDisplay=HDisplay;
4434    mmt.HSyncStart=HSyncStart;
4435    mmt.HSyncEnd=HSyncEnd;
4436    mmt.HTotal=HTotal;
4437    mmt.VDisplay=VDisplay;
4438    mmt.VSyncStart=VSyncStart;
4439    mmt.VSyncEnd=VSyncEnd;
4440    mmt.VTotal=VTotal;
4441    mmt.flags=flags;
4442 
4443    __svgalib_addusertiming(&mmt);
4444 
4445    return 1;
4446 
4447 };
4448 
4449 int vga_addmode(int xdim, int ydim, int cols,
4450                           int xbytes, int bytespp)
4451 {
4452    int i;
4453 
4454    i=__svgalib_addmode(xdim, ydim, cols, xbytes, bytespp);
4455 
4456    return i;
4457 };
4458 
4459 
4460 #ifdef __alpha__
4461 
4462 #define vuip	volatile unsigned int *
4463 
4464 extern void sethae(unsigned long hae);
4465 
4466 static struct hae hae;
4467 
4468 int iopl(int level)
4469 {
4470     return 0;
4471 }
4472 
4473 unsigned long vga_readb(unsigned long base, unsigned long off)
4474 {
4475     unsigned long result, shift;
4476 #if !defined(CONFIG_ALPHA_JENSEN)
4477     unsigned long msb;
4478 #endif
4479 
4480     shift = (off & 0x3) * 8;
4481 #if !defined(CONFIG_ALPHA_JENSEN)
4482     if (off >= (1UL << 24)) {
4483 	msb = off & 0xf8000000;
4484 	off -= msb;
4485 	if (msb && msb != hae.cache) {
4486 	    sethae(msb);
4487 	}
4488     }
4489 #endif
4490     result = *(vuip) ((off << MEM_SHIFT) + base + MEM_TYPE_BYTE);
4491     result >>= shift;
4492     return 0xffUL & result;
4493 }
4494 
4495 unsigned long vga_readw(unsigned long base, unsigned long off)
4496 {
4497     unsigned long result, shift;
4498 #if !defined(CONFIG_ALPHA_JENSEN)
4499     unsigned long msb;
4500 #endif
4501 
4502     shift = (off & 0x3) * 8;
4503 #if !defined(CONFIG_ALPHA_JENSEN)
4504     if (off >= (1UL << 24)) {
4505 	msb = off & 0xf8000000;
4506 	off -= msb;
4507 	if (msb && msb != hae.cache) {
4508 	    sethae(msb);
4509 	}
4510     }
4511 #endif
4512     result = *(vuip) ((off << MEM_SHIFT) + base + MEM_TYPE_WORD);
4513     result >>= shift;
4514     return 0xffffUL & result;
4515 }
4516 
4517 #if defined(CONFIG_ALPHA_JENSEN)
4518 unsigned long vga_readl(unsigned long base, unsigned long off)
4519 {
4520     unsigned long result;
4521     result = *(vuip) ((off << MEM_SHIFT) + base + MEM_TYPE_LONG);
4522     return 0xffffffffUL & result;
4523 }
4524 #endif
4525 
4526 void vga_writeb(unsigned char b, unsigned long base, unsigned long off)
4527 {
4528 #if !defined(CONFIG_ALPHA_JENSEN)
4529     unsigned long msb;
4530     unsigned int w;
4531 
4532     if (off >= (1UL << 24)) {
4533 	msb = off & 0xf8000000;
4534 	off -= msb;
4535 	if (msb && msb != hae.cache) {
4536 	    sethae(msb);
4537 	}
4538     }
4539   asm("insbl %2,%1,%0": "r="(w):"ri"(off & 0x3), "r"(b));
4540     *(vuip) ((off << MEM_SHIFT) + base + MEM_TYPE_BYTE) = w;
4541 #else
4542     *(vuip) ((off << MEM_SHIFT) + base + MEM_TYPE_BYTE) = b * 0x01010101;
4543 #endif
4544 }
4545 
4546 void vga_writew(unsigned short b, unsigned long base, unsigned long off)
4547 {
4548 #if !defined(CONFIG_ALPHA_JENSEN)
4549     unsigned long msb;
4550     unsigned int w;
4551 
4552     if (off >= (1UL << 24)) {
4553 	msb = off & 0xf8000000;
4554 	off -= msb;
4555 	if (msb && msb != hae.cache) {
4556 	    sethae(msb);
4557 	}
4558     }
4559   asm("inswl %2,%1,%0": "r="(w):"ri"(off & 0x3), "r"(b));
4560     *(vuip) ((off << MEM_SHIFT) + base + MEM_TYPE_WORD) = w;
4561 #else
4562     *(vuip) ((off << MEM_SHIFT) + base + MEM_TYPE_WORD) = b * 0x00010001;
4563 #endif
4564 }
4565 
4566 #if defined(CONFIG_ALPHA_JENSEN)
4567 void vga_writel(unsigned long b, unsigned long base, unsigned long off)
4568 {
4569     *(vuip) ((off << MEM_SHIFT) + base + MEM_TYPE_LONG) = b;
4570 }
4571 
4572 #endif
4573 
4574 #endif
4575