main.c revision 76852
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 76852 2001-05-19 17:05:52Z sobomax $ 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; 6076852Ssobomaxstatic vid_info_t VGLOldVInfo; 6128328Ssos 6228328Ssosvoid 6328328SsosVGLEnd() 6428328Ssos{ 6528328Ssosstruct vt_mode smode; 6628328Ssos 6730044Ssos if (!VGLInitDone) 6830044Ssos return; 6953013Syokota VGLInitDone = 0; 7053013Syokota 7153013Syokota signal(SIGUSR1, SIG_IGN); 7253013Syokota 7353013Syokota if (VGLMem != MAP_FAILED) { 7453013Syokota VGLClear(VGLDisplay, 0); 7553013Syokota munmap(VGLMem, VGLAdpInfo.va_window_size); 7650483Syokota } 7753013Syokota 7850141Syokota if (VGLOldMode >= M_VESA_BASE) { 7950141Syokota /* ugly, but necessary */ 8050141Syokota ioctl(0, _IO('V', VGLOldMode - M_VESA_BASE), 0); 8150141Syokota if (VGLOldMode == M_VESA_800x600) { 8250141Syokota int size[3]; 8376852Ssobomax size[0] = VGLOldVInfo.mv_csz; 8476852Ssobomax size[1] = VGLOldVInfo.mv_rsz; 8550141Syokota size[2] = 16; 8650141Syokota ioctl(0, KDRASTER, size); 8750141Syokota } 8850141Syokota } else { 8950141Syokota ioctl(0, _IO('S', VGLOldMode), 0); 9050141Syokota } 9128328Ssos ioctl(0, KDDISABIO, 0); 9228328Ssos ioctl(0, KDSETMODE, KD_TEXT); 9328328Ssos smode.mode = VT_AUTO; 9428328Ssos ioctl(0, VT_SETMODE, &smode); 9553013Syokota if (VGLBuf) 9653013Syokota free(VGLBuf); 9753013Syokota VGLBuf = NULL; 9828328Ssos free(VGLDisplay); 9953013Syokota VGLDisplay = NULL; 10030044Ssos VGLKeyboardEnd(); 10128328Ssos} 10228328Ssos 10328328Ssosstatic void 10428328SsosVGLAbort() 10528328Ssos{ 10628328Ssos VGLEnd(); 10728328Ssos exit(0); 10828328Ssos} 10928328Ssos 11028328Ssosstatic void 11128328SsosVGLSwitch() 11228328Ssos{ 11328328Ssos if (!VGLOnDisplay) 11428328Ssos VGLOnDisplay = 1; 11528328Ssos else 11628328Ssos VGLOnDisplay = 0; 11728328Ssos VGLSwitchPending = 1; 11828328Ssos signal(SIGUSR1, VGLSwitch); 11928328Ssos} 12028328Ssos 12128328Ssosint 12228328SsosVGLInit(int mode) 12328328Ssos{ 12428328Ssos struct vt_mode smode; 12553013Syokota int adptype; 12628328Ssos 12753013Syokota if (VGLInitDone) 12853013Syokota return -1; 12953013Syokota 13028328Ssos signal(SIGUSR1, VGLSwitch); 13128328Ssos signal(SIGINT, VGLAbort); 13250483Syokota signal(SIGTERM, VGLAbort); 13328328Ssos signal(SIGSEGV, VGLAbort); 13428328Ssos signal(SIGBUS, VGLAbort); 13528328Ssos 13628328Ssos VGLOnDisplay = 1; 13728328Ssos VGLSwitchPending = 0; 13828328Ssos 13953013Syokota if (ioctl(0, CONS_GET, &VGLOldMode) || ioctl(0, CONS_CURRENT, &adptype)) 14053013Syokota return -1; 14153013Syokota if (IOCGROUP(mode) == 'V') /* XXX: this is ugly */ 14253013Syokota VGLModeInfo.vi_mode = (mode & 0x0ff) + M_VESA_BASE; 14353013Syokota else 14453013Syokota VGLModeInfo.vi_mode = mode & 0x0ff; 14553013Syokota if (ioctl(0, CONS_MODEINFO, &VGLModeInfo)) /* FBIO_MODEINFO */ 14653013Syokota return -1; 14728328Ssos 14871643Ssobomax /* If current mode is VESA_800x600 then save its geometry to restore later */ 14976852Ssobomax if ((VGLOldMode >= M_VESA_BASE) && (VGLOldMode == M_VESA_800x600)) { 15076852Ssobomax VGLOldVInfo.size = sizeof(VGLOldVInfo); 15176852Ssobomax if (ioctl(0, CONS_GETINFO, &VGLOldVInfo)) 15271643Ssobomax return -1; 15376852Ssobomax } 15471643Ssobomax 15553013Syokota VGLDisplay = (VGLBitmap *)malloc(sizeof(VGLBitmap)); 15653013Syokota if (VGLDisplay == NULL) 15753013Syokota return -2; 15828328Ssos 15953013Syokota if (ioctl(0, KDENABIO, 0)) { 16053013Syokota free(VGLDisplay); 16153013Syokota return -3; 16228328Ssos } 16328328Ssos 16453013Syokota VGLInitDone = 1; 16553013Syokota 16653013Syokota /* 16753013Syokota * vi_mem_model specifies the memory model of the current video mode 16853013Syokota * in -CURRENT. 16953013Syokota */ 17053013Syokota switch (VGLModeInfo.vi_mem_model) { 17153013Syokota case V_INFO_MM_PLANAR: 17253013Syokota /* we can handle EGA/VGA planner modes only */ 17353013Syokota if (VGLModeInfo.vi_depth != 4 || VGLModeInfo.vi_planes != 4 17453013Syokota || (adptype != KD_EGA && adptype != KD_VGA)) { 17553013Syokota VGLEnd(); 17653013Syokota return -4; 17753013Syokota } 17828328Ssos VGLDisplay->Type = VIDBUF4; 17928328Ssos break; 18053013Syokota case V_INFO_MM_PACKED: 18153013Syokota /* we can do only 256 color packed modes */ 18253013Syokota if (VGLModeInfo.vi_depth != 8) { 18353013Syokota VGLEnd(); 18453013Syokota return -4; 18553013Syokota } 18628328Ssos VGLDisplay->Type = VIDBUF8; 18771623Snsouch VGLDisplay->PixelBytes = 1; 18828328Ssos break; 18953013Syokota case V_INFO_MM_VGAX: 19028328Ssos VGLDisplay->Type = VIDBUF8X; 19171623Snsouch VGLDisplay->PixelBytes = 1; 19228328Ssos break; 19370991Snsouch case V_INFO_MM_DIRECT: 19470991Snsouch VGLDisplay->PixelBytes = VGLModeInfo.vi_pixel_size; 19570991Snsouch switch (VGLDisplay->PixelBytes) { 19670991Snsouch case 2: 19770991Snsouch VGLDisplay->Type = VIDBUF16; 19870991Snsouch break; 19970991Snsouch#if notyet 20070991Snsouch case 3: 20170991Snsouch VGLDisplay->Type = VIDBUF24; 20270991Snsouch break; 20370991Snsouch#endif 20470991Snsouch case 4: 20570991Snsouch VGLDisplay->Type = VIDBUF32; 20670991Snsouch break; 20770991Snsouch default: 20870991Snsouch VGLEnd(); 20970991Snsouch return -4; 21070991Snsouch } 21170991Snsouch break; 21228328Ssos default: 21328328Ssos VGLEnd(); 21453013Syokota return -4; 21528328Ssos } 21628328Ssos 21728328Ssos ioctl(0, VT_WAITACTIVE, 0); 21828328Ssos ioctl(0, KDSETMODE, KD_GRAPHICS); 21953013Syokota if (ioctl(0, mode, 0)) { 22053013Syokota VGLEnd(); 22153013Syokota return -5; 22228328Ssos } 22353013Syokota if (ioctl(0, CONS_ADPINFO, &VGLAdpInfo)) { /* FBIO_ADPINFO */ 22453013Syokota VGLEnd(); 22553013Syokota return -6; 22653013Syokota } 22728328Ssos 22853013Syokota /* 22953013Syokota * Calculate the shadow screen buffer size. In -CURRENT, va_buffer_size 23053013Syokota * always holds the entire frame buffer size, wheather it's in the linear 23153013Syokota * mode or windowed mode. 23253013Syokota * VGLBufSize = VGLAdpInfo.va_buffer_size; 23353013Syokota * In -STABLE, va_buffer_size holds the frame buffer size, only if 23453013Syokota * the linear frame buffer mode is supported. Otherwise the field is zero. 23553013Syokota * We shall calculate the minimal size in this case: 23653013Syokota * VGLAdpInfo.va_line_width*VGLModeInfo.vi_height*VGLModeInfo.vi_planes 23753013Syokota * or 23853013Syokota * VGLAdpInfo.va_window_size*VGLModeInfo.vi_planes; 23953013Syokota * Use whichever is larger. 24053013Syokota */ 24153013Syokota if (VGLAdpInfo.va_buffer_size != 0) 24253013Syokota VGLBufSize = VGLAdpInfo.va_buffer_size; 24353013Syokota else 24453013Syokota VGLBufSize = max(VGLAdpInfo.va_line_width*VGLModeInfo.vi_height, 24553013Syokota VGLAdpInfo.va_window_size)*VGLModeInfo.vi_planes; 24653013Syokota VGLBuf = malloc(VGLBufSize); 24753013Syokota if (VGLBuf == NULL) { 24853013Syokota VGLEnd(); 24953013Syokota return -7; 25053013Syokota } 25153013Syokota 25253013Syokota#ifdef LIBVGL_DEBUG 25353013Syokota fprintf(stderr, "VGLBufSize:0x%x\n", VGLBufSize); 25453013Syokota#endif 25553013Syokota 25653013Syokota /* see if we are in the windowed buffer mode or in the linear buffer mode */ 25753013Syokota if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) { 25870991Snsouch switch (VGLDisplay->Type) { 25970991Snsouch case VIDBUF4: 26053013Syokota VGLDisplay->Type = VIDBUF4S; 26170991Snsouch break; 26270991Snsouch case VIDBUF8: 26353013Syokota VGLDisplay->Type = VIDBUF8S; 26470991Snsouch break; 26570991Snsouch case VIDBUF16: 26670991Snsouch VGLDisplay->Type = VIDBUF16S; 26770991Snsouch break; 26870991Snsouch case VIDBUF24: 26970991Snsouch VGLDisplay->Type = VIDBUF24S; 27070991Snsouch break; 27170991Snsouch case VIDBUF32: 27270991Snsouch VGLDisplay->Type = VIDBUF32S; 27370991Snsouch break; 27470991Snsouch default: 27570991Snsouch VGLEnd(); 27670991Snsouch return -8; 27770991Snsouch } 27853013Syokota } 27953013Syokota 28028328Ssos VGLMode = mode; 28153013Syokota VGLCurWindow = 0; 28228328Ssos 28353013Syokota VGLDisplay->Xsize = VGLModeInfo.vi_width; 28453013Syokota VGLDisplay->Ysize = VGLModeInfo.vi_height; 28553013Syokota VGLDisplay->VXsize = VGLAdpInfo.va_line_width 28653013Syokota *8/(VGLModeInfo.vi_depth/VGLModeInfo.vi_planes); 28753013Syokota VGLDisplay->VYsize = VGLBufSize/VGLModeInfo.vi_planes/VGLAdpInfo.va_line_width; 28853013Syokota VGLDisplay->Xorigin = 0; 28953013Syokota VGLDisplay->Yorigin = 0; 29028328Ssos 29153013Syokota VGLMem = (byte*)mmap(0, VGLAdpInfo.va_window_size, PROT_READ|PROT_WRITE, 29253013Syokota MAP_FILE, 0, 0); 29353013Syokota if (VGLMem == MAP_FAILED) { 29428328Ssos VGLEnd(); 29553013Syokota return -7; 29628328Ssos } 29753013Syokota VGLDisplay->Bitmap = VGLMem; 29828328Ssos 29928328Ssos VGLSavePalette(); 30028328Ssos 30153013Syokota#ifdef LIBVGL_DEBUG 30253013Syokota fprintf(stderr, "va_line_width:%d\n", VGLAdpInfo.va_line_width); 30353013Syokota fprintf(stderr, "VGLXsize:%d, Ysize:%d, VXsize:%d, VYsize:%d\n", 30453013Syokota VGLDisplay->Xsize, VGLDisplay->Ysize, 30553013Syokota VGLDisplay->VXsize, VGLDisplay->VYsize); 30653013Syokota#endif 30753013Syokota 30828328Ssos smode.mode = VT_PROCESS; 30928328Ssos smode.waitv = 0; 31028328Ssos smode.relsig = SIGUSR1; 31128328Ssos smode.acqsig = SIGUSR1; 31228328Ssos smode.frsig = SIGINT; 31353013Syokota if (ioctl(0, VT_SETMODE, &smode)) { 31428328Ssos VGLEnd(); 31553013Syokota return -9; 31628328Ssos } 31728328Ssos VGLTextSetFontFile((byte*)0); 31853013Syokota VGLClear(VGLDisplay, 0); 31928328Ssos return 0; 32028328Ssos} 32128328Ssos 32228328Ssosvoid 32328328SsosVGLCheckSwitch() 32428328Ssos{ 32550483Syokota while (VGLSwitchPending) { 32653013Syokota unsigned int offset; 32753013Syokota unsigned int len; 32828328Ssos int i; 32928328Ssos 33028328Ssos VGLSwitchPending = 0; 33128328Ssos if (VGLOnDisplay) { 33228328Ssos ioctl(0, KDENABIO, 0); 33328328Ssos ioctl(0, KDSETMODE, KD_GRAPHICS); 33428328Ssos ioctl(0, VGLMode, 0); 33553013Syokota VGLCurWindow = 0; 33653013Syokota VGLMem = (byte*)mmap(0, VGLAdpInfo.va_window_size, PROT_READ|PROT_WRITE, 33753013Syokota MAP_FILE, 0, 0); 33853013Syokota 33953013Syokota /* XXX: what if mmap() has failed! */ 34053013Syokota VGLDisplay->Type = VIDBUF8; /* XXX */ 34153013Syokota switch (VGLModeInfo.vi_mem_model) { 34253013Syokota case V_INFO_MM_PLANAR: 34353013Syokota if (VGLModeInfo.vi_depth == 4 && VGLModeInfo.vi_planes == 4) { 34453013Syokota if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) 34553013Syokota VGLDisplay->Type = VIDBUF4S; 34653013Syokota else 34753013Syokota VGLDisplay->Type = VIDBUF4; 34853013Syokota } else { 34953013Syokota /* shouldn't be happening */ 35053013Syokota } 35128328Ssos break; 35253013Syokota case V_INFO_MM_PACKED: 35353013Syokota if (VGLModeInfo.vi_depth == 8) { 35453013Syokota if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) 35553013Syokota VGLDisplay->Type = VIDBUF8S; 35653013Syokota else 35753013Syokota VGLDisplay->Type = VIDBUF8; 35853013Syokota } 35928328Ssos break; 36053013Syokota case V_INFO_MM_VGAX: 36153013Syokota VGLDisplay->Type = VIDBUF8X; 36253013Syokota break; 36370991Snsouch case V_INFO_MM_DIRECT: 36470991Snsouch switch (VGLModeInfo.vi_pixel_size) { 36570991Snsouch case 2: 36670991Snsouch if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) 36770991Snsouch VGLDisplay->Type = VIDBUF16S; 36870991Snsouch else 36970991Snsouch VGLDisplay->Type = VIDBUF16; 37070991Snsouch break; 37170991Snsouch case 3: 37270991Snsouch if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) 37370991Snsouch VGLDisplay->Type = VIDBUF24S; 37470991Snsouch else 37570991Snsouch VGLDisplay->Type = VIDBUF24; 37670991Snsouch break; 37770991Snsouch case 4: 37870991Snsouch if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) 37970991Snsouch VGLDisplay->Type = VIDBUF32S; 38070991Snsouch else 38170991Snsouch VGLDisplay->Type = VIDBUF32; 38270991Snsouch break; 38370991Snsouch default: 38470991Snsouch /* shouldn't be happening */ 38570991Snsouch break; 38670991Snsouch } 38728328Ssos default: 38853013Syokota /* shouldn't be happening */ 38928328Ssos break; 39028328Ssos } 39153013Syokota 39253013Syokota VGLDisplay->Bitmap = VGLMem; 39353013Syokota VGLDisplay->Xsize = VGLModeInfo.vi_width; 39453013Syokota VGLDisplay->Ysize = VGLModeInfo.vi_height; 39553013Syokota VGLSetVScreenSize(VGLDisplay, VGLDisplay->VXsize, VGLDisplay->VYsize); 39653013Syokota VGLPanScreen(VGLDisplay, VGLDisplay->Xorigin, VGLDisplay->Yorigin); 39753013Syokota switch (VGLDisplay->Type) { 39853013Syokota case VIDBUF4S: 39953013Syokota outb(0x3c6, 0xff); 40053013Syokota outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */ 40153013Syokota outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */ 40253013Syokota for (offset = 0; offset < VGLBufSize/VGLModeInfo.vi_planes; 40353013Syokota offset += len) { 40453013Syokota VGLSetSegment(offset); 40553013Syokota len = min(VGLBufSize/VGLModeInfo.vi_planes - offset, 40653013Syokota VGLAdpInfo.va_window_size); 40753013Syokota for (i = 0; i < VGLModeInfo.vi_planes; i++) { 40853013Syokota outb(0x3c4, 0x02); 40953013Syokota outb(0x3c5, 0x01<<i); 41053013Syokota bcopy(&VGLBuf[i*VGLBufSize/VGLModeInfo.vi_planes + offset], 41153013Syokota VGLMem, len); 41253013Syokota } 41353013Syokota } 41453013Syokota break; 41553013Syokota case VIDBUF4: 41653013Syokota case VIDBUF8X: 41753013Syokota outb(0x3c6, 0xff); 41853013Syokota outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */ 41953013Syokota outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */ 42053013Syokota for (i = 0; i < VGLModeInfo.vi_planes; i++) { 42153013Syokota outb(0x3c4, 0x02); 42253013Syokota outb(0x3c5, 0x01<<i); 42353013Syokota bcopy(&VGLBuf[i*VGLAdpInfo.va_window_size], VGLMem, 42453013Syokota VGLAdpInfo.va_window_size); 42553013Syokota } 42653013Syokota break; 42753013Syokota case VIDBUF8: 42853013Syokota case VIDBUF8S: 42970991Snsouch case VIDBUF16: 43070991Snsouch case VIDBUF16S: 43170991Snsouch case VIDBUF24: 43270991Snsouch case VIDBUF24S: 43370991Snsouch case VIDBUF32: 43470991Snsouch case VIDBUF32S: 43553013Syokota for (offset = 0; offset < VGLBufSize; offset += len) { 43653013Syokota VGLSetSegment(offset); 43753013Syokota len = min(VGLBufSize - offset, VGLAdpInfo.va_window_size); 43853013Syokota bcopy(&VGLBuf[offset], VGLMem, len); 43953013Syokota } 44053013Syokota break; 44153013Syokota } 44253013Syokota VGLRestorePalette(); 44353013Syokota ioctl(0, VT_RELDISP, VT_ACKACQ); 44428328Ssos } 44528328Ssos else { 44653013Syokota switch (VGLDisplay->Type) { 44753013Syokota case VIDBUF4S: 44853013Syokota for (offset = 0; offset < VGLBufSize/VGLModeInfo.vi_planes; 44953013Syokota offset += len) { 45053013Syokota VGLSetSegment(offset); 45153013Syokota len = min(VGLBufSize/VGLModeInfo.vi_planes - offset, 45253013Syokota VGLAdpInfo.va_window_size); 45353013Syokota for (i = 0; i < VGLModeInfo.vi_planes; i++) { 45453013Syokota outb(0x3ce, 0x04); 45553013Syokota outb(0x3cf, i); 45653013Syokota bcopy(VGLMem, &VGLBuf[i*VGLBufSize/VGLModeInfo.vi_planes + offset], 45753013Syokota len); 45853013Syokota } 45953013Syokota } 46053013Syokota break; 46153013Syokota case VIDBUF4: 46253013Syokota case VIDBUF8X: 46353013Syokota /* 46453013Syokota * NOTE: the saved buffer is NOT in the MEMBUF format which 46553013Syokota * the ordinary memory bitmap object is stored in. XXX 46653013Syokota */ 46753013Syokota for (i = 0; i < VGLModeInfo.vi_planes; i++) { 46853013Syokota outb(0x3ce, 0x04); 46953013Syokota outb(0x3cf, i); 47053013Syokota bcopy(VGLMem, &VGLBuf[i*VGLAdpInfo.va_window_size], 47153013Syokota VGLAdpInfo.va_window_size); 47253013Syokota } 47353013Syokota break; 47453013Syokota case VIDBUF8: 47553013Syokota case VIDBUF8S: 47670991Snsouch case VIDBUF16: 47770991Snsouch case VIDBUF16S: 47870991Snsouch case VIDBUF24: 47970991Snsouch case VIDBUF24S: 48070991Snsouch case VIDBUF32: 48170991Snsouch case VIDBUF32S: 48253013Syokota for (offset = 0; offset < VGLBufSize; offset += len) { 48353013Syokota VGLSetSegment(offset); 48453013Syokota len = min(VGLBufSize - offset, VGLAdpInfo.va_window_size); 48553013Syokota bcopy(VGLMem, &VGLBuf[offset], len); 48653013Syokota } 48753013Syokota break; 48828328Ssos } 48953013Syokota VGLMem = MAP_FAILED; 49053013Syokota munmap(VGLDisplay->Bitmap, VGLAdpInfo.va_window_size); 49128328Ssos ioctl(0, VGLOldMode, 0); 49228328Ssos ioctl(0, KDSETMODE, KD_TEXT); 49328328Ssos ioctl(0, KDDISABIO, 0); 49428328Ssos ioctl(0, VT_RELDISP, VT_TRUE); 49528328Ssos VGLDisplay->Bitmap = VGLBuf; 49628328Ssos VGLDisplay->Type = MEMBUF; 49753013Syokota VGLDisplay->Xsize = VGLDisplay->VXsize; 49853013Syokota VGLDisplay->Ysize = VGLDisplay->VYsize; 49950483Syokota while (!VGLOnDisplay) pause(); 50028328Ssos } 50128328Ssos } 50228328Ssos} 50353013Syokota 50453013Syokotaint 50553013SyokotaVGLSetSegment(unsigned int offset) 50653013Syokota{ 50753013Syokota if (offset/VGLAdpInfo.va_window_size != VGLCurWindow) { 50853013Syokota ioctl(0, CONS_SETWINORG, offset); /* FBIO_SETWINORG */ 50953013Syokota VGLCurWindow = offset/VGLAdpInfo.va_window_size; 51053013Syokota } 51153013Syokota return (offset%VGLAdpInfo.va_window_size); 51253013Syokota} 51353013Syokota 51453013Syokotaint 51553013SyokotaVGLSetVScreenSize(VGLBitmap *object, int VXsize, int VYsize) 51653013Syokota{ 51753013Syokota if (VXsize < object->Xsize || VYsize < object->Ysize) 51853013Syokota return -1; 51953013Syokota if (object->Type == MEMBUF) 52053013Syokota return -1; 52153013Syokota if (ioctl(0, FBIO_SETLINEWIDTH, &VXsize)) 52253013Syokota return -1; 52353013Syokota ioctl(0, CONS_ADPINFO, &VGLAdpInfo); /* FBIO_ADPINFO */ 52453013Syokota object->VXsize = VGLAdpInfo.va_line_width 52553013Syokota *8/(VGLModeInfo.vi_depth/VGLModeInfo.vi_planes); 52653013Syokota object->VYsize = VGLBufSize/VGLModeInfo.vi_planes/VGLAdpInfo.va_line_width; 52753013Syokota if (VYsize < object->VYsize) 52853013Syokota object->VYsize = VYsize; 52953013Syokota 53053013Syokota#ifdef LIBVGL_DEBUG 53153013Syokota fprintf(stderr, "new size: VGLXsize:%d, Ysize:%d, VXsize:%d, VYsize:%d\n", 53253013Syokota object->Xsize, object->Ysize, object->VXsize, object->VYsize); 53353013Syokota#endif 53453013Syokota 53553013Syokota return 0; 53653013Syokota} 53753013Syokota 53853013Syokotaint 53953013SyokotaVGLPanScreen(VGLBitmap *object, int x, int y) 54053013Syokota{ 54153013Syokota video_display_start_t origin; 54253013Syokota 54353013Syokota if (x < 0 || x + object->Xsize > object->VXsize 54453013Syokota || y < 0 || y + object->Ysize > object->VYsize) 54553013Syokota return -1; 54653013Syokota if (object->Type == MEMBUF) 54753013Syokota return 0; 54853013Syokota origin.x = x; 54953013Syokota origin.y = y; 55053013Syokota if (ioctl(0, FBIO_SETDISPSTART, &origin)) 55153013Syokota return -1; 55253013Syokota object->Xorigin = x; 55353013Syokota object->Yorigin = y; 55453013Syokota 55553013Syokota#ifdef LIBVGL_DEBUG 55653013Syokota fprintf(stderr, "new origin: (%d, %d)\n", x, y); 55753013Syokota#endif 55853013Syokota 55953013Syokota return 0; 56053013Syokota} 561