xref: /freebsd/lib/libvgl/main.c (revision 380a989b3223d455375b4fae70fd0b9bdd43bafb)
1 /*-
2  * Copyright (c) 1991-1997 S�ren Schmidt
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer
10  *    in this position and unchanged.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software withough specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  *  $Id: main.c,v 1.1 1997/08/17 21:09:34 sos Exp $
29  */
30 
31 #include <stdio.h>
32 #include <sys/types.h>
33 #include <sys/signal.h>
34 #include <sys/file.h>
35 #include <sys/ioctl.h>
36 #include <sys/mman.h>
37 #include <machine/console.h>
38 #include "vgl.h"
39 
40 VGLBitmap *VGLDisplay;
41 
42 static int VGLMode;
43 static int VGLOldMode;
44 static byte *VGLBuf;
45 static byte *VGLMem;
46 static int VGLSwitchPending;
47 static int VGLOnDisplay;
48 static int VGLInitDone = 0;
49 
50 void
51 VGLEnd()
52 {
53 struct vt_mode smode;
54 
55   if (!VGLInitDone)
56     return;
57 /*
58   while (!VGLOnDisplay) pause();
59   VGLCheckSwitch();;
60 */
61   outb(0x3c4, 0x02);
62   outb(0x3c5, 0x0f);
63   bzero(VGLMem, 64*1024);
64   ioctl(0, _IO('S', VGLOldMode), 0);
65   ioctl(0, KDDISABIO, 0);
66   ioctl(0, KDSETMODE, KD_TEXT);
67   smode.mode = VT_AUTO;
68   ioctl(0, VT_SETMODE, &smode);
69   free(VGLBuf);
70   free(VGLDisplay);
71   VGLKeyboardEnd();
72 }
73 
74 static void
75 VGLAbort()
76 {
77   VGLEnd();
78   exit(0);
79 }
80 
81 static void
82 VGLSwitch()
83 {
84   if (!VGLOnDisplay)
85     VGLOnDisplay = 1;
86   else
87     VGLOnDisplay = 0;
88   VGLSwitchPending = 1;
89   signal(SIGUSR1, VGLSwitch);
90 }
91 
92 int
93 VGLInit(int mode)
94 {
95   struct vt_mode smode;
96   struct winsize winsz;
97   int error;
98 
99   signal(SIGUSR1, VGLSwitch);
100   signal(SIGINT, VGLAbort);
101   signal(SIGSEGV, VGLAbort);
102   signal(SIGBUS, VGLAbort);
103 
104   VGLOnDisplay = 1;
105   VGLSwitchPending = 0;
106 
107   ioctl(0, CONS_GET, &VGLOldMode);
108 
109   VGLMem = (byte*)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_FILE,
110                           open("/dev/mem", O_RDWR), 0xA0000);
111   if (VGLMem <= (byte*)0)
112     return 1;
113 
114   VGLBuf = (byte*)malloc(256*1024);
115   if (VGLBuf == NULL)
116     return 1;
117 
118   VGLDisplay = (VGLBitmap*) malloc(sizeof(VGLBitmap));
119   if (VGLDisplay == NULL) {
120     free(VGLBuf);
121     return 1;
122   }
123 
124   switch (mode) {
125   case SW_BG640x480: case SW_CG640x480:
126     VGLDisplay->Type = VIDBUF4;
127     break;
128   case SW_VGA_CG320:
129     VGLDisplay->Type = VIDBUF8;
130     break;
131   case SW_VGA_MODEX:
132     VGLDisplay->Type = VIDBUF8X;
133     break;
134   default:
135     VGLEnd();
136     return 1;
137   }
138 
139   if ((error = ioctl(0, KDENABIO, 0)))
140     return error;
141 
142   ioctl(0, VT_WAITACTIVE, 0);
143   ioctl(0, KDSETMODE, KD_GRAPHICS);
144   if ((error = ioctl(0, mode, 0))) {
145     ioctl(0, KDSETMODE, KD_TEXT);
146     ioctl(0, KDDISABIO, 0);
147     return error;
148   }
149 
150   VGLMode = mode;
151 
152   outb(0x3c4, 0x02);
153   outb(0x3c5, 0x0f);
154   bzero(VGLMem, 64*1024);
155 
156   if (ioctl(0, TIOCGWINSZ, &winsz)) {
157     VGLEnd();
158     return 1;
159   }
160 
161   VGLDisplay->Bitmap = VGLMem;
162   VGLDisplay->Xsize = winsz.ws_xpixel;
163   VGLDisplay->Ysize = winsz.ws_ypixel;
164   VGLSavePalette();
165 
166   smode.mode = VT_PROCESS;
167   smode.waitv = 0;
168   smode.relsig = SIGUSR1;
169   smode.acqsig = SIGUSR1;
170   smode.frsig  = SIGINT;
171   if (ioctl(0, VT_SETMODE, &smode) == -1) {
172     VGLEnd();
173     return 1;
174   }
175   VGLTextSetFontFile((byte*)0);
176   VGLInitDone = 1;
177   return 0;
178 }
179 
180 void
181 VGLCheckSwitch()
182 {
183   if (VGLSwitchPending) {
184     int i;
185 
186     VGLSwitchPending = 0;
187     if (VGLOnDisplay) {
188       ioctl(0, KDENABIO, 0);
189       ioctl(0, KDSETMODE, KD_GRAPHICS);
190       ioctl(0, VGLMode, 0);
191       outb(0x3c6, 0xff);
192       for (i=0; i<4; i++) {
193         outb(0x3c4, 0x02);
194         outb(0x3c5, 0x01<<i);
195         bcopy(&VGLBuf[i*64*1024], VGLMem, 64*1024);
196       }
197       VGLRestorePalette();
198       ioctl(0, VT_RELDISP, VT_ACKACQ);
199       VGLDisplay->Bitmap = VGLMem;
200       switch (VGLMode) {
201       case SW_BG640x480: case SW_CG640x480:
202         VGLDisplay->Type = VIDBUF4;
203         break;
204       case SW_VGA_CG320:
205         VGLDisplay->Type = VIDBUF8;
206         break;
207       case SW_VGA_MODEX:
208         VGLDisplay->Type = VIDBUF8X;
209         break;
210       default:
211         VGLDisplay->Type = VIDBUF8;			/* XXX */
212         break;
213       }
214     }
215     else {
216       for (i=0; i<4; i++) {
217         outb(0x3ce, 0x04);
218         outb(0x3cf, i);
219         bcopy(VGLMem, &VGLBuf[i*64*1024], 64*1024);
220       }
221       ioctl(0, VGLOldMode, 0);
222       ioctl(0, KDSETMODE, KD_TEXT);
223       ioctl(0, KDDISABIO, 0);
224       ioctl(0, VT_RELDISP, VT_TRUE);
225       VGLDisplay->Bitmap = VGLBuf;
226       VGLDisplay->Type = MEMBUF;
227     }
228   }
229   while (!VGLOnDisplay) pause();
230 }
231 
232