summaryrefslogtreecommitdiff
path: root/hw/kdrive/vesa
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2000-09-03 05:11:46 +0000
committerKeith Packard <keithp@keithp.com>2000-09-03 05:11:46 +0000
commitc97fb611dd7dedef6d075ef9d56f3d32c8018d39 (patch)
tree92dbb45f2e31b7ab709255d2d07a606f466c1a38 /hw/kdrive/vesa
parent38059656849a5bab5b56b23359a90aca4ba396c7 (diff)
Rework vesa driver for shadowing and multiple screen support. Allow enable
to fail and avoid crashing
Diffstat (limited to 'hw/kdrive/vesa')
-rw-r--r--hw/kdrive/vesa/Imakefile8
-rw-r--r--hw/kdrive/vesa/Xvesa.man33
-rw-r--r--hw/kdrive/vesa/vbe.c276
-rw-r--r--hw/kdrive/vesa/vbe.h18
-rw-r--r--hw/kdrive/vesa/vesa.c545
-rw-r--r--hw/kdrive/vesa/vesa.h32
6 files changed, 768 insertions, 144 deletions
diff --git a/hw/kdrive/vesa/Imakefile b/hw/kdrive/vesa/Imakefile
index bcf8613cb..b891e70b3 100644
--- a/hw/kdrive/vesa/Imakefile
+++ b/hw/kdrive/vesa/Imakefile
@@ -1,14 +1,12 @@
XCOMM $XFree86$
-
-#include <Server.tmpl>
+KDRIVE=..
+#include "../Kdrive.tmpl"
SRCS = vesa.c vesainit.c vbe.c
OBJS = vesa.o vesainit.o vbe.o
-INCLUDES = -I.. -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
- -I../../../fb -I../../../mi -I../../../include -I../../../os \
- -I$(EXTINCSRC) -I$(XINCLUDESRC)
+INCLUDES = -I. $(KDINCS)
NormalLibraryObjectRule()
NormalLibraryTarget(vesa,$(OBJS))
diff --git a/hw/kdrive/vesa/Xvesa.man b/hw/kdrive/vesa/Xvesa.man
index eafd3539b..958934aa9 100644
--- a/hw/kdrive/vesa/Xvesa.man
+++ b/hw/kdrive/vesa/Xvesa.man
@@ -7,8 +7,12 @@ Xvesa \- VESA VBE tiny X server
.RI [ :display ]
.RI [ option ...]
.SH DESCRIPTION
-Xvesa is an X server for Linux on the x86 platform. Xvesa manipulates
-the video hardware by running the VESA BIOS in VM86 mode. It
+.B Xvesa
+is a generic X server for Linux on the x86 platform.
+.B Xvesa
+doesn't know about any particular hardware, and sets the video mode by
+running the video BIOS in VM86 mode.
+.B Xvesa
therefore runs untrusted code with full priviledges, and is one of the
most insecure X servers available.
.B Run at your own risk.
@@ -23,11 +27,10 @@ specifies the VESA video mode to use. If mode
.I n
is not supported by your BIOS and hardware,
.B Xvesa
-will fail, hang your system, or make your monitor explode. You are on
-your own. The list of video modes that your BIOS claims to support
-can be obtained by using the
-.B -listmodes
-option.
+will fail, hang your system, or make your monitor explode; you are on
+your own. This option is ignored if the
+.B -screen
+option was used.
.TP 8
.B -listmodes
tells the server to list all supported video modes. If
@@ -40,8 +43,20 @@ the
server won't be able to use.
.TP 8
.B -force
-tells the server to disable some sanity checks and use the specified
-mode even if the BIOS claims not to support it.
+disables some sanity checks and use the specified mode even if the
+BIOS claims not to support it.
+.TP 8
+.B -shadow
+use a shadow framebuffer even if it is not strictly necessary. This
+may dramatically improve performance on some machines.
+.TP 8
+.B -nolinear
+don't use a linear framebuffer even if one is available. You don't
+want to use this option.
+.TP 8
+.B -swaprgb
+pass RGB values in the order that works on my machine. Use this if
+the colours are wrong in PseudoColor modes.
.SH KEYBOARD
Xvesa handles the keyboard in the same manner as the
.B Xfbdev
diff --git a/hw/kdrive/vesa/vbe.c b/hw/kdrive/vesa/vbe.c
index 98e51560d..1e709b9de 100644
--- a/hw/kdrive/vesa/vbe.c
+++ b/hw/kdrive/vesa/vbe.c
@@ -114,7 +114,8 @@ VbeSetup()
MAP_SHARED | MAP_FIXED,
devmem, HIMEM_BASE);
if(hiMem == MAP_FAILED) {
- munmap(magicMem, MAGICMEM_SIZE);
+ ErrorF("Couldn't map high memory\n");
+ munmap(magicMem, MAGICMEM_SIZE);
munmap(loMem, LOMEM_SIZE);
goto fail;
}
@@ -128,7 +129,6 @@ VbeSetup()
vi->magicMem = magicMem;
vi->loMem = loMem;
vi->hiMem = hiMem;
- vi->fb = NULL;
vi->brk = LOMEM_BASE;
stack_base = VbeAllocateMemory(vi, STACK_SIZE);
@@ -152,7 +152,10 @@ VbeSetup()
vi->palette_scratch_base = ~0;
vi->palette_format = 6;
vi->palette_wait = 0;
-
+ vi->windowA_offset = vi->windowB_offset = -1;
+ vi->last_window = 1;
+ vi->vga_palette = 1;
+
memset(&vi->vms, 0, sizeof(struct vm86_struct));
vi->vms.flags = 0;
vi->vms.screen_bitmap = 0;
@@ -181,8 +184,6 @@ VbeSetup()
void
VbeCleanup(VbeInfoPtr vi)
{
- if(vi->fb)
- VbeUnmapFramebuffer(vi);
munmap(vi->magicMem, MAGICMEM_SIZE);
munmap(vi->loMem, LOMEM_SIZE);
munmap(vi->hiMem, HIMEM_SIZE);
@@ -233,12 +234,17 @@ VbeGetModeInfo(VbeInfoPtr vi, int mode)
}
int
-VbeSetMode(VbeInfoPtr vi, int mode)
+VbeSetMode(VbeInfoPtr vi, int mode, int linear)
{
int code;
+ vi->windowA_offset = vi->windowB_offset = -1;
+ vi->last_window = 1;
+
vi->vms.regs.eax = 0x4F02;
- vi->vms.regs.ebx = (mode & 0xFFFF) | 0xC000;
+ vi->vms.regs.ebx = (mode & 0xFFFF) | 0x8000;
+ if(linear)
+ vi->vms.regs.ebx |= 0x4000;
code = VbeDoInterrupt10(vi);
if(code < 0)
return -1;
@@ -306,11 +312,24 @@ VbeRestoreState(VbeInfoPtr vi)
return 0;
}
+int
+VbeSetTextMode(VbeInfoPtr vi, int mode)
+{
+ int code;
+
+ vi->vms.regs.eax = mode & 0x7f;
+ code = VbeDoInterrupt10(vi);
+ if(code < 0)
+ return -1;
+ return 0;
+}
+
void *
-VbeMapFramebuffer(VbeInfoPtr vi) {
+VbeMapFramebuffer(VbeInfoPtr vi,
+ VbeModeInfoBlock *vmib)
+{
U8 *fb;
VbeInfoBlock *vib = (VbeInfoBlock*)&(LM(vi, vi->vib_base));
- VbeModeInfoBlock *vmib = (VbeModeInfoBlock*)&(LM(vi, vi->vmib_base));
int size;
int pagesize = getpagesize(), before, after;
@@ -329,18 +348,28 @@ VbeMapFramebuffer(VbeInfoPtr vi) {
return NULL;
}
- vi->fb = fb;
- vi->fb_size = before + size + after;
return fb + before;
}
int
-VbeUnmapFramebuffer(VbeInfoPtr vi)
+VbeUnmapFramebuffer(VbeInfoPtr vi,
+ VbeModeInfoBlock *vmib,
+ void *fb)
{
int code;
- if(!vi->fb)
- ErrorF("Unmapping frambuffer not mapped\n");
- code = munmap(vi->fb, vi->fb_size);
+ VbeInfoBlock *vib = (VbeInfoBlock*)&(LM(vi, vi->vib_base));
+ int size;
+ int pagesize = getpagesize(), before, after;
+
+ size = 1024 * 64L * vib->TotalMemory;
+
+ before = vmib->PhysBasePtr % pagesize;
+ after = pagesize - ((vmib->PhysBasePtr + size) % pagesize);
+ if(after == pagesize)
+ after = 0;
+
+ fb = (void *) ((char *) fb - before);
+ code = munmap(fb, before + size + after);
if(code) {
ErrorF("Couldn't unmap framebuffer: %d\n", errno);
return -1;
@@ -375,7 +404,7 @@ int
VbeSetPalette(VbeInfoPtr vi, int first, int number, U8 *entries)
{
U8 *palette_scratch;
- int i, code;
+ int i, j, code;
if(number == 0)
return 0;
@@ -395,21 +424,41 @@ VbeSetPalette(VbeInfoPtr vi, int first, int number, U8 *entries)
return -1;
}
- for(i=0; i<number*4; i++)
- palette_scratch[i] = entries[i] >> (8 - vi->palette_format);
-
- vi->vms.regs.eax = 0x4F09;
- if(vi->palette_wait)
- vi->vms.regs.ebx = 0x80;
+ if (vi->vga_palette)
+ {
+ vi->vms.regs.eax = 0x1012;
+ vi->vms.regs.ebx = first;
+ vi->vms.regs.ecx = number;
+ vi->vms.regs.es = POINTER_SEGMENT(vi->palette_scratch_base);
+ vi->vms.regs.edx = POINTER_OFFSET(vi->palette_scratch_base);
+ j = 0;
+ i = 0;
+ while (number--)
+ {
+ palette_scratch[j++] = entries[i++] >> (8-vi->palette_format);
+ palette_scratch[j++] = entries[i++] >> (8-vi->palette_format);
+ palette_scratch[j++] = entries[i++] >> (8-vi->palette_format);
+ i++;
+ }
+ }
else
- vi->vms.regs.ebx = 0x00;
- vi->vms.regs.ecx = number;
- vi->vms.regs.edx = first;
- vi->vms.regs.es = POINTER_SEGMENT(vi->palette_scratch_base);
- vi->vms.regs.edi = POINTER_OFFSET(vi->palette_scratch_base);
+ {
+ for(i=0; i<number*4; i++)
+ palette_scratch[i] = entries[i] >> (8 - vi->palette_format);
+
+ vi->vms.regs.eax = 0x4F09;
+ if(vi->palette_wait)
+ vi->vms.regs.ebx = 0x80;
+ else
+ vi->vms.regs.ebx = 0x00;
+ vi->vms.regs.ecx = number;
+ vi->vms.regs.edx = first;
+ vi->vms.regs.es = POINTER_SEGMENT(vi->palette_scratch_base);
+ vi->vms.regs.edi = POINTER_OFFSET(vi->palette_scratch_base);
+ }
code = VbeDoInterrupt10(vi);
if(code < 0)
- return -1;
+ return -1;
return 0;
}
@@ -417,7 +466,7 @@ int
VbeGetPalette(VbeInfoPtr vi, int first, int number, U8 *entries)
{
U8 *palette_scratch;
- int i, code;
+ int i, j, code;
code = PreparePalette(vi);
if(code < 0)
@@ -434,18 +483,45 @@ VbeGetPalette(VbeInfoPtr vi, int first, int number, U8 *entries)
return -1;
}
- vi->vms.regs.eax = 0x4F09;
- vi->vms.regs.ebx = 0x01;
- vi->vms.regs.ecx = number;
- vi->vms.regs.edx = first;
- vi->vms.regs.es = POINTER_SEGMENT(vi->palette_scratch_base);
- vi->vms.regs.edi = POINTER_OFFSET(vi->palette_scratch_base);
- code = VbeDoInterrupt10(vi);
- if(code < 0)
- return -1;
-
- for(i=0; i<number*4; i++)
- entries[i] = palette_scratch[i] << (8-vi->palette_format);
+retry:
+ if (vi->vga_palette)
+ {
+ vi->vms.regs.eax = 0x1017;
+ vi->vms.regs.ebx = first;
+ vi->vms.regs.ecx = number;
+ vi->vms.regs.es = POINTER_SEGMENT(vi->palette_scratch_base);
+ vi->vms.regs.edx = POINTER_OFFSET(vi->palette_scratch_base);
+ code = VbeDoInterrupt10(vi);
+ if(code < 0)
+ return -1;
+ j = 0;
+ i = 0;
+ while (number--)
+ {
+ entries[i++] = palette_scratch[j++] << (8-vi->palette_format);
+ entries[i++] = palette_scratch[j++] << (8-vi->palette_format);
+ entries[i++] = palette_scratch[j++] << (8-vi->palette_format);
+ entries[i++] = 0;
+ }
+ }
+ else
+ {
+ vi->vms.regs.eax = 0x4F09;
+ vi->vms.regs.ebx = 0x01;
+ vi->vms.regs.ecx = number;
+ vi->vms.regs.edx = first;
+ vi->vms.regs.es = POINTER_SEGMENT(vi->palette_scratch_base);
+ vi->vms.regs.edi = POINTER_OFFSET(vi->palette_scratch_base);
+ code = VbeDoInterrupt10(vi);
+ if(code < 0)
+ {
+ vi->vga_palette = TRUE;
+ goto retry;
+ }
+
+ for(i=0; i<number*4; i++)
+ entries[i] = palette_scratch[i] << (8-vi->palette_format);
+ }
return 0;
}
@@ -458,7 +534,6 @@ VbeSetPaletteOptions(VbeInfoPtr vi, U8 bits, int wait)
ErrorF("Impossible palette format %d\n", vi->palette_format);
return -1;
}
- ErrorF("Setting palette format to %d\n", vi->palette_format);
if(bits != vi->palette_format) {
vi->palette_format = 0;
vi->vms.regs.eax = 0x4F08;
@@ -472,6 +547,94 @@ VbeSetPaletteOptions(VbeInfoPtr vi, U8 bits, int wait)
return 0;
}
+static int
+VbeReallySetWindow(VbeInfoPtr vi, U8 window, U16 winnum)
+{
+ int code;
+ vi->vms.regs.eax = 0x4F05;
+ vi->vms.regs.ebx = window;
+ vi->vms.regs.edx = winnum;
+ code = VbeDoInterrupt10(vi);
+ if(code < 0)
+ return -1;
+ return 0;
+}
+
+void *
+VbeSetWindow(VbeInfoPtr vi, int offset, int purpose, int *size_return)
+{
+ VbeModeInfoBlock *vmib = (VbeModeInfoBlock*)&(LM(vi, vi->vmib_base));
+ int window_size = vmib->WinSize * 1024;
+ int code;
+ int winnum;
+
+ if(vi->windowA_offset >= 0)
+ if(vi->windowA_offset <= offset && vi->windowA_offset + window_size > offset)
+ if(vmib->WinAAttributes & purpose)
+ goto windowA;
+
+ if(vi->windowB_offset >= 0)
+ if(vi->windowB_offset <= offset && vi->windowB_offset + window_size > offset)
+ if(vmib->WinBAttributes & purpose)
+ goto windowB;
+
+ if(!(vmib->WinBAttributes & purpose) ||
+ !(vmib->WinBAttributes & VBE_WINDOW_RELOCATE))
+ goto set_windowA;
+
+ if(!(vmib->WinAAttributes & purpose) ||
+ !(vmib->WinAAttributes & VBE_WINDOW_RELOCATE))
+ goto set_windowB;
+
+ if(vi->last_window)
+ goto set_windowA;
+ else
+ goto set_windowB;
+
+ set_windowA:
+ winnum = offset / (vmib->WinGranularity * 1024);
+ code = VbeReallySetWindow(vi, 0, winnum);
+ if(code < 0) {
+ ErrorF("Couldn't set window A to %d*%d\n",
+ (int)winnum, (int)vmib->WinGranularity);
+ return NULL;
+ }
+ vi->windowA_offset = winnum * vmib->WinGranularity * 1024;
+ windowA:
+ vi->last_window = 0;
+ *size_return = vmib->WinSize * 1024 - (offset - vi->windowA_offset);
+ return ((U8*)&(LM(vi, MAKE_POINTER(vmib->WinASegment, 0)))) +
+ offset - vi->windowA_offset;
+
+ set_windowB:
+ winnum = offset / (vmib->WinGranularity * 1024);
+ code = VbeReallySetWindow(vi, 1, winnum);
+ if(code < 0) {
+ ErrorF("Couldn't set window B to %d*%d\n",
+ (int)winnum, (int)vmib->WinGranularity);
+ return NULL;
+ }
+ vi->windowB_offset = winnum * vmib->WinGranularity * 1024;
+ windowB:
+ vi->last_window = 1;
+ *size_return = vmib->WinSize * 1024 - (offset - vi->windowB_offset);
+ return ((U8*)&(LM(vi, MAKE_POINTER(vmib->WinBSegment, 0)))) + offset - vi->windowB_offset;
+}
+
+int
+VbeSetWritePlaneMask(VbeInfoPtr vi, int mask)
+{
+ asm volatile ("outb %b0,%w1" : : "a" (2), "d" (0x3c4));
+ asm volatile ("outb %b0,%w1" : : "a" (mask), "d" (0x3c5));
+}
+
+int
+VbeSetReadPlaneMap(VbeInfoPtr vi, int map)
+{
+ asm volatile ("outb %b0,%w1" : : "a" (4), "d" (0x3ce));
+ asm volatile ("outb %b0,%w1" : : "a" (map), "d" (0x3cf));
+}
+
int
VbeReportInfo(VbeInfoPtr vi, VbeInfoBlock *vib)
{
@@ -496,12 +659,12 @@ VbeReportInfo(VbeInfoPtr vi, VbeInfoBlock *vib)
(vib->Capabilities[0]&1)?"fixed":"switchable",
(vib->Capabilities[0]&2)?"not ":"",
(vib->Capabilities[0]&3)?", RAMDAC causes snow":"");
- ErrorF("Total memory: %lu bytes\n", 64L*vib->TotalMemory);
+ ErrorF("Total memory: %lu kilobytes\n", 64L*vib->TotalMemory);
if(error)
return -1;
return 0;
}
-
+
int
VbeReportModeInfo(VbeInfoPtr vi, U16 mode, VbeModeInfoBlock *vmib)
{
@@ -572,7 +735,7 @@ VbeDoInterrupt10(VbeInfoPtr vi)
if(code < 0)
return -1;
- if((vi->vms.regs.eax & 0xFFFF) != 0x4F) {
+ if((vi->vms.regs.eax & 0xFFFF) != 0x4F && (oldax & 0xFF00) == 0x4F00) {
ErrorF("Int 10h (0x%04X) failed: 0x%04X",
oldax, vi->vms.regs.eax & 0xFFFF);
if((oldax & 0xFF00) == 0x4F00) {
@@ -627,7 +790,9 @@ VbeDoInterrupt(VbeInfoPtr vi, int num)
PUSHW(vi, POINTER_OFFSET(vi->ret_code));
vi->vms.regs.cs = seg;
vi->vms.regs.eip = off;
+ OsBlockSignals ();
code = vm86_loop(vi);
+ OsReleaseSignals ();
if(code < 0) {
perror("vm86 failed");
return -1;
@@ -873,6 +1038,7 @@ static int
vm86_loop(VbeInfoPtr vi)
{
int code;
+
while(1) {
code = vm86old(&vi->vms);
switch(VM86_TYPE(code)) {
@@ -1030,18 +1196,20 @@ static int
vm86old(struct vm86_struct *vm)
{
int res;
+
asm volatile (
- "pushl %%ebx\n\t"
- "movl %2, %%ebx\n\t"
- "movl %1,%%eax\n\t"
- "int $0x80\n\t"
- "popl %%ebx"
- : "=a" (res) : "n" (113), "r" (vm));
+ "pushl %%ebx\n\t"
+ "movl %2, %%ebx\n\t"
+ "movl %1,%%eax\n\t"
+ "int $0x80\n\t"
+ "popl %%ebx"
+ : "=a" (res) : "n" (113), "r" (vm));
if(res < 0) {
- errno = -res;
- res = -1;
+ errno = -res;
+ res = -1;
} else
- errno = 0;
+ errno = 0;
+ OsReleaseSignals ();
return res;
}
diff --git a/hw/kdrive/vesa/vbe.h b/hw/kdrive/vesa/vbe.h
index c8041fd2e..b76e99ee7 100644
--- a/hw/kdrive/vesa/vbe.h
+++ b/hw/kdrive/vesa/vbe.h
@@ -23,6 +23,10 @@ THE SOFTWARE.
#ifndef _VBE_H
#define _VBE_H
+#define VBE_WINDOW_RELOCATE 1
+#define VBE_WINDOW_READ 2
+#define VBE_WINDOW_WRITE 4
+
#ifndef U8
#define U8 unsigned char
#define U16 unsigned short
@@ -61,13 +65,16 @@ THE SOFTWARE.
typedef struct _VbeInfoRec {
int devmem, devzero;
- void *magicMem, *loMem, *hiMem, *fb;
- U32 fb_size;
+ void *magicMem, *loMem, *hiMem;
U32 brk;
struct vm86_struct vms;
U32 ret_code, stack_base, vib_base, vmib_base, statebuffer_base, palette_scratch_base;
U8 palette_format;
int palette_wait;
+ int windowA_offset;
+ int windowB_offset;
+ int last_window;
+ int vga_palette;
} VbeInfoRec, *VbeInfoPtr;
typedef struct _VbeInfoBlock {
@@ -143,15 +150,16 @@ VbeInfoPtr VbeSetup(void);
void VbeCleanup(VbeInfoPtr vi);
VbeInfoBlock *VbeGetInfo(VbeInfoPtr vi);
VbeModeInfoBlock *VbeGetModeInfo(VbeInfoPtr vi, int mode);
-int VbeSetMode(VbeInfoPtr vi, int mode);
+int VbeSetMode(VbeInfoPtr vi, int mode, int linear);
int VbeGetMode(VbeInfoPtr vi, int *mode);
int VbeSetupStateBuffer(VbeInfoPtr vi);
int VbeSaveState(VbeInfoPtr vi);
int VbeRestoreState(VbeInfoPtr vi);
-void *VbeMapFramebuffer(VbeInfoPtr vi);
-int VbeUnmapFrambuffer(VbeInfoPtr vi);
+void *VbeMapFramebuffer(VbeInfoPtr vi, VbeModeInfoBlock *vmib);
+int VbeUnmapFrambuffer(VbeInfoPtr vi, VbeModeInfoBlock *vmib, void *fb);
int VbeSetPalette(VbeInfoPtr vi, int first, int number, U8 *entries);
int VbeSetPaletteOptions(VbeInfoPtr vi, U8 bits, int wait);
+void *VbeSetWindow(VbeInfoPtr vi, int offset, int purpose, int *size_return);
int VbeReportInfo(VbeInfoPtr, VbeInfoBlock *);
int VbeReportModeInfo(VbeInfoPtr, U16 mode, VbeModeInfoBlock *);
diff --git a/hw/kdrive/vesa/vesa.c b/hw/kdrive/vesa/vesa.c
index 0939dabab..48e39ec8c 100644
--- a/hw/kdrive/vesa/vesa.c
+++ b/hw/kdrive/vesa/vesa.c
@@ -22,11 +22,12 @@ THE SOFTWARE.
#include "vesa.h"
-#define DEFAULT_MODE 0x115
-
-int vesa_video_mode = DEFAULT_MODE;
+int vesa_video_mode = 0;
Bool vesa_force_mode = FALSE;
Bool vesa_swap_rgb = FALSE;
+Bool vesa_shadow = FALSE;
+Bool vesa_linear_fb = TRUE;
+Bool vesa_restore = FALSE;
static Bool
vesaModeSupported(VbeInfoPtr vi, VbeModeInfoBlock *vmib, Bool complain)
@@ -36,17 +37,19 @@ vesaModeSupported(VbeInfoPtr vi, VbeModeInfoBlock *vmib, Bool complain)
ErrorF("Text mode specified.\n");
return FALSE;
}
- if(vmib->MemoryModel != 0x06 && vmib->MemoryModel != 0x04) {
+ if(vmib->MemoryModel != 0x06 && vmib->MemoryModel != 0x04 && vmib->MemoryModel != 0x03) {
if(complain)
ErrorF("Unsupported memory model 0x%X\n", vmib->MemoryModel);
return FALSE;
}
if((vmib->ModeAttributes & 0x80) == 0) {
- if(complain)
- ErrorF("No linear framebuffer available in this mode\n");
- return FALSE;
+ if ((vmib->WinAAttributes & 0x5) != 0x5) {
+ if(complain)
+ ErrorF("Neither linear nor windowed framebuffer available in this mode\n");
+ return FALSE;
+ }
}
- if(!(vmib->ModeAttributes&1)) {
+ if(!(vmib->ModeAttributes & 1)) {
if(complain)
ErrorF("Mode not supported on this hardware\n");
return FALSE;
@@ -61,7 +64,8 @@ vesaListModes()
VbeInfoPtr vi = NULL;
VbeInfoBlock *vib;
VbeModeInfoBlock *vmib;
- unsigned i;
+ unsigned p, num_modes, i;
+ CARD16 *modes_list = NULL;
vi = VbeSetup();
if(!vi)
@@ -72,32 +76,91 @@ vesaListModes()
goto fail;
VbeReportInfo(vi, vib);
- i = MAKE_POINTER_1(vib->VideoModePtr);
-
- while(VbeMemoryW(vi, i) != 0xFFFF) {
- vmib = VbeGetModeInfo(vi, VbeMemoryW(vi, i));
+ /* The spec says you need to copy the list */
+ p = MAKE_POINTER_1(vib->VideoModePtr);
+ num_modes = 0;
+ while(VbeMemoryW(vi, p) != 0xFFFF) {
+ num_modes++;
+ p+=2;
+ }
+ modes_list = ALLOCATE_LOCAL(num_modes * sizeof(CARD16));
+ if(!modes_list)
+ goto fail;
+ p = MAKE_POINTER_1(vib->VideoModePtr);
+ for(i=0; i<num_modes; i++) {
+ modes_list[i] = VbeMemoryW(vi, p);
+ p += 2;
+ }
+
+ for(i=0; i<num_modes; i++) {
+ vmib = VbeGetModeInfo(vi, modes_list[i]);
if(!vmib)
goto fail;
if(vesa_force_mode || vesaModeSupported(vi, vmib, FALSE))
- VbeReportModeInfo(vi, VbeMemoryW(vi, i), vmib);
- i+=2;
+ VbeReportModeInfo(vi, modes_list[i], vmib);
}
+ if(modes_list)
+ DEALLOCATE_LOCAL(modes_list);
VbeCleanup(vi);
return TRUE;
fail:
+ if(modes_list)
+ DEALLOCATE_LOCAL(modes_list);
VbeCleanup(vi);
return FALSE;
}
Bool
-vesaInitialize (KdCardInfo *card, VesaPrivPtr priv)
+vesaGetModes (KdCardInfo *card, VesaCardPrivPtr priv)
+{
+ VesaModePtr mode;
+ int nmode;
+ unsigned int i;
+ VbeInfoPtr vi = priv->vi;
+ VbeInfoBlock *vib = priv->vib;
+ VbeModeInfoBlock *vmib;
+
+ /* The spec says you need to copy the list */
+ i = MAKE_POINTER_1(vib->VideoModePtr);
+ nmode = 0;
+ while(VbeMemoryW(vi, i) != 0xFFFF) {
+ nmode++;
+ i+=2;
+ }
+ if (!nmode)
+ return FALSE;
+ priv->modes = xalloc (nmode * sizeof (VesaModeRec));
+ if (!priv->modes)
+ return FALSE;
+ priv->nmode = nmode;
+ i = MAKE_POINTER_1(vib->VideoModePtr);
+ nmode = 0;
+ while(nmode < priv->nmode) {
+ priv->modes[nmode].mode = VbeMemoryW(vi, i);
+ nmode++;
+ i+=2;
+ }
+ i = MAKE_POINTER_1(vib->VideoModePtr);
+ nmode = 0;
+ while(nmode < priv->nmode) {
+ vmib = VbeGetModeInfo(vi, priv->modes[nmode].mode);
+ if(!vmib)
+ break;
+ priv->modes[nmode].vmib = *vmib;
+ i += 2;
+ nmode++;
+ }
+ return TRUE;
+}
+
+
+Bool
+vesaInitialize (KdCardInfo *card, VesaCardPrivPtr priv)
{
int code;
- priv->mode = vesa_video_mode;
-
priv->vi = VbeSetup();
if(!priv->vi)
goto fail;
@@ -106,13 +169,6 @@ vesaInitialize (KdCardInfo *card, VesaPrivPtr priv)
if(!priv->vib)
goto fail;
- priv->vmib = VbeGetModeInfo(priv->vi, priv->mode);
- if(!priv->vmib)
- goto fail;
-
- if(!vesa_force_mode && !vesaModeSupported(priv->vi, priv->vmib, TRUE))
- goto fail;
-
code = VbeSetupStateBuffer(priv->vi);
if(code < 0)
goto fail;
@@ -121,10 +177,9 @@ vesaInitialize (KdCardInfo *card, VesaPrivPtr priv)
if(code<0)
goto fail;
- priv->fb = VbeMapFramebuffer(priv->vi);
- if(!priv->vi)
- goto fail;
-
+ if (!vesaGetModes (card, priv))
+ goto fail;
+
card->driver = priv;
return TRUE;
@@ -138,9 +193,9 @@ vesaInitialize (KdCardInfo *card, VesaPrivPtr priv)
Bool
vesaCardInit(KdCardInfo *card)
{
- VesaPrivPtr priv;
+ VesaCardPrivPtr priv;
- priv = xalloc(sizeof(VesaPrivRec));
+ priv = xalloc(sizeof(VesaCardPrivRec));
if(!priv)
return FALSE;
@@ -153,30 +208,137 @@ vesaCardInit(KdCardInfo *card)
return TRUE;
}
+int
+vesaDepth (VbeModeInfoBlock *m)
+{
+ if (m->MemoryModel == 0x06)
+ return (m->RedMaskSize +
+ m->GreenMaskSize +
+ m->BlueMaskSize);
+ else
+ return m->BitsPerPixel;
+}
+
Bool
-vesaScreenInit(KdScreenInfo *screen)
+vesaModeGood (KdScreenInfo *screen,
+ VbeModeInfoBlock *a)
{
- VesaPrivPtr priv = screen->card->driver;
+ if (a->XResolution <= screen->width &&
+ a->YResolution <= screen->height &&
+ vesaDepth (a) >= screen->fb[0].depth)
+ {
+ return TRUE;
+ }
+}
+
+#define vabs(a) ((a) >= 0 ? (a) : -(a))
+
+int
+vesaSizeError (KdScreenInfo *screen,
+ VbeModeInfoBlock *a)
+{
+ int xdist, ydist;
+ xdist = vabs (screen->width - a->XResolution);
+ ydist = vabs (screen->height - a->YResolution);
+ return xdist * xdist + ydist * ydist;
+}
+
+Bool
+vesaModeBetter (KdScreenInfo *screen,
+ VbeModeInfoBlock *a,
+ VbeModeInfoBlock *b)
+{
+ int aerr, berr;
+
+ if (vesaModeGood (screen, a))
+ {
+ if (!vesaModeGood (screen, b))
+ return TRUE;
+ }
+ else
+ {
+ if (vesaModeGood (screen, b))
+ return FALSE;
+ }
+ aerr = vesaSizeError (screen, a);
+ berr = vesaSizeError (screen, b);
+ if (aerr < berr)
+ return TRUE;
+ if (berr < aerr)
+ return FALSE;
+ if (vabs (screen->fb[0].depth - vesaDepth (a)) <
+ vabs (screen->fb[0].depth - vesaDepth (b)))
+ return TRUE;
+ return FALSE;
+}
+
+VesaModePtr
+vesaSelectMode (KdScreenInfo *screen)
+{
+ VesaCardPrivPtr priv = screen->card->driver;
+ int i, best;
+
+ if (vesa_video_mode)
+ {
+ for (best = 0; best < priv->nmode; best++)
+ if (priv->modes[best].mode == vesa_video_mode &&
+ (vesaModeSupported (priv->vi, &priv->modes[best].vmib, FALSE) ||
+ vesa_force_mode))
+ return &priv->modes[best];
+ }
+ for (best = 0; best < priv->nmode; best++)
+ {
+ if (vesaModeSupported (priv->vi, &priv->modes[best].vmib, FALSE))
+ break;
+ }
+ if (best == priv->nmode)
+ return 0;
+ for (i = best + 1; i < priv->nmode; i++)
+ if (vesaModeSupported (priv->vi, &priv->modes[i].vmib, FALSE) &&
+ vesaModeBetter (screen, &priv->modes[i].vmib,
+ &priv->modes[best].vmib))
+ best = i;
+ return &priv->modes[best];
+}
+
+Bool
+vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr)
+{
+ VesaCardPrivPtr priv = screen->card->driver;
+ VbeModeInfoBlock *vmib;
Pixel allbits;
int depth;
- screen->width = priv->vmib->XResolution;
- screen->height = priv->vmib->YResolution;
- screen->fb[0].depth = priv->vmib->BitsPerPixel;
- screen->fb[0].bitsPerPixel = priv->vmib->BitsPerPixel;
- screen->fb[0].byteStride = priv->vmib->BytesPerScanLine;
- screen->fb[0].pixelStride =
- (priv->vmib->BytesPerScanLine * 8) / priv->vmib->BitsPerPixel;
+ pscr->mode = vesaSelectMode (screen);
+ if (!pscr->mode)
+ return FALSE;
- if(priv->vmib->MemoryModel == 0x06) {
+ pscr->shadow = vesa_shadow;
+ if (vesa_linear_fb)
+ pscr->mapping = VESA_LINEAR;
+ else
+ pscr->mapping = VESA_WINDOWED;
+
+ vmib = &pscr->mode->vmib;
+
+ screen->width = vmib->XResolution;
+ screen->height = vmib->YResolution;
+ screen->fb[0].depth = vesaDepth (vmib);
+ screen->fb[0].bitsPerPixel = vmib->BitsPerPixel;
+ screen->fb[0].byteStride = vmib->BytesPerScanLine;
+ screen->fb[0].pixelStride = ((vmib->BytesPerScanLine * 8) /
+ vmib->BitsPerPixel);
+
+ switch (vmib->MemoryModel) {
+ case 0x06:
/* TrueColor or DirectColor */
screen->fb[0].visuals = (1 << TrueColor);
screen->fb[0].redMask =
- FbStipMask(priv->vmib->RedFieldPosition, priv->vmib->RedMaskSize);
+ FbStipMask(vmib->RedFieldPosition, vmib->RedMaskSize);
screen->fb[0].greenMask =
- FbStipMask(priv->vmib->GreenFieldPosition, priv->vmib->GreenMaskSize);
+ FbStipMask(vmib->GreenFieldPosition, vmib->GreenMaskSize);
screen->fb[0].blueMask =
- FbStipMask(priv->vmib->BlueFieldPosition, priv->vmib->BlueMaskSize);
+ FbStipMask(vmib->BlueFieldPosition, vmib->BlueMaskSize);
allbits =
screen->fb[0].redMask |
screen->fb[0].greenMask |
@@ -185,7 +347,8 @@ vesaScreenInit(KdScreenInfo *screen)
while (depth && !(allbits & (1 << (depth - 1))))
depth--;
screen->fb[0].depth = depth;
- } else if (priv->vmib->MemoryModel == 0x04) {
+ break;
+ case 0x04:
/* PseudoColor */
screen->fb[0].visuals = ((1 << StaticGray) |
(1 << GrayScale) |
@@ -196,35 +359,204 @@ vesaScreenInit(KdScreenInfo *screen)
screen->fb[0].blueMask = 0x00;
screen->fb[0].greenMask = 0x00;
screen->fb[0].redMask = 0x00;
- } else {
+ break;
+ case 0x03:
+ /* 4 plane planar */
+ screen->fb[0].visuals = (1 << StaticColor);
+ screen->fb[0].blueMask = 0x00;
+ screen->fb[0].greenMask = 0x00;
+ screen->fb[0].redMask = 0x00;
+ screen->fb[0].depth = 4;
+ screen->fb[0].bitsPerPixel = 4;
+ pscr->mapping = VESA_PLANAR;
+ break;
+ default:
ErrorF("Unsupported VESA MemoryModel 0x%02X\n",
- priv->vmib->MemoryModel);
+ vmib->MemoryModel);
return FALSE;
}
+ if (pscr->mapping == VESA_LINEAR && !(vmib->ModeAttributes & 0x80))
+ pscr->mapping = VESA_WINDOWED;
+
+ switch (pscr->mapping) {
+ case VESA_LINEAR:
+ pscr->fb = VbeMapFramebuffer(priv->vi, vmib);
+ break;
+ case VESA_WINDOWED:
+ pscr->fb = NULL;
+ pscr->shadow = TRUE;
+ break;
+ case VESA_PLANAR:
+ pscr->fb = NULL;
+ pscr->shadow = TRUE;
+ break;
+ }
+
screen->rate = 72;
- screen->fb[0].frameBuffer = (CARD8 *)(priv->fb);
+ screen->fb[0].frameBuffer = (CARD8 *)(pscr->fb);
+
+ if (pscr->shadow)
+ return KdShadowScreenInit (screen);
+
+ return TRUE;
+}
+
+Bool
+vesaScreenInit(KdScreenInfo *screen)
+{
+ VesaScreenPrivPtr pscr;
+
+ pscr = xcalloc (1, sizeof (VesaScreenPrivRec));
+ if (!pscr)
+ return FALSE;
+ if (!vesaScreenInitialize (screen, pscr))
+ return FALSE;
+ screen->driver = pscr;
+ return TRUE;
+}
+
+void *
+vesaWindowPlanar (ScreenPtr pScreen,
+ CARD32 row,
+ CARD32 offset,
+ int mode,
+ CARD32 *size)
+{
+ KdScreenPriv(pScreen);
+ VesaCardPrivPtr priv = pScreenPriv->card->driver;
+ VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
+ VbeModeInfoBlock *vmib = &pscr->mode->vmib;
+ static int plane;
+ int winSize;
+ void *base;
+
+ if (!pScreenPriv->enabled)
+ return 0;
+ plane = offset & 3;
+ VbeSetWritePlaneMask (priv->vi, (1 << plane));
+ offset = offset >> 2;
+ base = VbeSetWindow (priv->vi,
+ vmib->BytesPerScanLine * row + offset,
+ mode,
+ &winSize);
+ *size = (CARD32) winSize;
+ return base;
+}
+
+void *
+vesaWindowLinear (ScreenPtr pScreen,
+ CARD32 row,
+ CARD32 offset,
+ int mode,
+ CARD32 *size)
+{
+ KdScreenPriv(pScreen);
+ VesaCardPrivPtr priv = pScreenPriv->card->driver;
+ VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
+ VbeModeInfoBlock *vmib = &pscr->mode->vmib;
+
+ if (!pScreenPriv->enabled)
+ return 0;
+ *size = vmib->BytesPerScanLine;
+ return (CARD8 *) pscr->fb + row * vmib->BytesPerScanLine + offset;
+}
+
+void *
+vesaWindowWindowed (ScreenPtr pScreen,
+ CARD32 row,
+ CARD32 offset,
+ int mode,
+ CARD32 *size)
+{
+ KdScreenPriv(pScreen);
+ VesaCardPrivPtr priv = pScreenPriv->card->driver;
+ VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
+ VbeModeInfoBlock *vmib = &pscr->mode->vmib;
+ int winSize;
+ void *base;
+
+ if (!pScreenPriv->enabled)
+ return 0;
+ base = VbeSetWindow (priv->vi,
+ vmib->BytesPerScanLine * row + offset,
+ mode,
+ &winSize);
+ *size = (CARD32) winSize;
+ return base;
+}
+
+static CARD16 vga16Colors[16][3] = {
+ { 0, 0, 0, }, /* 0 */
+ { 0x80,0, 0, }, /* 1 */
+ { 0, 0x80,0, }, /* 2 */
+ { 0x80,0x80,0, }, /* 3 */
+ { 0, 0, 0x80,}, /* 4 */
+ { 0x80,0, 0x80,}, /* 5 */
+ { 0, 0x80,0x80,}, /* 6 */
+ { 0x80,0x80,0x80,}, /* 7 */
+ { 0xC0,0xC0,0xC0,}, /* 8 */
+ { 0xFF,0, 0 ,}, /* 9 */
+ { 0, 0xFF,0 ,}, /* 10 */
+ { 0xFF,0xFF,0 ,}, /* 11 */
+ { 0 ,0, 0xFF,}, /* 12 */
+ { 0xFF,0, 0xFF,}, /* 13 */
+ { 0, 0xFF,0xFF,}, /* 14 */
+ { 0xFF,0xFF,0xFF,}, /* 15 */
+};
+
+Bool
+vesaCreateColormap16 (ColormapPtr pmap)
+{
+ int i;
+ for (i = 0; i < 16; i++)
+ {
+ pmap->red[i].co.local.red = (vga16Colors[i][0]<<8)|vga16Colors[i][0];
+ pmap->red[i].co.local.green = (vga16Colors[i][1]<<8)|vga16Colors[i][1];
+ pmap->red[i].co.local.blue = (vga16Colors[i][2]<<8)|vga16Colors[i][2];
+ }
return TRUE;
}
+
Bool
vesaInitScreen(ScreenPtr pScreen)
{
+ KdScreenPriv(pScreen);
+ VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
+
+ if (pscr->shadow)
+ {
+ switch (pscr->mapping) {
+ case VESA_LINEAR:
+ return KdShadowInitScreen (pScreen, shadowUpdatePacked, vesaWindowLinear);
+ case VESA_WINDOWED:
+ return KdShadowInitScreen (pScreen, shadowUpdatePacked, vesaWindowWindowed);
+ case VESA_PLANAR:
+ pScreen->CreateColormap = vesaCreateColormap16;
+ return KdShadowInitScreen (pScreen, shadowUpdatePlanar4, vesaWindowPlanar);
+ }
+ }
+
return TRUE;
}
-void
+Bool
vesaEnable(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
- VesaPrivPtr priv = pScreenPriv->card->driver;
+ VesaCardPrivPtr priv = pScreenPriv->card->driver;
+ VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
int code;
int palette_wait = 0, palette_hi = 0;
+ int i=0;
+ int size;
+ char *p;
- code = VbeSetMode(priv->vi, priv->mode);
+ code = VbeSetMode(priv->vi, pscr->mode->mode, pscr->mapping == VESA_LINEAR);
if(code < 0)
- FatalError("Couldn't set mode\n");
+ return FALSE;
if(priv->vib->Capabilities[0] & 1)
palette_hi = 1;
@@ -233,23 +565,85 @@ vesaEnable(ScreenPtr pScreen)
if(palette_hi || palette_wait)
VbeSetPaletteOptions(priv->vi, palette_hi?8:6, palette_wait);
- return;
+ switch (pscr->mapping) {
+ case VESA_LINEAR:
+ memcpy (priv->text, pscr->fb, VESA_TEXT_SAVE);
+ break;
+ case VESA_WINDOWED:
+ while(i < VESA_TEXT_SAVE) {
+ p = VbeSetWindow(priv->vi, i, VBE_WINDOW_READ, &size);
+ if(!p) {
+ ErrorF("Couldn't set window for saving VGA font\n");
+ break;
+ }
+ if(i + size > VESA_TEXT_SAVE)
+ size = VESA_TEXT_SAVE - i;
+ memcpy(((char*)priv->text) + i, p, size);
+ i += size;
+ }
+ break;
+ case VESA_PLANAR:
+ p = VbeSetWindow (priv->vi, 0, VBE_WINDOW_READ, &size);
+ for (i = 0; i < 4; i++)
+ {
+ VbeSetReadPlaneMap (priv->vi, i);
+ memcpy (((char *)priv->text) + i * (VESA_TEXT_SAVE/4), p,
+ (VESA_TEXT_SAVE/4));
+ }
+ break;
+ }
+ return TRUE;
}
void
vesaDisable(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
- VesaPrivPtr priv = pScreenPriv->card->driver;
-
+ VesaCardPrivPtr priv = pScreenPriv->card->driver;
+ VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
+ int i=0;
+ int size;
+ char *p;
+
+ switch (pscr->mapping) {
+ case VESA_LINEAR:
+ memcpy(pscr->fb, priv->text, VESA_TEXT_SAVE);
+ break;
+ case VESA_WINDOWED:
+ while(i < VESA_TEXT_SAVE) {
+ p = VbeSetWindow(priv->vi, i, VBE_WINDOW_WRITE, &size);
+ if(!p) {
+ ErrorF("Couldn't set window for restoring VGA font\n");
+ break;
+ }
+ if(i + size > VESA_TEXT_SAVE)
+ size = VESA_TEXT_SAVE - i;
+ memcpy(p, ((char*)priv->text) + i, size);
+ i += size;
+ }
+ break;
+ case VESA_PLANAR:
+ p = VbeSetWindow (priv->vi, 0, VBE_WINDOW_WRITE, &size);
+ for (i = 0; i < 4; i++)
+ {
+ VbeSetWritePlaneMask (priv->vi, 1 << i);
+ memcpy (p,
+ ((char *)priv->text) + i * (VESA_TEXT_SAVE/4),
+ (VESA_TEXT_SAVE/4));
+ }
+ break;
+ }
}
void
vesaPreserve(KdCardInfo *card)
{
- VesaPrivPtr priv = card->driver;
+ VesaCardPrivPtr priv = card->driver;
int code;
+ /* The framebuffer might not be valid at this point, so we cannot
+ save the VGA fonts now; we do it in vesaEnable. */
+
code = VbeSaveState(priv->vi);
if(code < 0)
FatalError("Couldn't save state\n");
@@ -260,7 +654,7 @@ vesaPreserve(KdCardInfo *card)
void
vesaRestore(KdCardInfo *card)
{
- VesaPrivPtr priv = card->driver;
+ VesaCardPrivPtr priv = card->driver;
VbeRestoreState(priv->vi);
return;
}
@@ -268,8 +662,9 @@ vesaRestore(KdCardInfo *card)
void
vesaCardFini(KdCardInfo *card)
{
- VesaPrivPtr priv = card->driver;
- VbeUnmapFramebuffer(priv->vi);
+ VesaCardPrivPtr priv = card->driver;
+ if (vesa_restore)
+ VbeSetTextMode(priv->vi,3);
VbeCleanup(priv->vi);
return;
}
@@ -277,15 +672,21 @@ vesaCardFini(KdCardInfo *card)
void
vesaScreenFini(KdScreenInfo *screen)
{
- return;
+ VesaScreenPrivPtr pscr = screen->driver;
+ VesaCardPrivPtr priv = screen->card->driver;
+
+ if (pscr->fb)
+ VbeUnmapFramebuffer(priv->vi, &pscr->mode->vmib, pscr->fb);
+ return;
}
void
vesaPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
{
KdScreenPriv(pScreen);
- VesaPrivPtr priv = pScreenPriv->card->driver;
- int i, j, k;
+ VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
+ VesaCardPrivPtr priv = pScreenPriv->card->driver;
+ int i, j, k, start;
CARD8 scratch[4*256];
int red, green, blue;
@@ -314,7 +715,14 @@ vesaPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
scratch[k+blue] = pdefs[i+k].blue >> 8;
scratch[k+3] = 0;
}
- VbeSetPalette(priv->vi, pdefs[i].pixel, j - i, scratch);
+ start = pdefs[i].pixel;
+ if (pscr->mapping == VESA_PLANAR)
+ {
+ for (start = pdefs[i].pixel; start < 256; start += 16)
+ VbeSetPalette(priv->vi, start, j - i, scratch);
+ }
+ else
+ VbeSetPalette(priv->vi, start, j - i, scratch);
i = j;
}
}
@@ -323,7 +731,7 @@ void
vesaGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
{
KdScreenPriv(pScreen);
- VesaPrivPtr priv = pScreenPriv->card->driver;
+ VesaCardPrivPtr priv = pScreenPriv->card->driver;
int first, i, j, k;
CARD8 scratch[4];
int red, green, blue;
@@ -367,6 +775,15 @@ vesaProcessArgument (int argc, char **argv, int i)
} else if(!strcmp(argv[i], "-swaprgb")) {
vesa_swap_rgb = TRUE;
return 1;
+ } else if(!strcmp(argv[i], "-shadow")) {
+ vesa_shadow = TRUE;
+ return 1;
+ } else if(!strcmp(argv[i], "-nolinear")) {
+ vesa_linear_fb = FALSE;
+ return 1;
+ } else if(!strcmp(argv[i], "-restore")) {
+ vesa_restore = TRUE;
+ return 1;
}
return 0;
diff --git a/hw/kdrive/vesa/vesa.h b/hw/kdrive/vesa/vesa.h
index 453b36f2e..256146cad 100644
--- a/hw/kdrive/vesa/vesa.h
+++ b/hw/kdrive/vesa/vesa.h
@@ -27,24 +27,42 @@ THE SOFTWARE.
#include <sys/vm86.h>
#include "vbe.h"
-typedef struct _VesaPriv {
+#define VESA_TEXT_SAVE (64*1024)
+
+typedef struct _VesaMode {
int mode;
+ VbeModeInfoBlock vmib;
+} VesaModeRec, *VesaModePtr;
+
+typedef struct _VesaCardPriv {
VbeInfoPtr vi;
VbeInfoBlock *vib;
- VbeModeInfoBlock *vmib;
+ VesaModePtr modes;
+ int nmode;
+ char text[VESA_TEXT_SAVE];
+} VesaCardPrivRec, *VesaCardPrivPtr;
+
+#define VESA_LINEAR 0
+#define VESA_WINDOWED 1
+#define VESA_PLANAR 2
+typedef struct _VesaScreenPriv {
+ VesaModePtr mode;
+ Bool shadow;
+ int mapping;
void *fb;
-} VesaPrivRec, *VesaPrivPtr;
+} VesaScreenPrivRec, *VesaScreenPrivPtr;
extern int vesa_video_mode;
extern Bool vesa_force_mode;
Bool vesaListModes(void);
-Bool vesaInitialize(KdCardInfo *card, VesaPrivPtr priv);
+Bool vesaInitialize(KdCardInfo *card, VesaCardPrivPtr priv);
Bool vesaCardInit(KdCardInfo *card);
-Bool vesaInitialize (KdCardInfo *card, VesaPrivPtr priv);
-Bool vesaScreenInit(KdScreenInfo *screen);
+Bool vesaInitialize (KdCardInfo *card, VesaCardPrivPtr priv);
+Bool vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr);
+Bool vesaScreenInit(KdScreenInfo *screen);
Bool vesaInitScreen(ScreenPtr pScreen);
-void vesaEnable(ScreenPtr pScreen);
+Bool vesaEnable(ScreenPtr pScreen);
void vesaDisable(ScreenPtr pScreen);
void vesaPreserve(KdCardInfo *card);
void vesaRestore(KdCardInfo *card);