main.c revision 50476
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 * $FreeBSD: head/lib/libvgl/main.c 50476 1999-08-28 00:22:10Z peter $ 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 40VGLBitmap *VGLDisplay; 41 42static int VGLMode; 43static int VGLOldMode; 44static byte *VGLBuf; 45static byte *VGLMem; 46static int VGLSwitchPending; 47static int VGLOnDisplay; 48static int VGLInitDone = 0; 49 50void 51VGLEnd() 52{ 53struct 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 if (VGLOldMode >= M_VESA_BASE) { 65 /* ugly, but necessary */ 66 ioctl(0, _IO('V', VGLOldMode - M_VESA_BASE), 0); 67 if (VGLOldMode == M_VESA_800x600) { 68 int size[3]; 69 size[0] = 80; 70 size[1] = 25; 71 size[2] = 16; 72 ioctl(0, KDRASTER, size); 73 } 74 } else { 75 ioctl(0, _IO('S', VGLOldMode), 0); 76 } 77 ioctl(0, KDDISABIO, 0); 78 ioctl(0, KDSETMODE, KD_TEXT); 79 smode.mode = VT_AUTO; 80 ioctl(0, VT_SETMODE, &smode); 81 free(VGLBuf); 82 free(VGLDisplay); 83 VGLKeyboardEnd(); 84} 85 86static void 87VGLAbort() 88{ 89 VGLEnd(); 90 exit(0); 91} 92 93static void 94VGLSwitch() 95{ 96 if (!VGLOnDisplay) 97 VGLOnDisplay = 1; 98 else 99 VGLOnDisplay = 0; 100 VGLSwitchPending = 1; 101 signal(SIGUSR1, VGLSwitch); 102} 103 104int 105VGLInit(int mode) 106{ 107 struct vt_mode smode; 108 struct winsize winsz; 109 int error; 110 111 signal(SIGUSR1, VGLSwitch); 112 signal(SIGINT, VGLAbort); 113 signal(SIGSEGV, VGLAbort); 114 signal(SIGBUS, VGLAbort); 115 116 VGLOnDisplay = 1; 117 VGLSwitchPending = 0; 118 119 ioctl(0, CONS_GET, &VGLOldMode); 120 121 VGLMem = (byte*)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_FILE, 122 open("/dev/mem", O_RDWR), 0xA0000); 123 if (VGLMem <= (byte*)0) 124 return 1; 125 126 VGLBuf = (byte*)malloc(256*1024); 127 if (VGLBuf == NULL) 128 return 1; 129 130 VGLDisplay = (VGLBitmap*) malloc(sizeof(VGLBitmap)); 131 if (VGLDisplay == NULL) { 132 free(VGLBuf); 133 return 1; 134 } 135 136 switch (mode) { 137 case SW_BG640x480: case SW_CG640x480: 138 VGLDisplay->Type = VIDBUF4; 139 break; 140 case SW_VGA_CG320: 141 VGLDisplay->Type = VIDBUF8; 142 break; 143 case SW_VGA_MODEX: 144 VGLDisplay->Type = VIDBUF8X; 145 break; 146 default: 147 VGLEnd(); 148 return 1; 149 } 150 151 if ((error = ioctl(0, KDENABIO, 0))) 152 return error; 153 154 ioctl(0, VT_WAITACTIVE, 0); 155 ioctl(0, KDSETMODE, KD_GRAPHICS); 156 if ((error = ioctl(0, mode, 0))) { 157 ioctl(0, KDSETMODE, KD_TEXT); 158 ioctl(0, KDDISABIO, 0); 159 return error; 160 } 161 162 VGLMode = mode; 163 164 outb(0x3c4, 0x02); 165 outb(0x3c5, 0x0f); 166 bzero(VGLMem, 64*1024); 167 168 if (ioctl(0, TIOCGWINSZ, &winsz)) { 169 VGLEnd(); 170 return 1; 171 } 172 173 VGLDisplay->Bitmap = VGLMem; 174 VGLDisplay->Xsize = winsz.ws_xpixel; 175 VGLDisplay->Ysize = winsz.ws_ypixel; 176 VGLSavePalette(); 177 178 smode.mode = VT_PROCESS; 179 smode.waitv = 0; 180 smode.relsig = SIGUSR1; 181 smode.acqsig = SIGUSR1; 182 smode.frsig = SIGINT; 183 if (ioctl(0, VT_SETMODE, &smode) == -1) { 184 VGLEnd(); 185 return 1; 186 } 187 VGLTextSetFontFile((byte*)0); 188 VGLInitDone = 1; 189 return 0; 190} 191 192void 193VGLCheckSwitch() 194{ 195 if (VGLSwitchPending) { 196 int i; 197 198 VGLSwitchPending = 0; 199 if (VGLOnDisplay) { 200 ioctl(0, KDENABIO, 0); 201 ioctl(0, KDSETMODE, KD_GRAPHICS); 202 ioctl(0, VGLMode, 0); 203 outb(0x3c6, 0xff); 204 for (i=0; i<4; i++) { 205 outb(0x3c4, 0x02); 206 outb(0x3c5, 0x01<<i); 207 bcopy(&VGLBuf[i*64*1024], VGLMem, 64*1024); 208 } 209 VGLRestorePalette(); 210 ioctl(0, VT_RELDISP, VT_ACKACQ); 211 VGLDisplay->Bitmap = VGLMem; 212 switch (VGLMode) { 213 case SW_BG640x480: case SW_CG640x480: 214 VGLDisplay->Type = VIDBUF4; 215 break; 216 case SW_VGA_CG320: 217 VGLDisplay->Type = VIDBUF8; 218 break; 219 case SW_VGA_MODEX: 220 VGLDisplay->Type = VIDBUF8X; 221 break; 222 default: 223 VGLDisplay->Type = VIDBUF8; /* XXX */ 224 break; 225 } 226 } 227 else { 228 for (i=0; i<4; i++) { 229 outb(0x3ce, 0x04); 230 outb(0x3cf, i); 231 bcopy(VGLMem, &VGLBuf[i*64*1024], 64*1024); 232 } 233 ioctl(0, VGLOldMode, 0); 234 ioctl(0, KDSETMODE, KD_TEXT); 235 ioctl(0, KDDISABIO, 0); 236 ioctl(0, VT_RELDISP, VT_TRUE); 237 VGLDisplay->Bitmap = VGLBuf; 238 VGLDisplay->Type = MEMBUF; 239 } 240 } 241 while (!VGLOnDisplay) pause(); 242} 243 244