main.c revision 80270
128328Ssos/*- 228328Ssos * Copyright (c) 1991-1997 S�ren Schmidt 328328Ssos * All rights reserved. 428328Ssos * 528328Ssos * Redistribution and use in source and binary forms, with or without 628328Ssos * modification, are permitted provided that the following conditions 728328Ssos * are met: 828328Ssos * 1. Redistributions of source code must retain the above copyright 928328Ssos * notice, this list of conditions and the following disclaimer 1028328Ssos * in this position and unchanged. 1128328Ssos * 2. Redistributions in binary form must reproduce the above copyright 1228328Ssos * notice, this list of conditions and the following disclaimer in the 1328328Ssos * documentation and/or other materials provided with the distribution. 1428328Ssos * 3. The name of the author may not be used to endorse or promote products 1528328Ssos * derived from this software withough specific prior written permission 1628328Ssos * 1728328Ssos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1828328Ssos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1928328Ssos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2028328Ssos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2128328Ssos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2228328Ssos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2328328Ssos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2428328Ssos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2528328Ssos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2628328Ssos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2728328Ssos * 2850476Speter * $FreeBSD: head/lib/libvgl/main.c 80270 2001-07-24 11:15:20Z yokota $ 2928328Ssos */ 3028328Ssos 3128328Ssos#include <stdio.h> 3228328Ssos#include <sys/types.h> 3328328Ssos#include <sys/signal.h> 3428328Ssos#include <sys/file.h> 3528328Ssos#include <sys/ioctl.h> 3628328Ssos#include <sys/mman.h> 3766834Sphk#include <sys/fbio.h> 3866834Sphk#include <sys/kbio.h> 3966834Sphk#include <sys/consio.h> 4028328Ssos#include "vgl.h" 4128328Ssos 4270991Snsouch/* XXX Direct Color 24bits modes unsupported */ 4370991Snsouch 4453013Syokota#define min(x, y) (((x) < (y)) ? (x) : (y)) 4553013Syokota#define max(x, y) (((x) > (y)) ? (x) : (y)) 4653013Syokota 4728328SsosVGLBitmap *VGLDisplay; 4853013Syokotavideo_info_t VGLModeInfo; 4953013Syokotavideo_adapter_info_t VGLAdpInfo; 5053013Syokotabyte *VGLBuf; 5128328Ssos 5228328Ssosstatic int VGLMode; 5328328Ssosstatic int VGLOldMode; 5453013Syokotastatic size_t VGLBufSize; 5553013Syokotastatic byte *VGLMem = MAP_FAILED; 5628328Ssosstatic int VGLSwitchPending; 5780270Syokotastatic int VGLAbortPending; 5828328Ssosstatic int VGLOnDisplay; 5953013Syokotastatic unsigned int VGLCurWindow; 6030044Ssosstatic int VGLInitDone = 0; 6176852Ssobomaxstatic vid_info_t VGLOldVInfo; 6228328Ssos 6328328Ssosvoid 6428328SsosVGLEnd() 6528328Ssos{ 6628328Ssosstruct vt_mode smode; 6728328Ssos 6830044Ssos if (!VGLInitDone) 6930044Ssos return; 7053013Syokota VGLInitDone = 0; 7180270Syokota VGLSwitchPending = 0; 7280270Syokota VGLAbortPending = 0; 7353013Syokota 7453013Syokota signal(SIGUSR1, SIG_IGN); 7553013Syokota 7653013Syokota if (VGLMem != MAP_FAILED) { 7753013Syokota VGLClear(VGLDisplay, 0); 7853013Syokota munmap(VGLMem, VGLAdpInfo.va_window_size); 7950483Syokota } 8053013Syokota 8150141Syokota if (VGLOldMode >= M_VESA_BASE) { 8250141Syokota /* ugly, but necessary */ 8350141Syokota ioctl(0, _IO('V', VGLOldMode - M_VESA_BASE), 0); 8450141Syokota if (VGLOldMode == M_VESA_800x600) { 8550141Syokota int size[3]; 8676852Ssobomax size[0] = VGLOldVInfo.mv_csz; 8776852Ssobomax size[1] = VGLOldVInfo.mv_rsz; 8850141Syokota size[2] = 16; 8950141Syokota ioctl(0, KDRASTER, size); 9050141Syokota } 9150141Syokota } else { 9250141Syokota ioctl(0, _IO('S', VGLOldMode), 0); 9350141Syokota } 9428328Ssos ioctl(0, KDDISABIO, 0); 9528328Ssos ioctl(0, KDSETMODE, KD_TEXT); 9628328Ssos smode.mode = VT_AUTO; 9728328Ssos ioctl(0, VT_SETMODE, &smode); 9853013Syokota if (VGLBuf) 9953013Syokota free(VGLBuf); 10053013Syokota VGLBuf = NULL; 10128328Ssos free(VGLDisplay); 10253013Syokota VGLDisplay = NULL; 10330044Ssos VGLKeyboardEnd(); 10428328Ssos} 10528328Ssos 10628328Ssosstatic void 10728328SsosVGLAbort() 10828328Ssos{ 10980270Syokota VGLAbortPending = 1; 11080270Syokota signal(SIGINT, SIG_IGN); 11180270Syokota signal(SIGTERM, SIG_IGN); 11280270Syokota signal(SIGSEGV, SIG_IGN); 11380270Syokota signal(SIGBUS, SIG_IGN); 11480270Syokota signal(SIGUSR2, SIG_IGN); 11528328Ssos} 11628328Ssos 11728328Ssosstatic void 11828328SsosVGLSwitch() 11928328Ssos{ 12028328Ssos if (!VGLOnDisplay) 12128328Ssos VGLOnDisplay = 1; 12228328Ssos else 12328328Ssos VGLOnDisplay = 0; 12428328Ssos VGLSwitchPending = 1; 12528328Ssos signal(SIGUSR1, VGLSwitch); 12628328Ssos} 12728328Ssos 12828328Ssosint 12928328SsosVGLInit(int mode) 13028328Ssos{ 13128328Ssos struct vt_mode smode; 13253013Syokota int adptype; 13328328Ssos 13453013Syokota if (VGLInitDone) 13553013Syokota return -1; 13653013Syokota 13728328Ssos signal(SIGUSR1, VGLSwitch); 13828328Ssos signal(SIGINT, VGLAbort); 13950483Syokota signal(SIGTERM, VGLAbort); 14028328Ssos signal(SIGSEGV, VGLAbort); 14128328Ssos signal(SIGBUS, VGLAbort); 14280270Syokota signal(SIGUSR2, SIG_IGN); 14328328Ssos 14428328Ssos VGLOnDisplay = 1; 14528328Ssos VGLSwitchPending = 0; 14680270Syokota VGLAbortPending = 0; 14728328Ssos 14853013Syokota if (ioctl(0, CONS_GET, &VGLOldMode) || ioctl(0, CONS_CURRENT, &adptype)) 14953013Syokota return -1; 15053013Syokota if (IOCGROUP(mode) == 'V') /* XXX: this is ugly */ 15153013Syokota VGLModeInfo.vi_mode = (mode & 0x0ff) + M_VESA_BASE; 15253013Syokota else 15353013Syokota VGLModeInfo.vi_mode = mode & 0x0ff; 15453013Syokota if (ioctl(0, CONS_MODEINFO, &VGLModeInfo)) /* FBIO_MODEINFO */ 15553013Syokota return -1; 15628328Ssos 15771643Ssobomax /* If current mode is VESA_800x600 then save its geometry to restore later */ 15876852Ssobomax if ((VGLOldMode >= M_VESA_BASE) && (VGLOldMode == M_VESA_800x600)) { 15976852Ssobomax VGLOldVInfo.size = sizeof(VGLOldVInfo); 16076852Ssobomax if (ioctl(0, CONS_GETINFO, &VGLOldVInfo)) 16171643Ssobomax return -1; 16276852Ssobomax } 16371643Ssobomax 16453013Syokota VGLDisplay = (VGLBitmap *)malloc(sizeof(VGLBitmap)); 16553013Syokota if (VGLDisplay == NULL) 16653013Syokota return -2; 16728328Ssos 16853013Syokota if (ioctl(0, KDENABIO, 0)) { 16953013Syokota free(VGLDisplay); 17053013Syokota return -3; 17128328Ssos } 17228328Ssos 17353013Syokota VGLInitDone = 1; 17453013Syokota 17553013Syokota /* 17653013Syokota * vi_mem_model specifies the memory model of the current video mode 17753013Syokota * in -CURRENT. 17853013Syokota */ 17953013Syokota switch (VGLModeInfo.vi_mem_model) { 18053013Syokota case V_INFO_MM_PLANAR: 18153013Syokota /* we can handle EGA/VGA planner modes only */ 18253013Syokota if (VGLModeInfo.vi_depth != 4 || VGLModeInfo.vi_planes != 4 18353013Syokota || (adptype != KD_EGA && adptype != KD_VGA)) { 18453013Syokota VGLEnd(); 18553013Syokota return -4; 18653013Syokota } 18728328Ssos VGLDisplay->Type = VIDBUF4; 18828328Ssos break; 18953013Syokota case V_INFO_MM_PACKED: 19053013Syokota /* we can do only 256 color packed modes */ 19153013Syokota if (VGLModeInfo.vi_depth != 8) { 19253013Syokota VGLEnd(); 19353013Syokota return -4; 19453013Syokota } 19528328Ssos VGLDisplay->Type = VIDBUF8; 19671623Snsouch VGLDisplay->PixelBytes = 1; 19728328Ssos break; 19853013Syokota case V_INFO_MM_VGAX: 19928328Ssos VGLDisplay->Type = VIDBUF8X; 20071623Snsouch VGLDisplay->PixelBytes = 1; 20128328Ssos break; 20270991Snsouch case V_INFO_MM_DIRECT: 20370991Snsouch VGLDisplay->PixelBytes = VGLModeInfo.vi_pixel_size; 20470991Snsouch switch (VGLDisplay->PixelBytes) { 20570991Snsouch case 2: 20670991Snsouch VGLDisplay->Type = VIDBUF16; 20770991Snsouch break; 20870991Snsouch#if notyet 20970991Snsouch case 3: 21070991Snsouch VGLDisplay->Type = VIDBUF24; 21170991Snsouch break; 21270991Snsouch#endif 21370991Snsouch case 4: 21470991Snsouch VGLDisplay->Type = VIDBUF32; 21570991Snsouch break; 21670991Snsouch default: 21770991Snsouch VGLEnd(); 21870991Snsouch return -4; 21970991Snsouch } 22070991Snsouch break; 22128328Ssos default: 22228328Ssos VGLEnd(); 22353013Syokota return -4; 22428328Ssos } 22528328Ssos 22628328Ssos ioctl(0, VT_WAITACTIVE, 0); 22728328Ssos ioctl(0, KDSETMODE, KD_GRAPHICS); 22853013Syokota if (ioctl(0, mode, 0)) { 22953013Syokota VGLEnd(); 23053013Syokota return -5; 23128328Ssos } 23253013Syokota if (ioctl(0, CONS_ADPINFO, &VGLAdpInfo)) { /* FBIO_ADPINFO */ 23353013Syokota VGLEnd(); 23453013Syokota return -6; 23553013Syokota } 23628328Ssos 23753013Syokota /* 23853013Syokota * Calculate the shadow screen buffer size. In -CURRENT, va_buffer_size 23953013Syokota * always holds the entire frame buffer size, wheather it's in the linear 24053013Syokota * mode or windowed mode. 24153013Syokota * VGLBufSize = VGLAdpInfo.va_buffer_size; 24253013Syokota * In -STABLE, va_buffer_size holds the frame buffer size, only if 24353013Syokota * the linear frame buffer mode is supported. Otherwise the field is zero. 24453013Syokota * We shall calculate the minimal size in this case: 24553013Syokota * VGLAdpInfo.va_line_width*VGLModeInfo.vi_height*VGLModeInfo.vi_planes 24653013Syokota * or 24753013Syokota * VGLAdpInfo.va_window_size*VGLModeInfo.vi_planes; 24853013Syokota * Use whichever is larger. 24953013Syokota */ 25053013Syokota if (VGLAdpInfo.va_buffer_size != 0) 25153013Syokota VGLBufSize = VGLAdpInfo.va_buffer_size; 25253013Syokota else 25353013Syokota VGLBufSize = max(VGLAdpInfo.va_line_width*VGLModeInfo.vi_height, 25453013Syokota VGLAdpInfo.va_window_size)*VGLModeInfo.vi_planes; 25553013Syokota VGLBuf = malloc(VGLBufSize); 25653013Syokota if (VGLBuf == NULL) { 25753013Syokota VGLEnd(); 25853013Syokota return -7; 25953013Syokota } 26053013Syokota 26153013Syokota#ifdef LIBVGL_DEBUG 26253013Syokota fprintf(stderr, "VGLBufSize:0x%x\n", VGLBufSize); 26353013Syokota#endif 26453013Syokota 26553013Syokota /* see if we are in the windowed buffer mode or in the linear buffer mode */ 26653013Syokota if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) { 26770991Snsouch switch (VGLDisplay->Type) { 26870991Snsouch case VIDBUF4: 26953013Syokota VGLDisplay->Type = VIDBUF4S; 27070991Snsouch break; 27170991Snsouch case VIDBUF8: 27253013Syokota VGLDisplay->Type = VIDBUF8S; 27370991Snsouch break; 27470991Snsouch case VIDBUF16: 27570991Snsouch VGLDisplay->Type = VIDBUF16S; 27670991Snsouch break; 27770991Snsouch case VIDBUF24: 27870991Snsouch VGLDisplay->Type = VIDBUF24S; 27970991Snsouch break; 28070991Snsouch case VIDBUF32: 28170991Snsouch VGLDisplay->Type = VIDBUF32S; 28270991Snsouch break; 28370991Snsouch default: 28470991Snsouch VGLEnd(); 28570991Snsouch return -8; 28670991Snsouch } 28753013Syokota } 28853013Syokota 28928328Ssos VGLMode = mode; 29053013Syokota VGLCurWindow = 0; 29128328Ssos 29253013Syokota VGLDisplay->Xsize = VGLModeInfo.vi_width; 29353013Syokota VGLDisplay->Ysize = VGLModeInfo.vi_height; 29453013Syokota VGLDisplay->VXsize = VGLAdpInfo.va_line_width 29553013Syokota *8/(VGLModeInfo.vi_depth/VGLModeInfo.vi_planes); 29653013Syokota VGLDisplay->VYsize = VGLBufSize/VGLModeInfo.vi_planes/VGLAdpInfo.va_line_width; 29753013Syokota VGLDisplay->Xorigin = 0; 29853013Syokota VGLDisplay->Yorigin = 0; 29928328Ssos 30053013Syokota VGLMem = (byte*)mmap(0, VGLAdpInfo.va_window_size, PROT_READ|PROT_WRITE, 30153013Syokota MAP_FILE, 0, 0); 30253013Syokota if (VGLMem == MAP_FAILED) { 30328328Ssos VGLEnd(); 30453013Syokota return -7; 30528328Ssos } 30653013Syokota VGLDisplay->Bitmap = VGLMem; 30728328Ssos 30828328Ssos VGLSavePalette(); 30928328Ssos 31053013Syokota#ifdef LIBVGL_DEBUG 31153013Syokota fprintf(stderr, "va_line_width:%d\n", VGLAdpInfo.va_line_width); 31253013Syokota fprintf(stderr, "VGLXsize:%d, Ysize:%d, VXsize:%d, VYsize:%d\n", 31353013Syokota VGLDisplay->Xsize, VGLDisplay->Ysize, 31453013Syokota VGLDisplay->VXsize, VGLDisplay->VYsize); 31553013Syokota#endif 31653013Syokota 31728328Ssos smode.mode = VT_PROCESS; 31828328Ssos smode.waitv = 0; 31928328Ssos smode.relsig = SIGUSR1; 32028328Ssos smode.acqsig = SIGUSR1; 32128328Ssos smode.frsig = SIGINT; 32253013Syokota if (ioctl(0, VT_SETMODE, &smode)) { 32328328Ssos VGLEnd(); 32453013Syokota return -9; 32528328Ssos } 32628328Ssos VGLTextSetFontFile((byte*)0); 32753013Syokota VGLClear(VGLDisplay, 0); 32828328Ssos return 0; 32928328Ssos} 33028328Ssos 33128328Ssosvoid 33228328SsosVGLCheckSwitch() 33328328Ssos{ 33480270Syokota if (VGLAbortPending) { 33580270Syokota VGLEnd(); 33680270Syokota exit(0); 33780270Syokota } 33850483Syokota while (VGLSwitchPending) { 33953013Syokota unsigned int offset; 34053013Syokota unsigned int len; 34128328Ssos int i; 34228328Ssos 34328328Ssos VGLSwitchPending = 0; 34428328Ssos if (VGLOnDisplay) { 34528328Ssos ioctl(0, KDENABIO, 0); 34628328Ssos ioctl(0, KDSETMODE, KD_GRAPHICS); 34728328Ssos ioctl(0, VGLMode, 0); 34853013Syokota VGLCurWindow = 0; 34953013Syokota VGLMem = (byte*)mmap(0, VGLAdpInfo.va_window_size, PROT_READ|PROT_WRITE, 35053013Syokota MAP_FILE, 0, 0); 35153013Syokota 35253013Syokota /* XXX: what if mmap() has failed! */ 35353013Syokota VGLDisplay->Type = VIDBUF8; /* XXX */ 35453013Syokota switch (VGLModeInfo.vi_mem_model) { 35553013Syokota case V_INFO_MM_PLANAR: 35653013Syokota if (VGLModeInfo.vi_depth == 4 && VGLModeInfo.vi_planes == 4) { 35753013Syokota if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) 35853013Syokota VGLDisplay->Type = VIDBUF4S; 35953013Syokota else 36053013Syokota VGLDisplay->Type = VIDBUF4; 36153013Syokota } else { 36253013Syokota /* shouldn't be happening */ 36353013Syokota } 36428328Ssos break; 36553013Syokota case V_INFO_MM_PACKED: 36653013Syokota if (VGLModeInfo.vi_depth == 8) { 36753013Syokota if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) 36853013Syokota VGLDisplay->Type = VIDBUF8S; 36953013Syokota else 37053013Syokota VGLDisplay->Type = VIDBUF8; 37153013Syokota } 37228328Ssos break; 37353013Syokota case V_INFO_MM_VGAX: 37453013Syokota VGLDisplay->Type = VIDBUF8X; 37553013Syokota break; 37670991Snsouch case V_INFO_MM_DIRECT: 37770991Snsouch switch (VGLModeInfo.vi_pixel_size) { 37870991Snsouch case 2: 37970991Snsouch if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) 38070991Snsouch VGLDisplay->Type = VIDBUF16S; 38170991Snsouch else 38270991Snsouch VGLDisplay->Type = VIDBUF16; 38370991Snsouch break; 38470991Snsouch case 3: 38570991Snsouch if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) 38670991Snsouch VGLDisplay->Type = VIDBUF24S; 38770991Snsouch else 38870991Snsouch VGLDisplay->Type = VIDBUF24; 38970991Snsouch break; 39070991Snsouch case 4: 39170991Snsouch if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) 39270991Snsouch VGLDisplay->Type = VIDBUF32S; 39370991Snsouch else 39470991Snsouch VGLDisplay->Type = VIDBUF32; 39570991Snsouch break; 39670991Snsouch default: 39770991Snsouch /* shouldn't be happening */ 39870991Snsouch break; 39970991Snsouch } 40028328Ssos default: 40153013Syokota /* shouldn't be happening */ 40228328Ssos break; 40328328Ssos } 40453013Syokota 40553013Syokota VGLDisplay->Bitmap = VGLMem; 40653013Syokota VGLDisplay->Xsize = VGLModeInfo.vi_width; 40753013Syokota VGLDisplay->Ysize = VGLModeInfo.vi_height; 40853013Syokota VGLSetVScreenSize(VGLDisplay, VGLDisplay->VXsize, VGLDisplay->VYsize); 40953013Syokota VGLPanScreen(VGLDisplay, VGLDisplay->Xorigin, VGLDisplay->Yorigin); 41053013Syokota switch (VGLDisplay->Type) { 41153013Syokota case VIDBUF4S: 41253013Syokota outb(0x3c6, 0xff); 41353013Syokota outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */ 41453013Syokota outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */ 41553013Syokota for (offset = 0; offset < VGLBufSize/VGLModeInfo.vi_planes; 41653013Syokota offset += len) { 41753013Syokota VGLSetSegment(offset); 41853013Syokota len = min(VGLBufSize/VGLModeInfo.vi_planes - offset, 41953013Syokota VGLAdpInfo.va_window_size); 42053013Syokota for (i = 0; i < VGLModeInfo.vi_planes; i++) { 42153013Syokota outb(0x3c4, 0x02); 42253013Syokota outb(0x3c5, 0x01<<i); 42353013Syokota bcopy(&VGLBuf[i*VGLBufSize/VGLModeInfo.vi_planes + offset], 42453013Syokota VGLMem, len); 42553013Syokota } 42653013Syokota } 42753013Syokota break; 42853013Syokota case VIDBUF4: 42953013Syokota case VIDBUF8X: 43053013Syokota outb(0x3c6, 0xff); 43153013Syokota outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */ 43253013Syokota outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */ 43353013Syokota for (i = 0; i < VGLModeInfo.vi_planes; i++) { 43453013Syokota outb(0x3c4, 0x02); 43553013Syokota outb(0x3c5, 0x01<<i); 43653013Syokota bcopy(&VGLBuf[i*VGLAdpInfo.va_window_size], VGLMem, 43753013Syokota VGLAdpInfo.va_window_size); 43853013Syokota } 43953013Syokota break; 44053013Syokota case VIDBUF8: 44153013Syokota case VIDBUF8S: 44270991Snsouch case VIDBUF16: 44370991Snsouch case VIDBUF16S: 44470991Snsouch case VIDBUF24: 44570991Snsouch case VIDBUF24S: 44670991Snsouch case VIDBUF32: 44770991Snsouch case VIDBUF32S: 44853013Syokota for (offset = 0; offset < VGLBufSize; offset += len) { 44953013Syokota VGLSetSegment(offset); 45053013Syokota len = min(VGLBufSize - offset, VGLAdpInfo.va_window_size); 45153013Syokota bcopy(&VGLBuf[offset], VGLMem, len); 45253013Syokota } 45353013Syokota break; 45453013Syokota } 45553013Syokota VGLRestorePalette(); 45653013Syokota ioctl(0, VT_RELDISP, VT_ACKACQ); 45728328Ssos } 45828328Ssos else { 45953013Syokota switch (VGLDisplay->Type) { 46053013Syokota case VIDBUF4S: 46153013Syokota for (offset = 0; offset < VGLBufSize/VGLModeInfo.vi_planes; 46253013Syokota offset += len) { 46353013Syokota VGLSetSegment(offset); 46453013Syokota len = min(VGLBufSize/VGLModeInfo.vi_planes - offset, 46553013Syokota VGLAdpInfo.va_window_size); 46653013Syokota for (i = 0; i < VGLModeInfo.vi_planes; i++) { 46753013Syokota outb(0x3ce, 0x04); 46853013Syokota outb(0x3cf, i); 46953013Syokota bcopy(VGLMem, &VGLBuf[i*VGLBufSize/VGLModeInfo.vi_planes + offset], 47053013Syokota len); 47153013Syokota } 47253013Syokota } 47353013Syokota break; 47453013Syokota case VIDBUF4: 47553013Syokota case VIDBUF8X: 47653013Syokota /* 47753013Syokota * NOTE: the saved buffer is NOT in the MEMBUF format which 47853013Syokota * the ordinary memory bitmap object is stored in. XXX 47953013Syokota */ 48053013Syokota for (i = 0; i < VGLModeInfo.vi_planes; i++) { 48153013Syokota outb(0x3ce, 0x04); 48253013Syokota outb(0x3cf, i); 48353013Syokota bcopy(VGLMem, &VGLBuf[i*VGLAdpInfo.va_window_size], 48453013Syokota VGLAdpInfo.va_window_size); 48553013Syokota } 48653013Syokota break; 48753013Syokota case VIDBUF8: 48853013Syokota case VIDBUF8S: 48970991Snsouch case VIDBUF16: 49070991Snsouch case VIDBUF16S: 49170991Snsouch case VIDBUF24: 49270991Snsouch case VIDBUF24S: 49370991Snsouch case VIDBUF32: 49470991Snsouch case VIDBUF32S: 49553013Syokota for (offset = 0; offset < VGLBufSize; offset += len) { 49653013Syokota VGLSetSegment(offset); 49753013Syokota len = min(VGLBufSize - offset, VGLAdpInfo.va_window_size); 49853013Syokota bcopy(VGLMem, &VGLBuf[offset], len); 49953013Syokota } 50053013Syokota break; 50128328Ssos } 50253013Syokota VGLMem = MAP_FAILED; 50353013Syokota munmap(VGLDisplay->Bitmap, VGLAdpInfo.va_window_size); 50428328Ssos ioctl(0, VGLOldMode, 0); 50528328Ssos ioctl(0, KDSETMODE, KD_TEXT); 50628328Ssos ioctl(0, KDDISABIO, 0); 50728328Ssos ioctl(0, VT_RELDISP, VT_TRUE); 50828328Ssos VGLDisplay->Bitmap = VGLBuf; 50928328Ssos VGLDisplay->Type = MEMBUF; 51053013Syokota VGLDisplay->Xsize = VGLDisplay->VXsize; 51153013Syokota VGLDisplay->Ysize = VGLDisplay->VYsize; 51250483Syokota while (!VGLOnDisplay) pause(); 51328328Ssos } 51428328Ssos } 51528328Ssos} 51653013Syokota 51753013Syokotaint 51853013SyokotaVGLSetSegment(unsigned int offset) 51953013Syokota{ 52053013Syokota if (offset/VGLAdpInfo.va_window_size != VGLCurWindow) { 52153013Syokota ioctl(0, CONS_SETWINORG, offset); /* FBIO_SETWINORG */ 52253013Syokota VGLCurWindow = offset/VGLAdpInfo.va_window_size; 52353013Syokota } 52453013Syokota return (offset%VGLAdpInfo.va_window_size); 52553013Syokota} 52653013Syokota 52753013Syokotaint 52853013SyokotaVGLSetVScreenSize(VGLBitmap *object, int VXsize, int VYsize) 52953013Syokota{ 53053013Syokota if (VXsize < object->Xsize || VYsize < object->Ysize) 53153013Syokota return -1; 53253013Syokota if (object->Type == MEMBUF) 53353013Syokota return -1; 53453013Syokota if (ioctl(0, FBIO_SETLINEWIDTH, &VXsize)) 53553013Syokota return -1; 53653013Syokota ioctl(0, CONS_ADPINFO, &VGLAdpInfo); /* FBIO_ADPINFO */ 53753013Syokota object->VXsize = VGLAdpInfo.va_line_width 53853013Syokota *8/(VGLModeInfo.vi_depth/VGLModeInfo.vi_planes); 53953013Syokota object->VYsize = VGLBufSize/VGLModeInfo.vi_planes/VGLAdpInfo.va_line_width; 54053013Syokota if (VYsize < object->VYsize) 54153013Syokota object->VYsize = VYsize; 54253013Syokota 54353013Syokota#ifdef LIBVGL_DEBUG 54453013Syokota fprintf(stderr, "new size: VGLXsize:%d, Ysize:%d, VXsize:%d, VYsize:%d\n", 54553013Syokota object->Xsize, object->Ysize, object->VXsize, object->VYsize); 54653013Syokota#endif 54753013Syokota 54853013Syokota return 0; 54953013Syokota} 55053013Syokota 55153013Syokotaint 55253013SyokotaVGLPanScreen(VGLBitmap *object, int x, int y) 55353013Syokota{ 55453013Syokota video_display_start_t origin; 55553013Syokota 55653013Syokota if (x < 0 || x + object->Xsize > object->VXsize 55753013Syokota || y < 0 || y + object->Ysize > object->VYsize) 55853013Syokota return -1; 55953013Syokota if (object->Type == MEMBUF) 56053013Syokota return 0; 56153013Syokota origin.x = x; 56253013Syokota origin.y = y; 56353013Syokota if (ioctl(0, FBIO_SETDISPSTART, &origin)) 56453013Syokota return -1; 56553013Syokota object->Xorigin = x; 56653013Syokota object->Yorigin = y; 56753013Syokota 56853013Syokota#ifdef LIBVGL_DEBUG 56953013Syokota fprintf(stderr, "new origin: (%d, %d)\n", x, y); 57053013Syokota#endif 57153013Syokota 57253013Syokota return 0; 57353013Syokota} 574