main.c revision 71623
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 71623 2001-01-25 11:01:20Z nsouch $ 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; 5728328Ssosstatic int VGLOnDisplay; 5853013Syokotastatic unsigned int VGLCurWindow; 5930044Ssosstatic int VGLInitDone = 0; 6028328Ssos 6128328Ssosvoid 6228328SsosVGLEnd() 6328328Ssos{ 6428328Ssosstruct vt_mode smode; 6528328Ssos 6630044Ssos if (!VGLInitDone) 6730044Ssos return; 6853013Syokota VGLInitDone = 0; 6953013Syokota 7053013Syokota signal(SIGUSR1, SIG_IGN); 7153013Syokota 7253013Syokota if (VGLMem != MAP_FAILED) { 7353013Syokota VGLClear(VGLDisplay, 0); 7453013Syokota munmap(VGLMem, VGLAdpInfo.va_window_size); 7550483Syokota } 7653013Syokota 7750141Syokota if (VGLOldMode >= M_VESA_BASE) { 7850141Syokota /* ugly, but necessary */ 7950141Syokota ioctl(0, _IO('V', VGLOldMode - M_VESA_BASE), 0); 8050141Syokota if (VGLOldMode == M_VESA_800x600) { 8150141Syokota int size[3]; 8250141Syokota size[0] = 80; 8350141Syokota size[1] = 25; 8450141Syokota size[2] = 16; 8550141Syokota ioctl(0, KDRASTER, size); 8650141Syokota } 8750141Syokota } else { 8850141Syokota ioctl(0, _IO('S', VGLOldMode), 0); 8950141Syokota } 9028328Ssos ioctl(0, KDDISABIO, 0); 9128328Ssos ioctl(0, KDSETMODE, KD_TEXT); 9228328Ssos smode.mode = VT_AUTO; 9328328Ssos ioctl(0, VT_SETMODE, &smode); 9453013Syokota if (VGLBuf) 9553013Syokota free(VGLBuf); 9653013Syokota VGLBuf = NULL; 9728328Ssos free(VGLDisplay); 9853013Syokota VGLDisplay = NULL; 9930044Ssos VGLKeyboardEnd(); 10028328Ssos} 10128328Ssos 10228328Ssosstatic void 10328328SsosVGLAbort() 10428328Ssos{ 10528328Ssos VGLEnd(); 10628328Ssos exit(0); 10728328Ssos} 10828328Ssos 10928328Ssosstatic void 11028328SsosVGLSwitch() 11128328Ssos{ 11228328Ssos if (!VGLOnDisplay) 11328328Ssos VGLOnDisplay = 1; 11428328Ssos else 11528328Ssos VGLOnDisplay = 0; 11628328Ssos VGLSwitchPending = 1; 11728328Ssos signal(SIGUSR1, VGLSwitch); 11828328Ssos} 11928328Ssos 12028328Ssosint 12128328SsosVGLInit(int mode) 12228328Ssos{ 12328328Ssos struct vt_mode smode; 12453013Syokota int adptype; 12528328Ssos 12653013Syokota if (VGLInitDone) 12753013Syokota return -1; 12853013Syokota 12928328Ssos signal(SIGUSR1, VGLSwitch); 13028328Ssos signal(SIGINT, VGLAbort); 13150483Syokota signal(SIGTERM, VGLAbort); 13228328Ssos signal(SIGSEGV, VGLAbort); 13328328Ssos signal(SIGBUS, VGLAbort); 13428328Ssos 13528328Ssos VGLOnDisplay = 1; 13628328Ssos VGLSwitchPending = 0; 13728328Ssos 13853013Syokota if (ioctl(0, CONS_GET, &VGLOldMode) || ioctl(0, CONS_CURRENT, &adptype)) 13953013Syokota return -1; 14053013Syokota if (IOCGROUP(mode) == 'V') /* XXX: this is ugly */ 14153013Syokota VGLModeInfo.vi_mode = (mode & 0x0ff) + M_VESA_BASE; 14253013Syokota else 14353013Syokota VGLModeInfo.vi_mode = mode & 0x0ff; 14453013Syokota if (ioctl(0, CONS_MODEINFO, &VGLModeInfo)) /* FBIO_MODEINFO */ 14553013Syokota return -1; 14628328Ssos 14753013Syokota VGLDisplay = (VGLBitmap *)malloc(sizeof(VGLBitmap)); 14853013Syokota if (VGLDisplay == NULL) 14953013Syokota return -2; 15028328Ssos 15153013Syokota if (ioctl(0, KDENABIO, 0)) { 15253013Syokota free(VGLDisplay); 15353013Syokota return -3; 15428328Ssos } 15528328Ssos 15653013Syokota VGLInitDone = 1; 15753013Syokota 15853013Syokota /* 15953013Syokota * vi_mem_model specifies the memory model of the current video mode 16053013Syokota * in -CURRENT. 16153013Syokota */ 16253013Syokota switch (VGLModeInfo.vi_mem_model) { 16353013Syokota case V_INFO_MM_PLANAR: 16453013Syokota /* we can handle EGA/VGA planner modes only */ 16553013Syokota if (VGLModeInfo.vi_depth != 4 || VGLModeInfo.vi_planes != 4 16653013Syokota || (adptype != KD_EGA && adptype != KD_VGA)) { 16753013Syokota VGLEnd(); 16853013Syokota return -4; 16953013Syokota } 17028328Ssos VGLDisplay->Type = VIDBUF4; 17128328Ssos break; 17253013Syokota case V_INFO_MM_PACKED: 17353013Syokota /* we can do only 256 color packed modes */ 17453013Syokota if (VGLModeInfo.vi_depth != 8) { 17553013Syokota VGLEnd(); 17653013Syokota return -4; 17753013Syokota } 17828328Ssos VGLDisplay->Type = VIDBUF8; 17971623Snsouch VGLDisplay->PixelBytes = 1; 18028328Ssos break; 18153013Syokota case V_INFO_MM_VGAX: 18228328Ssos VGLDisplay->Type = VIDBUF8X; 18371623Snsouch VGLDisplay->PixelBytes = 1; 18428328Ssos break; 18570991Snsouch case V_INFO_MM_DIRECT: 18670991Snsouch VGLDisplay->PixelBytes = VGLModeInfo.vi_pixel_size; 18770991Snsouch switch (VGLDisplay->PixelBytes) { 18870991Snsouch case 2: 18970991Snsouch VGLDisplay->Type = VIDBUF16; 19070991Snsouch break; 19170991Snsouch#if notyet 19270991Snsouch case 3: 19370991Snsouch VGLDisplay->Type = VIDBUF24; 19470991Snsouch break; 19570991Snsouch#endif 19670991Snsouch case 4: 19770991Snsouch VGLDisplay->Type = VIDBUF32; 19870991Snsouch break; 19970991Snsouch default: 20070991Snsouch VGLEnd(); 20170991Snsouch return -4; 20270991Snsouch } 20370991Snsouch break; 20428328Ssos default: 20528328Ssos VGLEnd(); 20653013Syokota return -4; 20728328Ssos } 20828328Ssos 20928328Ssos ioctl(0, VT_WAITACTIVE, 0); 21028328Ssos ioctl(0, KDSETMODE, KD_GRAPHICS); 21153013Syokota if (ioctl(0, mode, 0)) { 21253013Syokota VGLEnd(); 21353013Syokota return -5; 21428328Ssos } 21553013Syokota if (ioctl(0, CONS_ADPINFO, &VGLAdpInfo)) { /* FBIO_ADPINFO */ 21653013Syokota VGLEnd(); 21753013Syokota return -6; 21853013Syokota } 21928328Ssos 22053013Syokota /* 22153013Syokota * Calculate the shadow screen buffer size. In -CURRENT, va_buffer_size 22253013Syokota * always holds the entire frame buffer size, wheather it's in the linear 22353013Syokota * mode or windowed mode. 22453013Syokota * VGLBufSize = VGLAdpInfo.va_buffer_size; 22553013Syokota * In -STABLE, va_buffer_size holds the frame buffer size, only if 22653013Syokota * the linear frame buffer mode is supported. Otherwise the field is zero. 22753013Syokota * We shall calculate the minimal size in this case: 22853013Syokota * VGLAdpInfo.va_line_width*VGLModeInfo.vi_height*VGLModeInfo.vi_planes 22953013Syokota * or 23053013Syokota * VGLAdpInfo.va_window_size*VGLModeInfo.vi_planes; 23153013Syokota * Use whichever is larger. 23253013Syokota */ 23353013Syokota if (VGLAdpInfo.va_buffer_size != 0) 23453013Syokota VGLBufSize = VGLAdpInfo.va_buffer_size; 23553013Syokota else 23653013Syokota VGLBufSize = max(VGLAdpInfo.va_line_width*VGLModeInfo.vi_height, 23753013Syokota VGLAdpInfo.va_window_size)*VGLModeInfo.vi_planes; 23853013Syokota VGLBuf = malloc(VGLBufSize); 23953013Syokota if (VGLBuf == NULL) { 24053013Syokota VGLEnd(); 24153013Syokota return -7; 24253013Syokota } 24353013Syokota 24453013Syokota#ifdef LIBVGL_DEBUG 24553013Syokota fprintf(stderr, "VGLBufSize:0x%x\n", VGLBufSize); 24653013Syokota#endif 24753013Syokota 24853013Syokota /* see if we are in the windowed buffer mode or in the linear buffer mode */ 24953013Syokota if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) { 25070991Snsouch switch (VGLDisplay->Type) { 25170991Snsouch case VIDBUF4: 25253013Syokota VGLDisplay->Type = VIDBUF4S; 25370991Snsouch break; 25470991Snsouch case VIDBUF8: 25553013Syokota VGLDisplay->Type = VIDBUF8S; 25670991Snsouch break; 25770991Snsouch case VIDBUF16: 25870991Snsouch VGLDisplay->Type = VIDBUF16S; 25970991Snsouch break; 26070991Snsouch case VIDBUF24: 26170991Snsouch VGLDisplay->Type = VIDBUF24S; 26270991Snsouch break; 26370991Snsouch case VIDBUF32: 26470991Snsouch VGLDisplay->Type = VIDBUF32S; 26570991Snsouch break; 26670991Snsouch default: 26770991Snsouch VGLEnd(); 26870991Snsouch return -8; 26970991Snsouch } 27053013Syokota } 27153013Syokota 27228328Ssos VGLMode = mode; 27353013Syokota VGLCurWindow = 0; 27428328Ssos 27553013Syokota VGLDisplay->Xsize = VGLModeInfo.vi_width; 27653013Syokota VGLDisplay->Ysize = VGLModeInfo.vi_height; 27753013Syokota VGLDisplay->VXsize = VGLAdpInfo.va_line_width 27853013Syokota *8/(VGLModeInfo.vi_depth/VGLModeInfo.vi_planes); 27953013Syokota VGLDisplay->VYsize = VGLBufSize/VGLModeInfo.vi_planes/VGLAdpInfo.va_line_width; 28053013Syokota VGLDisplay->Xorigin = 0; 28153013Syokota VGLDisplay->Yorigin = 0; 28228328Ssos 28353013Syokota VGLMem = (byte*)mmap(0, VGLAdpInfo.va_window_size, PROT_READ|PROT_WRITE, 28453013Syokota MAP_FILE, 0, 0); 28553013Syokota if (VGLMem == MAP_FAILED) { 28628328Ssos VGLEnd(); 28753013Syokota return -7; 28828328Ssos } 28953013Syokota VGLDisplay->Bitmap = VGLMem; 29028328Ssos 29128328Ssos VGLSavePalette(); 29228328Ssos 29353013Syokota#ifdef LIBVGL_DEBUG 29453013Syokota fprintf(stderr, "va_line_width:%d\n", VGLAdpInfo.va_line_width); 29553013Syokota fprintf(stderr, "VGLXsize:%d, Ysize:%d, VXsize:%d, VYsize:%d\n", 29653013Syokota VGLDisplay->Xsize, VGLDisplay->Ysize, 29753013Syokota VGLDisplay->VXsize, VGLDisplay->VYsize); 29853013Syokota#endif 29953013Syokota 30028328Ssos smode.mode = VT_PROCESS; 30128328Ssos smode.waitv = 0; 30228328Ssos smode.relsig = SIGUSR1; 30328328Ssos smode.acqsig = SIGUSR1; 30428328Ssos smode.frsig = SIGINT; 30553013Syokota if (ioctl(0, VT_SETMODE, &smode)) { 30628328Ssos VGLEnd(); 30753013Syokota return -9; 30828328Ssos } 30928328Ssos VGLTextSetFontFile((byte*)0); 31053013Syokota VGLClear(VGLDisplay, 0); 31128328Ssos return 0; 31228328Ssos} 31328328Ssos 31428328Ssosvoid 31528328SsosVGLCheckSwitch() 31628328Ssos{ 31750483Syokota while (VGLSwitchPending) { 31853013Syokota unsigned int offset; 31953013Syokota unsigned int len; 32028328Ssos int i; 32128328Ssos 32228328Ssos VGLSwitchPending = 0; 32328328Ssos if (VGLOnDisplay) { 32428328Ssos ioctl(0, KDENABIO, 0); 32528328Ssos ioctl(0, KDSETMODE, KD_GRAPHICS); 32628328Ssos ioctl(0, VGLMode, 0); 32753013Syokota VGLCurWindow = 0; 32853013Syokota VGLMem = (byte*)mmap(0, VGLAdpInfo.va_window_size, PROT_READ|PROT_WRITE, 32953013Syokota MAP_FILE, 0, 0); 33053013Syokota 33153013Syokota /* XXX: what if mmap() has failed! */ 33253013Syokota VGLDisplay->Type = VIDBUF8; /* XXX */ 33353013Syokota switch (VGLModeInfo.vi_mem_model) { 33453013Syokota case V_INFO_MM_PLANAR: 33553013Syokota if (VGLModeInfo.vi_depth == 4 && VGLModeInfo.vi_planes == 4) { 33653013Syokota if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) 33753013Syokota VGLDisplay->Type = VIDBUF4S; 33853013Syokota else 33953013Syokota VGLDisplay->Type = VIDBUF4; 34053013Syokota } else { 34153013Syokota /* shouldn't be happening */ 34253013Syokota } 34328328Ssos break; 34453013Syokota case V_INFO_MM_PACKED: 34553013Syokota if (VGLModeInfo.vi_depth == 8) { 34653013Syokota if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) 34753013Syokota VGLDisplay->Type = VIDBUF8S; 34853013Syokota else 34953013Syokota VGLDisplay->Type = VIDBUF8; 35053013Syokota } 35128328Ssos break; 35253013Syokota case V_INFO_MM_VGAX: 35353013Syokota VGLDisplay->Type = VIDBUF8X; 35453013Syokota break; 35570991Snsouch case V_INFO_MM_DIRECT: 35670991Snsouch switch (VGLModeInfo.vi_pixel_size) { 35770991Snsouch case 2: 35870991Snsouch if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) 35970991Snsouch VGLDisplay->Type = VIDBUF16S; 36070991Snsouch else 36170991Snsouch VGLDisplay->Type = VIDBUF16; 36270991Snsouch break; 36370991Snsouch case 3: 36470991Snsouch if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) 36570991Snsouch VGLDisplay->Type = VIDBUF24S; 36670991Snsouch else 36770991Snsouch VGLDisplay->Type = VIDBUF24; 36870991Snsouch break; 36970991Snsouch case 4: 37070991Snsouch if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) 37170991Snsouch VGLDisplay->Type = VIDBUF32S; 37270991Snsouch else 37370991Snsouch VGLDisplay->Type = VIDBUF32; 37470991Snsouch break; 37570991Snsouch default: 37670991Snsouch /* shouldn't be happening */ 37770991Snsouch break; 37870991Snsouch } 37928328Ssos default: 38053013Syokota /* shouldn't be happening */ 38128328Ssos break; 38228328Ssos } 38353013Syokota 38453013Syokota VGLDisplay->Bitmap = VGLMem; 38553013Syokota VGLDisplay->Xsize = VGLModeInfo.vi_width; 38653013Syokota VGLDisplay->Ysize = VGLModeInfo.vi_height; 38753013Syokota VGLSetVScreenSize(VGLDisplay, VGLDisplay->VXsize, VGLDisplay->VYsize); 38853013Syokota VGLPanScreen(VGLDisplay, VGLDisplay->Xorigin, VGLDisplay->Yorigin); 38953013Syokota switch (VGLDisplay->Type) { 39053013Syokota case VIDBUF4S: 39153013Syokota outb(0x3c6, 0xff); 39253013Syokota outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */ 39353013Syokota outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */ 39453013Syokota for (offset = 0; offset < VGLBufSize/VGLModeInfo.vi_planes; 39553013Syokota offset += len) { 39653013Syokota VGLSetSegment(offset); 39753013Syokota len = min(VGLBufSize/VGLModeInfo.vi_planes - offset, 39853013Syokota VGLAdpInfo.va_window_size); 39953013Syokota for (i = 0; i < VGLModeInfo.vi_planes; i++) { 40053013Syokota outb(0x3c4, 0x02); 40153013Syokota outb(0x3c5, 0x01<<i); 40253013Syokota bcopy(&VGLBuf[i*VGLBufSize/VGLModeInfo.vi_planes + offset], 40353013Syokota VGLMem, len); 40453013Syokota } 40553013Syokota } 40653013Syokota break; 40753013Syokota case VIDBUF4: 40853013Syokota case VIDBUF8X: 40953013Syokota outb(0x3c6, 0xff); 41053013Syokota outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */ 41153013Syokota outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */ 41253013Syokota for (i = 0; i < VGLModeInfo.vi_planes; i++) { 41353013Syokota outb(0x3c4, 0x02); 41453013Syokota outb(0x3c5, 0x01<<i); 41553013Syokota bcopy(&VGLBuf[i*VGLAdpInfo.va_window_size], VGLMem, 41653013Syokota VGLAdpInfo.va_window_size); 41753013Syokota } 41853013Syokota break; 41953013Syokota case VIDBUF8: 42053013Syokota case VIDBUF8S: 42170991Snsouch case VIDBUF16: 42270991Snsouch case VIDBUF16S: 42370991Snsouch case VIDBUF24: 42470991Snsouch case VIDBUF24S: 42570991Snsouch case VIDBUF32: 42670991Snsouch case VIDBUF32S: 42753013Syokota for (offset = 0; offset < VGLBufSize; offset += len) { 42853013Syokota VGLSetSegment(offset); 42953013Syokota len = min(VGLBufSize - offset, VGLAdpInfo.va_window_size); 43053013Syokota bcopy(&VGLBuf[offset], VGLMem, len); 43153013Syokota } 43253013Syokota break; 43353013Syokota } 43453013Syokota VGLRestorePalette(); 43553013Syokota ioctl(0, VT_RELDISP, VT_ACKACQ); 43628328Ssos } 43728328Ssos else { 43853013Syokota switch (VGLDisplay->Type) { 43953013Syokota case VIDBUF4S: 44053013Syokota for (offset = 0; offset < VGLBufSize/VGLModeInfo.vi_planes; 44153013Syokota offset += len) { 44253013Syokota VGLSetSegment(offset); 44353013Syokota len = min(VGLBufSize/VGLModeInfo.vi_planes - offset, 44453013Syokota VGLAdpInfo.va_window_size); 44553013Syokota for (i = 0; i < VGLModeInfo.vi_planes; i++) { 44653013Syokota outb(0x3ce, 0x04); 44753013Syokota outb(0x3cf, i); 44853013Syokota bcopy(VGLMem, &VGLBuf[i*VGLBufSize/VGLModeInfo.vi_planes + offset], 44953013Syokota len); 45053013Syokota } 45153013Syokota } 45253013Syokota break; 45353013Syokota case VIDBUF4: 45453013Syokota case VIDBUF8X: 45553013Syokota /* 45653013Syokota * NOTE: the saved buffer is NOT in the MEMBUF format which 45753013Syokota * the ordinary memory bitmap object is stored in. XXX 45853013Syokota */ 45953013Syokota for (i = 0; i < VGLModeInfo.vi_planes; i++) { 46053013Syokota outb(0x3ce, 0x04); 46153013Syokota outb(0x3cf, i); 46253013Syokota bcopy(VGLMem, &VGLBuf[i*VGLAdpInfo.va_window_size], 46353013Syokota VGLAdpInfo.va_window_size); 46453013Syokota } 46553013Syokota break; 46653013Syokota case VIDBUF8: 46753013Syokota case VIDBUF8S: 46870991Snsouch case VIDBUF16: 46970991Snsouch case VIDBUF16S: 47070991Snsouch case VIDBUF24: 47170991Snsouch case VIDBUF24S: 47270991Snsouch case VIDBUF32: 47370991Snsouch case VIDBUF32S: 47453013Syokota for (offset = 0; offset < VGLBufSize; offset += len) { 47553013Syokota VGLSetSegment(offset); 47653013Syokota len = min(VGLBufSize - offset, VGLAdpInfo.va_window_size); 47753013Syokota bcopy(VGLMem, &VGLBuf[offset], len); 47853013Syokota } 47953013Syokota break; 48028328Ssos } 48153013Syokota VGLMem = MAP_FAILED; 48253013Syokota munmap(VGLDisplay->Bitmap, VGLAdpInfo.va_window_size); 48328328Ssos ioctl(0, VGLOldMode, 0); 48428328Ssos ioctl(0, KDSETMODE, KD_TEXT); 48528328Ssos ioctl(0, KDDISABIO, 0); 48628328Ssos ioctl(0, VT_RELDISP, VT_TRUE); 48728328Ssos VGLDisplay->Bitmap = VGLBuf; 48828328Ssos VGLDisplay->Type = MEMBUF; 48953013Syokota VGLDisplay->Xsize = VGLDisplay->VXsize; 49053013Syokota VGLDisplay->Ysize = VGLDisplay->VYsize; 49150483Syokota while (!VGLOnDisplay) pause(); 49228328Ssos } 49328328Ssos } 49428328Ssos} 49553013Syokota 49653013Syokotaint 49753013SyokotaVGLSetSegment(unsigned int offset) 49853013Syokota{ 49953013Syokota if (offset/VGLAdpInfo.va_window_size != VGLCurWindow) { 50053013Syokota ioctl(0, CONS_SETWINORG, offset); /* FBIO_SETWINORG */ 50153013Syokota VGLCurWindow = offset/VGLAdpInfo.va_window_size; 50253013Syokota } 50353013Syokota return (offset%VGLAdpInfo.va_window_size); 50453013Syokota} 50553013Syokota 50653013Syokotaint 50753013SyokotaVGLSetVScreenSize(VGLBitmap *object, int VXsize, int VYsize) 50853013Syokota{ 50953013Syokota if (VXsize < object->Xsize || VYsize < object->Ysize) 51053013Syokota return -1; 51153013Syokota if (object->Type == MEMBUF) 51253013Syokota return -1; 51353013Syokota if (ioctl(0, FBIO_SETLINEWIDTH, &VXsize)) 51453013Syokota return -1; 51553013Syokota ioctl(0, CONS_ADPINFO, &VGLAdpInfo); /* FBIO_ADPINFO */ 51653013Syokota object->VXsize = VGLAdpInfo.va_line_width 51753013Syokota *8/(VGLModeInfo.vi_depth/VGLModeInfo.vi_planes); 51853013Syokota object->VYsize = VGLBufSize/VGLModeInfo.vi_planes/VGLAdpInfo.va_line_width; 51953013Syokota if (VYsize < object->VYsize) 52053013Syokota object->VYsize = VYsize; 52153013Syokota 52253013Syokota#ifdef LIBVGL_DEBUG 52353013Syokota fprintf(stderr, "new size: VGLXsize:%d, Ysize:%d, VXsize:%d, VYsize:%d\n", 52453013Syokota object->Xsize, object->Ysize, object->VXsize, object->VYsize); 52553013Syokota#endif 52653013Syokota 52753013Syokota return 0; 52853013Syokota} 52953013Syokota 53053013Syokotaint 53153013SyokotaVGLPanScreen(VGLBitmap *object, int x, int y) 53253013Syokota{ 53353013Syokota video_display_start_t origin; 53453013Syokota 53553013Syokota if (x < 0 || x + object->Xsize > object->VXsize 53653013Syokota || y < 0 || y + object->Ysize > object->VYsize) 53753013Syokota return -1; 53853013Syokota if (object->Type == MEMBUF) 53953013Syokota return 0; 54053013Syokota origin.x = x; 54153013Syokota origin.y = y; 54253013Syokota if (ioctl(0, FBIO_SETDISPSTART, &origin)) 54353013Syokota return -1; 54453013Syokota object->Xorigin = x; 54553013Syokota object->Yorigin = y; 54653013Syokota 54753013Syokota#ifdef LIBVGL_DEBUG 54853013Syokota fprintf(stderr, "new origin: (%d, %d)\n", x, y); 54953013Syokota#endif 55053013Syokota 55153013Syokota return 0; 55253013Syokota} 553