- This is the new version of libvgl jointly developed by sos and I.
It adds new functions and extend some structures and can handle VESA modes. - Update the man page. - Bump the library version number. (The old version will be added to compat3x.)
This commit is contained in:
parent
d7ccb880d1
commit
5acf51ea02
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=53013
@ -1,6 +1,6 @@
|
||||
# $FreeBSD$
|
||||
LIB= vgl
|
||||
SHLIB_MAJOR= 1
|
||||
SHLIB_MAJOR= 2
|
||||
SHLIB_MINOR= 0
|
||||
CFLAGS+=-Wall -I${.CURDIR}
|
||||
SRCS= main.c simple.c bitmap.c text.c mouse.c keyboard.c
|
||||
|
@ -30,9 +30,11 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <machine/console.h>
|
||||
#include "vgl.h"
|
||||
|
||||
static byte VGLPlane[4][128];
|
||||
#define min(x, y) (((x) < (y)) ? (x) : (y))
|
||||
|
||||
static byte mask[8] = {0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
|
||||
static int color2bit[16] = {0x00000000, 0x00000001, 0x00000100, 0x00000101,
|
||||
0x00010000, 0x00010001, 0x00010100, 0x00010101,
|
||||
@ -43,20 +45,28 @@ static void
|
||||
WriteVerticalLine(VGLBitmap *dst, int x, int y, int width, byte *line)
|
||||
{
|
||||
int i, pos, last, planepos, start_offset, end_offset, offset;
|
||||
int len;
|
||||
unsigned int word = 0;
|
||||
byte *address;
|
||||
byte *VGLPlane[4];
|
||||
|
||||
switch (dst->Type) {
|
||||
case VIDBUF4:
|
||||
address = dst->Bitmap + (dst->Xsize/8 * y) + x/8;
|
||||
case VIDBUF4S:
|
||||
start_offset = (x & 0x07);
|
||||
end_offset = (x + width) & 0x07;
|
||||
offset = start_offset;
|
||||
i = (width + start_offset) / 8;
|
||||
if (end_offset)
|
||||
i++;
|
||||
VGLPlane[0] = VGLBuf;
|
||||
VGLPlane[1] = VGLPlane[0] + i;
|
||||
VGLPlane[2] = VGLPlane[1] + i;
|
||||
VGLPlane[3] = VGLPlane[2] + i;
|
||||
pos = 0;
|
||||
planepos = 0;
|
||||
last = 8 - start_offset;
|
||||
while (pos < width) {
|
||||
word = 0;
|
||||
last = pos + 8 - offset;
|
||||
while (pos < last && pos < width)
|
||||
word = (word<<1) | color2bit[line[pos++]&0x0f];
|
||||
VGLPlane[0][planepos] = word;
|
||||
@ -64,7 +74,7 @@ WriteVerticalLine(VGLBitmap *dst, int x, int y, int width, byte *line)
|
||||
VGLPlane[2][planepos] = word>>16;
|
||||
VGLPlane[3][planepos] = word>>24;
|
||||
planepos++;
|
||||
offset = 0;
|
||||
last += 8;
|
||||
}
|
||||
planepos--;
|
||||
if (end_offset) {
|
||||
@ -76,20 +86,43 @@ WriteVerticalLine(VGLBitmap *dst, int x, int y, int width, byte *line)
|
||||
}
|
||||
if (start_offset || end_offset)
|
||||
width+=8;
|
||||
width /= 8;
|
||||
outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */
|
||||
outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */
|
||||
for (i=0; i<4; i++) {
|
||||
outb(0x3c4, 0x02);
|
||||
outb(0x3c5, 0x01<<i);
|
||||
outb(0x3ce, 0x04);
|
||||
outb(0x3cf, i);
|
||||
if (start_offset)
|
||||
VGLPlane[i][0] |= *address & ~mask[start_offset];
|
||||
if (end_offset)
|
||||
VGLPlane[i][planepos] |= *(address + planepos) & mask[end_offset];
|
||||
bcopy(&VGLPlane[i][0], address, width/8);
|
||||
pos = VGLAdpInfo.va_line_width*y + x/8;
|
||||
if (dst->Type == VIDBUF4) {
|
||||
if (end_offset)
|
||||
VGLPlane[i][planepos] |= dst->Bitmap[pos+planepos] & mask[end_offset];
|
||||
if (start_offset)
|
||||
VGLPlane[i][0] |= dst->Bitmap[pos] & ~mask[start_offset];
|
||||
bcopy(&VGLPlane[i][0], dst->Bitmap + pos, width);
|
||||
} else { /* VIDBUF4S */
|
||||
if (end_offset) {
|
||||
offset = VGLSetSegment(pos + planepos);
|
||||
VGLPlane[i][planepos] |= dst->Bitmap[offset] & mask[end_offset];
|
||||
}
|
||||
offset = VGLSetSegment(pos);
|
||||
if (start_offset)
|
||||
VGLPlane[i][0] |= dst->Bitmap[offset] & ~mask[start_offset];
|
||||
for (last = width; ; ) {
|
||||
len = min(VGLAdpInfo.va_window_size - offset, last);
|
||||
bcopy(&VGLPlane[i][width - last], dst->Bitmap + offset, len);
|
||||
pos += len;
|
||||
last -= len;
|
||||
if (last <= 0)
|
||||
break;
|
||||
offset = VGLSetSegment(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VIDBUF8X:
|
||||
address = dst->Bitmap + (dst->Xsize/2 * y) + x/4;
|
||||
address = dst->Bitmap + VGLAdpInfo.va_line_width * y + x/4;
|
||||
for (i=0; i<4; i++) {
|
||||
outb(0x3c4, 0x02);
|
||||
outb(0x3c5, 0x01 << ((x + i)%4));
|
||||
@ -99,9 +132,20 @@ WriteVerticalLine(VGLBitmap *dst, int x, int y, int width, byte *line)
|
||||
++address;
|
||||
}
|
||||
break;
|
||||
case VIDBUF8S:
|
||||
pos = dst->VXsize * y + x;
|
||||
while (width > 0) {
|
||||
offset = VGLSetSegment(pos);
|
||||
i = min(VGLAdpInfo.va_window_size - offset, width);
|
||||
bcopy(line, dst->Bitmap + offset, i);
|
||||
line += i;
|
||||
pos += i;
|
||||
width -= i;
|
||||
}
|
||||
break;
|
||||
case VIDBUF8:
|
||||
case MEMBUF:
|
||||
address = dst->Bitmap + (dst->Xsize * y) + x;
|
||||
address = dst->Bitmap + dst->VXsize * y + x;
|
||||
bcopy(line, address, width);
|
||||
break;
|
||||
|
||||
@ -113,40 +157,67 @@ static void
|
||||
ReadVerticalLine(VGLBitmap *src, int x, int y, int width, byte *line)
|
||||
{
|
||||
int i, bit, pos, count, planepos, start_offset, end_offset, offset;
|
||||
int width2, len;
|
||||
byte *address;
|
||||
byte *VGLPlane[4];
|
||||
|
||||
switch (src->Type) {
|
||||
case VIDBUF4:
|
||||
address = src->Bitmap + (src->Xsize/8 * y) + x/8;
|
||||
case VIDBUF4S:
|
||||
start_offset = (x & 0x07);
|
||||
end_offset = (x + width) & 0x07;
|
||||
offset = start_offset;
|
||||
if (start_offset)
|
||||
count = (width - (8 - start_offset)) / 8 + 1;
|
||||
else
|
||||
count = width / 8;
|
||||
count = (width + start_offset) / 8;
|
||||
if (end_offset)
|
||||
count++;
|
||||
count++;
|
||||
VGLPlane[0] = VGLBuf;
|
||||
VGLPlane[1] = VGLPlane[0] + count;
|
||||
VGLPlane[2] = VGLPlane[1] + count;
|
||||
VGLPlane[3] = VGLPlane[2] + count;
|
||||
for (i=0; i<4; i++) {
|
||||
outb(0x3ce, 0x04);
|
||||
outb(0x3cf, i);
|
||||
pos = VGLAdpInfo.va_line_width*y + x/8;
|
||||
for (width2 = count; width2 > 0; ) {
|
||||
offset = VGLSetSegment(pos);
|
||||
len = min(VGLAdpInfo.va_window_size - offset, width2);
|
||||
bcopy(src->Bitmap + offset, &VGLPlane[i][count - width2], len);
|
||||
pos += len;
|
||||
width2 -= len;
|
||||
}
|
||||
}
|
||||
goto read_planar;
|
||||
case VIDBUF4:
|
||||
address = src->Bitmap + VGLAdpInfo.va_line_width * y + x/8;
|
||||
start_offset = (x & 0x07);
|
||||
end_offset = (x + width) & 0x07;
|
||||
count = (width + start_offset) / 8;
|
||||
if (end_offset)
|
||||
count++;
|
||||
VGLPlane[0] = VGLBuf;
|
||||
VGLPlane[1] = VGLPlane[0] + count;
|
||||
VGLPlane[2] = VGLPlane[1] + count;
|
||||
VGLPlane[3] = VGLPlane[2] + count;
|
||||
for (i=0; i<4; i++) {
|
||||
outb(0x3ce, 0x04);
|
||||
outb(0x3cf, i);
|
||||
bcopy(address, &VGLPlane[i][0], count);
|
||||
}
|
||||
read_planar:
|
||||
pos = 0;
|
||||
planepos = 0;
|
||||
bit = 7 - start_offset;
|
||||
while (pos < width) {
|
||||
for (bit = (7-offset); bit >= 0 && pos < width; bit--, pos++) {
|
||||
for (; bit >= 0 && pos < width; bit--, pos++) {
|
||||
line[pos] = (VGLPlane[0][planepos] & (1<<bit) ? 1 : 0) |
|
||||
((VGLPlane[1][planepos] & (1<<bit) ? 1 : 0) << 1) |
|
||||
((VGLPlane[2][planepos] & (1<<bit) ? 1 : 0) << 2) |
|
||||
((VGLPlane[3][planepos] & (1<<bit) ? 1 : 0) << 3);
|
||||
}
|
||||
planepos++;
|
||||
offset = 0;
|
||||
bit = 7;
|
||||
}
|
||||
break;
|
||||
case VIDBUF8X:
|
||||
address = src->Bitmap + (src->Xsize/2 * y) + x/4;
|
||||
address = src->Bitmap + VGLAdpInfo.va_line_width * y + x/4;
|
||||
for (i=0; i<4; i++) {
|
||||
outb(0x3ce, 0x04);
|
||||
outb(0x3cf, (x + i)%4);
|
||||
@ -156,9 +227,20 @@ ReadVerticalLine(VGLBitmap *src, int x, int y, int width, byte *line)
|
||||
++address;
|
||||
}
|
||||
break;
|
||||
case VIDBUF8S:
|
||||
pos = src->VXsize * y + x;
|
||||
while (width > 0) {
|
||||
offset = VGLSetSegment(pos);
|
||||
i = min(VGLAdpInfo.va_window_size - offset, width);
|
||||
bcopy(src->Bitmap + offset, line, i);
|
||||
line += i;
|
||||
pos += i;
|
||||
width -= i;
|
||||
}
|
||||
break;
|
||||
case VIDBUF8:
|
||||
case MEMBUF:
|
||||
address = src->Bitmap + (src->Xsize * y) + x;
|
||||
address = src->Bitmap + src->VXsize * y + x;
|
||||
bcopy(address, line, width);
|
||||
break;
|
||||
default:
|
||||
@ -171,7 +253,8 @@ __VGLBitmapCopy(VGLBitmap *src, int srcx, int srcy,
|
||||
{
|
||||
int srcline, dstline;
|
||||
|
||||
if (srcx>src->Xsize||srcy>src->Ysize||dstx>dst->Xsize||dsty>dst->Ysize)
|
||||
if (srcx>src->VXsize || srcy>src->VYsize
|
||||
|| dstx>dst->VXsize || dsty>dst->VYsize)
|
||||
return -1;
|
||||
if (srcx < 0) {
|
||||
width=width+srcx; dstx-=srcx; srcx=0;
|
||||
@ -185,34 +268,45 @@ __VGLBitmapCopy(VGLBitmap *src, int srcx, int srcy,
|
||||
if (dsty < 0) {
|
||||
hight=hight+dsty; srcy-=dsty; dsty=0;
|
||||
}
|
||||
if (srcx+width > src->Xsize)
|
||||
width=src->Xsize-srcx;
|
||||
if (srcy+hight > src->Ysize)
|
||||
hight=src->Ysize-srcy;
|
||||
if (dstx+width > dst->Xsize)
|
||||
width=dst->Xsize-dstx;
|
||||
if (dsty+hight > dst->Ysize)
|
||||
hight=dst->Ysize-dsty;
|
||||
if (srcx+width > src->VXsize)
|
||||
width=src->VXsize-srcx;
|
||||
if (srcy+hight > src->VYsize)
|
||||
hight=src->VYsize-srcy;
|
||||
if (dstx+width > dst->VXsize)
|
||||
width=dst->VXsize-dstx;
|
||||
if (dsty+hight > dst->VYsize)
|
||||
hight=dst->VYsize-dsty;
|
||||
if (width < 0 || hight < 0)
|
||||
return -1;
|
||||
if (src->Type == MEMBUF) {
|
||||
for (srcline=srcy, dstline=dsty; srcline<srcy+hight; srcline++, dstline++) {
|
||||
WriteVerticalLine(dst, dstx, dstline, width,
|
||||
(src->Bitmap+(srcline*src->Xsize)+srcx));
|
||||
(src->Bitmap+(srcline*src->VXsize)+srcx));
|
||||
}
|
||||
}
|
||||
else if (dst->Type == MEMBUF) {
|
||||
for (srcline=srcy, dstline=dsty; srcline<srcy+hight; srcline++, dstline++) {
|
||||
ReadVerticalLine(src, srcx, srcline, width,
|
||||
(dst->Bitmap+(dstline*dst->Xsize)+dstx));
|
||||
(dst->Bitmap+(dstline*dst->VXsize)+dstx));
|
||||
}
|
||||
}
|
||||
else {
|
||||
byte buffer[1024];
|
||||
for (srcline=srcy, dstline=dsty; srcline<srcy+hight; srcline++, dstline++) {
|
||||
ReadVerticalLine(src, srcx, srcline, width, buffer);
|
||||
WriteVerticalLine(dst, dstx, dstline, width, buffer);
|
||||
byte buffer[2048]; /* XXX */
|
||||
byte *p;
|
||||
|
||||
if (width > sizeof(buffer)) {
|
||||
p = malloc(width);
|
||||
if (p == NULL)
|
||||
return 1;
|
||||
} else {
|
||||
p = buffer;
|
||||
}
|
||||
for (srcline=srcy, dstline=dsty; srcline<srcy+hight; srcline++, dstline++) {
|
||||
ReadVerticalLine(src, srcx, srcline, width, p);
|
||||
WriteVerticalLine(dst, dstx, dstline, width, p);
|
||||
}
|
||||
if (width > sizeof(buffer))
|
||||
free(p);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -229,3 +323,42 @@ VGLBitmapCopy(VGLBitmap *src, int srcx, int srcy,
|
||||
return error;
|
||||
}
|
||||
|
||||
VGLBitmap
|
||||
*VGLBitmapCreate(int type, int xsize, int ysize, byte *bits)
|
||||
{
|
||||
VGLBitmap *object;
|
||||
|
||||
if (type != MEMBUF)
|
||||
return NULL;
|
||||
if (xsize < 0 || ysize < 0)
|
||||
return NULL;
|
||||
object = (VGLBitmap *)malloc(sizeof(*object));
|
||||
if (object == NULL)
|
||||
return NULL;
|
||||
object->Type = type;
|
||||
object->Xsize = xsize;
|
||||
object->Ysize = ysize;
|
||||
object->VXsize = xsize;
|
||||
object->VYsize = ysize;
|
||||
object->Xorigin = 0;
|
||||
object->Yorigin = 0;
|
||||
object->Bitmap = bits;
|
||||
return object;
|
||||
}
|
||||
|
||||
void
|
||||
VGLBitmapDestroy(VGLBitmap *object)
|
||||
{
|
||||
if (object->Bitmap)
|
||||
free(object->Bitmap);
|
||||
free(object);
|
||||
}
|
||||
|
||||
int
|
||||
VGLBitmapAllocateBits(VGLBitmap *object)
|
||||
{
|
||||
object->Bitmap = (byte *)malloc(object->VXsize*object->VYsize);
|
||||
if (object->Bitmap == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -37,14 +37,21 @@
|
||||
#include <machine/console.h>
|
||||
#include "vgl.h"
|
||||
|
||||
#define min(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#define max(x, y) (((x) > (y)) ? (x) : (y))
|
||||
|
||||
VGLBitmap *VGLDisplay;
|
||||
video_info_t VGLModeInfo;
|
||||
video_adapter_info_t VGLAdpInfo;
|
||||
byte *VGLBuf;
|
||||
|
||||
static int VGLMode;
|
||||
static int VGLOldMode;
|
||||
static byte *VGLBuf;
|
||||
static byte *VGLMem;
|
||||
static size_t VGLBufSize;
|
||||
static byte *VGLMem = MAP_FAILED;
|
||||
static int VGLSwitchPending;
|
||||
static int VGLOnDisplay;
|
||||
static unsigned int VGLCurWindow;
|
||||
static int VGLInitDone = 0;
|
||||
|
||||
void
|
||||
@ -54,11 +61,15 @@ struct vt_mode smode;
|
||||
|
||||
if (!VGLInitDone)
|
||||
return;
|
||||
if (VGLOnDisplay && !VGLSwitchPending) {
|
||||
outb(0x3c4, 0x02);
|
||||
outb(0x3c5, 0x0f);
|
||||
bzero(VGLMem, 64*1024);
|
||||
VGLInitDone = 0;
|
||||
|
||||
signal(SIGUSR1, SIG_IGN);
|
||||
|
||||
if (VGLMem != MAP_FAILED) {
|
||||
VGLClear(VGLDisplay, 0);
|
||||
munmap(VGLMem, VGLAdpInfo.va_window_size);
|
||||
}
|
||||
|
||||
if (VGLOldMode >= M_VESA_BASE) {
|
||||
/* ugly, but necessary */
|
||||
ioctl(0, _IO('V', VGLOldMode - M_VESA_BASE), 0);
|
||||
@ -76,8 +87,11 @@ struct vt_mode smode;
|
||||
ioctl(0, KDSETMODE, KD_TEXT);
|
||||
smode.mode = VT_AUTO;
|
||||
ioctl(0, VT_SETMODE, &smode);
|
||||
free(VGLBuf);
|
||||
if (VGLBuf)
|
||||
free(VGLBuf);
|
||||
VGLBuf = NULL;
|
||||
free(VGLDisplay);
|
||||
VGLDisplay = NULL;
|
||||
VGLKeyboardEnd();
|
||||
}
|
||||
|
||||
@ -103,8 +117,10 @@ int
|
||||
VGLInit(int mode)
|
||||
{
|
||||
struct vt_mode smode;
|
||||
struct winsize winsz;
|
||||
int error;
|
||||
int adptype;
|
||||
|
||||
if (VGLInitDone)
|
||||
return -1;
|
||||
|
||||
signal(SIGUSR1, VGLSwitch);
|
||||
signal(SIGINT, VGLAbort);
|
||||
@ -115,76 +131,142 @@ VGLInit(int mode)
|
||||
VGLOnDisplay = 1;
|
||||
VGLSwitchPending = 0;
|
||||
|
||||
ioctl(0, CONS_GET, &VGLOldMode);
|
||||
if (ioctl(0, CONS_GET, &VGLOldMode) || ioctl(0, CONS_CURRENT, &adptype))
|
||||
return -1;
|
||||
if (IOCGROUP(mode) == 'V') /* XXX: this is ugly */
|
||||
VGLModeInfo.vi_mode = (mode & 0x0ff) + M_VESA_BASE;
|
||||
else
|
||||
VGLModeInfo.vi_mode = mode & 0x0ff;
|
||||
if (ioctl(0, CONS_MODEINFO, &VGLModeInfo)) /* FBIO_MODEINFO */
|
||||
return -1;
|
||||
|
||||
VGLMem = (byte*)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_FILE,
|
||||
open("/dev/mem", O_RDWR), 0xA0000);
|
||||
if (VGLMem <= (byte*)0)
|
||||
return 1;
|
||||
VGLDisplay = (VGLBitmap *)malloc(sizeof(VGLBitmap));
|
||||
if (VGLDisplay == NULL)
|
||||
return -2;
|
||||
|
||||
VGLBuf = (byte*)malloc(256*1024);
|
||||
if (VGLBuf == NULL)
|
||||
return 1;
|
||||
|
||||
VGLDisplay = (VGLBitmap*) malloc(sizeof(VGLBitmap));
|
||||
if (VGLDisplay == NULL) {
|
||||
free(VGLBuf);
|
||||
return 1;
|
||||
if (ioctl(0, KDENABIO, 0)) {
|
||||
free(VGLDisplay);
|
||||
return -3;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case SW_BG640x480: case SW_CG640x480:
|
||||
VGLInitDone = 1;
|
||||
|
||||
/*
|
||||
* vi_mem_model specifies the memory model of the current video mode
|
||||
* in -CURRENT.
|
||||
*/
|
||||
switch (VGLModeInfo.vi_mem_model) {
|
||||
case V_INFO_MM_PLANAR:
|
||||
/* we can handle EGA/VGA planner modes only */
|
||||
if (VGLModeInfo.vi_depth != 4 || VGLModeInfo.vi_planes != 4
|
||||
|| (adptype != KD_EGA && adptype != KD_VGA)) {
|
||||
VGLEnd();
|
||||
return -4;
|
||||
}
|
||||
VGLDisplay->Type = VIDBUF4;
|
||||
break;
|
||||
case SW_VGA_CG320:
|
||||
case V_INFO_MM_PACKED:
|
||||
/* we can do only 256 color packed modes */
|
||||
if (VGLModeInfo.vi_depth != 8) {
|
||||
VGLEnd();
|
||||
return -4;
|
||||
}
|
||||
VGLDisplay->Type = VIDBUF8;
|
||||
break;
|
||||
case SW_VGA_MODEX:
|
||||
case V_INFO_MM_VGAX:
|
||||
VGLDisplay->Type = VIDBUF8X;
|
||||
break;
|
||||
default:
|
||||
VGLEnd();
|
||||
return 1;
|
||||
return -4;
|
||||
}
|
||||
|
||||
if ((error = ioctl(0, KDENABIO, 0)))
|
||||
return error;
|
||||
|
||||
ioctl(0, VT_WAITACTIVE, 0);
|
||||
ioctl(0, KDSETMODE, KD_GRAPHICS);
|
||||
if ((error = ioctl(0, mode, 0))) {
|
||||
ioctl(0, KDSETMODE, KD_TEXT);
|
||||
ioctl(0, KDDISABIO, 0);
|
||||
return error;
|
||||
if (ioctl(0, mode, 0)) {
|
||||
VGLEnd();
|
||||
return -5;
|
||||
}
|
||||
if (ioctl(0, CONS_ADPINFO, &VGLAdpInfo)) { /* FBIO_ADPINFO */
|
||||
VGLEnd();
|
||||
return -6;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the shadow screen buffer size. In -CURRENT, va_buffer_size
|
||||
* always holds the entire frame buffer size, wheather it's in the linear
|
||||
* mode or windowed mode.
|
||||
* VGLBufSize = VGLAdpInfo.va_buffer_size;
|
||||
* In -STABLE, va_buffer_size holds the frame buffer size, only if
|
||||
* the linear frame buffer mode is supported. Otherwise the field is zero.
|
||||
* We shall calculate the minimal size in this case:
|
||||
* VGLAdpInfo.va_line_width*VGLModeInfo.vi_height*VGLModeInfo.vi_planes
|
||||
* or
|
||||
* VGLAdpInfo.va_window_size*VGLModeInfo.vi_planes;
|
||||
* Use whichever is larger.
|
||||
*/
|
||||
if (VGLAdpInfo.va_buffer_size != 0)
|
||||
VGLBufSize = VGLAdpInfo.va_buffer_size;
|
||||
else
|
||||
VGLBufSize = max(VGLAdpInfo.va_line_width*VGLModeInfo.vi_height,
|
||||
VGLAdpInfo.va_window_size)*VGLModeInfo.vi_planes;
|
||||
VGLBuf = malloc(VGLBufSize);
|
||||
if (VGLBuf == NULL) {
|
||||
VGLEnd();
|
||||
return -7;
|
||||
}
|
||||
|
||||
#ifdef LIBVGL_DEBUG
|
||||
fprintf(stderr, "VGLBufSize:0x%x\n", VGLBufSize);
|
||||
#endif
|
||||
|
||||
/* see if we are in the windowed buffer mode or in the linear buffer mode */
|
||||
if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size) {
|
||||
if (VGLDisplay->Type == VIDBUF4)
|
||||
VGLDisplay->Type = VIDBUF4S;
|
||||
else if (VGLDisplay->Type == VIDBUF8)
|
||||
VGLDisplay->Type = VIDBUF8S;
|
||||
}
|
||||
|
||||
VGLMode = mode;
|
||||
VGLCurWindow = 0;
|
||||
|
||||
outb(0x3c4, 0x02);
|
||||
outb(0x3c5, 0x0f);
|
||||
bzero(VGLMem, 64*1024);
|
||||
VGLDisplay->Xsize = VGLModeInfo.vi_width;
|
||||
VGLDisplay->Ysize = VGLModeInfo.vi_height;
|
||||
VGLDisplay->VXsize = VGLAdpInfo.va_line_width
|
||||
*8/(VGLModeInfo.vi_depth/VGLModeInfo.vi_planes);
|
||||
VGLDisplay->VYsize = VGLBufSize/VGLModeInfo.vi_planes/VGLAdpInfo.va_line_width;
|
||||
VGLDisplay->Xorigin = 0;
|
||||
VGLDisplay->Yorigin = 0;
|
||||
|
||||
if (ioctl(0, TIOCGWINSZ, &winsz)) {
|
||||
VGLMem = (byte*)mmap(0, VGLAdpInfo.va_window_size, PROT_READ|PROT_WRITE,
|
||||
MAP_FILE, 0, 0);
|
||||
if (VGLMem == MAP_FAILED) {
|
||||
VGLEnd();
|
||||
return 1;
|
||||
return -7;
|
||||
}
|
||||
|
||||
VGLDisplay->Bitmap = VGLMem;
|
||||
VGLDisplay->Xsize = winsz.ws_xpixel;
|
||||
VGLDisplay->Ysize = winsz.ws_ypixel;
|
||||
|
||||
VGLSavePalette();
|
||||
|
||||
#ifdef LIBVGL_DEBUG
|
||||
fprintf(stderr, "va_line_width:%d\n", VGLAdpInfo.va_line_width);
|
||||
fprintf(stderr, "VGLXsize:%d, Ysize:%d, VXsize:%d, VYsize:%d\n",
|
||||
VGLDisplay->Xsize, VGLDisplay->Ysize,
|
||||
VGLDisplay->VXsize, VGLDisplay->VYsize);
|
||||
#endif
|
||||
|
||||
smode.mode = VT_PROCESS;
|
||||
smode.waitv = 0;
|
||||
smode.relsig = SIGUSR1;
|
||||
smode.acqsig = SIGUSR1;
|
||||
smode.frsig = SIGINT;
|
||||
if (ioctl(0, VT_SETMODE, &smode) == -1) {
|
||||
if (ioctl(0, VT_SETMODE, &smode)) {
|
||||
VGLEnd();
|
||||
return 1;
|
||||
return -9;
|
||||
}
|
||||
VGLTextSetFontFile((byte*)0);
|
||||
VGLInitDone = 1;
|
||||
VGLClear(VGLDisplay, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -192,6 +274,8 @@ void
|
||||
VGLCheckSwitch()
|
||||
{
|
||||
while (VGLSwitchPending) {
|
||||
unsigned int offset;
|
||||
unsigned int len;
|
||||
int i;
|
||||
|
||||
VGLSwitchPending = 0;
|
||||
@ -199,44 +283,195 @@ VGLCheckSwitch()
|
||||
ioctl(0, KDENABIO, 0);
|
||||
ioctl(0, KDSETMODE, KD_GRAPHICS);
|
||||
ioctl(0, VGLMode, 0);
|
||||
outb(0x3c6, 0xff);
|
||||
for (i=0; i<4; i++) {
|
||||
outb(0x3c4, 0x02);
|
||||
outb(0x3c5, 0x01<<i);
|
||||
bcopy(&VGLBuf[i*64*1024], VGLMem, 64*1024);
|
||||
VGLCurWindow = 0;
|
||||
VGLMem = (byte*)mmap(0, VGLAdpInfo.va_window_size, PROT_READ|PROT_WRITE,
|
||||
MAP_FILE, 0, 0);
|
||||
|
||||
/* XXX: what if mmap() has failed! */
|
||||
VGLDisplay->Type = VIDBUF8; /* XXX */
|
||||
switch (VGLModeInfo.vi_mem_model) {
|
||||
case V_INFO_MM_PLANAR:
|
||||
if (VGLModeInfo.vi_depth == 4 && VGLModeInfo.vi_planes == 4) {
|
||||
if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size)
|
||||
VGLDisplay->Type = VIDBUF4S;
|
||||
else
|
||||
VGLDisplay->Type = VIDBUF4;
|
||||
} else {
|
||||
/* shouldn't be happening */
|
||||
}
|
||||
break;
|
||||
case V_INFO_MM_PACKED:
|
||||
if (VGLModeInfo.vi_depth == 8) {
|
||||
if (VGLBufSize/VGLModeInfo.vi_planes > VGLAdpInfo.va_window_size)
|
||||
VGLDisplay->Type = VIDBUF8S;
|
||||
else
|
||||
VGLDisplay->Type = VIDBUF8;
|
||||
} else {
|
||||
/* shouldn't be happening */
|
||||
}
|
||||
break;
|
||||
case V_INFO_MM_VGAX:
|
||||
VGLDisplay->Type = VIDBUF8X;
|
||||
break;
|
||||
default:
|
||||
/* shouldn't be happening */
|
||||
break;
|
||||
}
|
||||
|
||||
VGLDisplay->Bitmap = VGLMem;
|
||||
VGLDisplay->Xsize = VGLModeInfo.vi_width;
|
||||
VGLDisplay->Ysize = VGLModeInfo.vi_height;
|
||||
VGLSetVScreenSize(VGLDisplay, VGLDisplay->VXsize, VGLDisplay->VYsize);
|
||||
VGLPanScreen(VGLDisplay, VGLDisplay->Xorigin, VGLDisplay->Yorigin);
|
||||
switch (VGLDisplay->Type) {
|
||||
case VIDBUF4S:
|
||||
outb(0x3c6, 0xff);
|
||||
outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */
|
||||
outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */
|
||||
for (offset = 0; offset < VGLBufSize/VGLModeInfo.vi_planes;
|
||||
offset += len) {
|
||||
VGLSetSegment(offset);
|
||||
len = min(VGLBufSize/VGLModeInfo.vi_planes - offset,
|
||||
VGLAdpInfo.va_window_size);
|
||||
for (i = 0; i < VGLModeInfo.vi_planes; i++) {
|
||||
outb(0x3c4, 0x02);
|
||||
outb(0x3c5, 0x01<<i);
|
||||
bcopy(&VGLBuf[i*VGLBufSize/VGLModeInfo.vi_planes + offset],
|
||||
VGLMem, len);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VIDBUF4:
|
||||
case VIDBUF8X:
|
||||
outb(0x3c6, 0xff);
|
||||
outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */
|
||||
outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */
|
||||
for (i = 0; i < VGLModeInfo.vi_planes; i++) {
|
||||
outb(0x3c4, 0x02);
|
||||
outb(0x3c5, 0x01<<i);
|
||||
bcopy(&VGLBuf[i*VGLAdpInfo.va_window_size], VGLMem,
|
||||
VGLAdpInfo.va_window_size);
|
||||
}
|
||||
break;
|
||||
case VIDBUF8:
|
||||
case VIDBUF8S:
|
||||
for (offset = 0; offset < VGLBufSize; offset += len) {
|
||||
VGLSetSegment(offset);
|
||||
len = min(VGLBufSize - offset, VGLAdpInfo.va_window_size);
|
||||
bcopy(&VGLBuf[offset], VGLMem, len);
|
||||
}
|
||||
break;
|
||||
}
|
||||
VGLRestorePalette();
|
||||
ioctl(0, VT_RELDISP, VT_ACKACQ);
|
||||
VGLDisplay->Bitmap = VGLMem;
|
||||
switch (VGLMode) {
|
||||
case SW_BG640x480: case SW_CG640x480:
|
||||
VGLDisplay->Type = VIDBUF4;
|
||||
break;
|
||||
case SW_VGA_CG320:
|
||||
VGLDisplay->Type = VIDBUF8;
|
||||
break;
|
||||
case SW_VGA_MODEX:
|
||||
VGLDisplay->Type = VIDBUF8X;
|
||||
break;
|
||||
default:
|
||||
VGLDisplay->Type = VIDBUF8; /* XXX */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i=0; i<4; i++) {
|
||||
outb(0x3ce, 0x04);
|
||||
outb(0x3cf, i);
|
||||
bcopy(VGLMem, &VGLBuf[i*64*1024], 64*1024);
|
||||
switch (VGLDisplay->Type) {
|
||||
case VIDBUF4S:
|
||||
for (offset = 0; offset < VGLBufSize/VGLModeInfo.vi_planes;
|
||||
offset += len) {
|
||||
VGLSetSegment(offset);
|
||||
len = min(VGLBufSize/VGLModeInfo.vi_planes - offset,
|
||||
VGLAdpInfo.va_window_size);
|
||||
for (i = 0; i < VGLModeInfo.vi_planes; i++) {
|
||||
outb(0x3ce, 0x04);
|
||||
outb(0x3cf, i);
|
||||
bcopy(VGLMem, &VGLBuf[i*VGLBufSize/VGLModeInfo.vi_planes + offset],
|
||||
len);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VIDBUF4:
|
||||
case VIDBUF8X:
|
||||
/*
|
||||
* NOTE: the saved buffer is NOT in the MEMBUF format which
|
||||
* the ordinary memory bitmap object is stored in. XXX
|
||||
*/
|
||||
for (i = 0; i < VGLModeInfo.vi_planes; i++) {
|
||||
outb(0x3ce, 0x04);
|
||||
outb(0x3cf, i);
|
||||
bcopy(VGLMem, &VGLBuf[i*VGLAdpInfo.va_window_size],
|
||||
VGLAdpInfo.va_window_size);
|
||||
}
|
||||
break;
|
||||
case VIDBUF8:
|
||||
case VIDBUF8S:
|
||||
for (offset = 0; offset < VGLBufSize; offset += len) {
|
||||
VGLSetSegment(offset);
|
||||
len = min(VGLBufSize - offset, VGLAdpInfo.va_window_size);
|
||||
bcopy(VGLMem, &VGLBuf[offset], len);
|
||||
}
|
||||
break;
|
||||
}
|
||||
VGLMem = MAP_FAILED;
|
||||
munmap(VGLDisplay->Bitmap, VGLAdpInfo.va_window_size);
|
||||
ioctl(0, VGLOldMode, 0);
|
||||
ioctl(0, KDSETMODE, KD_TEXT);
|
||||
ioctl(0, KDDISABIO, 0);
|
||||
ioctl(0, VT_RELDISP, VT_TRUE);
|
||||
VGLDisplay->Bitmap = VGLBuf;
|
||||
VGLDisplay->Type = MEMBUF;
|
||||
VGLDisplay->Xsize = VGLDisplay->VXsize;
|
||||
VGLDisplay->Ysize = VGLDisplay->VYsize;
|
||||
while (!VGLOnDisplay) pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
VGLSetSegment(unsigned int offset)
|
||||
{
|
||||
if (offset/VGLAdpInfo.va_window_size != VGLCurWindow) {
|
||||
ioctl(0, CONS_SETWINORG, offset); /* FBIO_SETWINORG */
|
||||
VGLCurWindow = offset/VGLAdpInfo.va_window_size;
|
||||
}
|
||||
return (offset%VGLAdpInfo.va_window_size);
|
||||
}
|
||||
|
||||
int
|
||||
VGLSetVScreenSize(VGLBitmap *object, int VXsize, int VYsize)
|
||||
{
|
||||
if (VXsize < object->Xsize || VYsize < object->Ysize)
|
||||
return -1;
|
||||
if (object->Type == MEMBUF)
|
||||
return -1;
|
||||
if (ioctl(0, FBIO_SETLINEWIDTH, &VXsize))
|
||||
return -1;
|
||||
ioctl(0, CONS_ADPINFO, &VGLAdpInfo); /* FBIO_ADPINFO */
|
||||
object->VXsize = VGLAdpInfo.va_line_width
|
||||
*8/(VGLModeInfo.vi_depth/VGLModeInfo.vi_planes);
|
||||
object->VYsize = VGLBufSize/VGLModeInfo.vi_planes/VGLAdpInfo.va_line_width;
|
||||
if (VYsize < object->VYsize)
|
||||
object->VYsize = VYsize;
|
||||
|
||||
#ifdef LIBVGL_DEBUG
|
||||
fprintf(stderr, "new size: VGLXsize:%d, Ysize:%d, VXsize:%d, VYsize:%d\n",
|
||||
object->Xsize, object->Ysize, object->VXsize, object->VYsize);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
VGLPanScreen(VGLBitmap *object, int x, int y)
|
||||
{
|
||||
video_display_start_t origin;
|
||||
|
||||
if (x < 0 || x + object->Xsize > object->VXsize
|
||||
|| y < 0 || y + object->Ysize > object->VYsize)
|
||||
return -1;
|
||||
if (object->Type == MEMBUF)
|
||||
return 0;
|
||||
origin.x = x;
|
||||
origin.y = y;
|
||||
if (ioctl(0, FBIO_SETDISPSTART, &origin))
|
||||
return -1;
|
||||
object->Xorigin = x;
|
||||
object->Yorigin = y;
|
||||
|
||||
#ifdef LIBVGL_DEBUG
|
||||
fprintf(stderr, "new origin: (%d, %d)\n", x, y);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -35,9 +35,6 @@
|
||||
#include <machine/console.h>
|
||||
#include "vgl.h"
|
||||
|
||||
/* prototype for internal function */
|
||||
int __VGLBitmapCopy(VGLBitmap *src, int srcx, int srcy, VGLBitmap *dst, int dstx, int dsty, int width, int hight);
|
||||
|
||||
#define X 0xff
|
||||
static byte StdAndMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = {
|
||||
X,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
@ -77,12 +74,13 @@ static byte StdOrMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = {
|
||||
};
|
||||
#undef X
|
||||
static VGLBitmap VGLMouseStdAndMask =
|
||||
{ MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdAndMask };
|
||||
VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdAndMask);
|
||||
static VGLBitmap VGLMouseStdOrMask =
|
||||
{ MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdOrMask };
|
||||
VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdOrMask);
|
||||
static VGLBitmap *VGLMouseAndMask, *VGLMouseOrMask;
|
||||
static byte map[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE];
|
||||
static VGLBitmap VGLMouseSave = { MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, map};
|
||||
static VGLBitmap VGLMouseSave =
|
||||
VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, map);
|
||||
static int VGLMouseVisible = 0;
|
||||
static int VGLMouseFrozen = 0;
|
||||
static int VGLMouseShown = 0;
|
||||
@ -94,7 +92,8 @@ void
|
||||
VGLMousePointerShow()
|
||||
{
|
||||
byte buf[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE];
|
||||
VGLBitmap buffer = { MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, buf };
|
||||
VGLBitmap buffer =
|
||||
VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, buf);
|
||||
byte crtcidx, crtcval, gdcidx, gdcval;
|
||||
int pos;
|
||||
|
||||
|
@ -38,45 +38,41 @@ static byte VGLSavePaletteBlue[256];
|
||||
|
||||
#define ABS(a) (((a)<0) ? -(a) : (a))
|
||||
#define SGN(a) (((a)<0) ? -1 : 1)
|
||||
|
||||
#define min(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#define max(x, y) (((x) > (y)) ? (x) : (y))
|
||||
|
||||
void
|
||||
VGLSetXY(VGLBitmap *object, int x, int y, byte color)
|
||||
{
|
||||
int offset;
|
||||
|
||||
VGLCheckSwitch();
|
||||
if (x>=0 && x<object->Xsize && y>=0 && y<object->Ysize) {
|
||||
if (x>=0 && x<object->VXsize && y>=0 && y<object->VYsize) {
|
||||
if (!VGLMouseFreeze(x, y, 1, 1, color)) {
|
||||
switch (object->Type) {
|
||||
case MEMBUF:
|
||||
case VIDBUF8:
|
||||
object->Bitmap[y*object->Xsize+x]=(color);
|
||||
object->Bitmap[y*object->VXsize+x]=(color);
|
||||
break;
|
||||
case VIDBUF8S:
|
||||
object->Bitmap[VGLSetSegment(y*object->VXsize+x)]=(color);
|
||||
break;
|
||||
case VIDBUF8X:
|
||||
outb(0x3c4, 0x02);
|
||||
outb(0x3c5, 0x01 << (x&0x3));
|
||||
object->Bitmap[(unsigned)(object->Xsize/2*y)+(x/4)] = (color);
|
||||
object->Bitmap[(unsigned)(VGLAdpInfo.va_line_width*y)+(x/4)] = (color);
|
||||
break;
|
||||
case VIDBUF4S:
|
||||
offset = VGLSetSegment(y*VGLAdpInfo.va_line_width + x/8);
|
||||
goto set_planar;
|
||||
case VIDBUF4:
|
||||
outb(0x3c4, 0x02); outb(0x3c5, 0x01);
|
||||
outb(0x3ce, 0x04); outb(0x3cf, 0x00);
|
||||
object->Bitmap[(y*object->Xsize/8+x/8)&0xffff] =
|
||||
( object->Bitmap[(y*object->Xsize/8+x/8)&0xffff] & ~(0x80>>(x%8)) )
|
||||
| ((color & 0x01) ? (0x80>>(x%8)) : 0);
|
||||
outb(0x3c4, 0x02); outb(0x3c5, 0x02);
|
||||
outb(0x3ce, 0x04); outb(0x3cf, 0x01);
|
||||
object->Bitmap[(y*object->Xsize/8+x/8)&0xffff] =
|
||||
( object->Bitmap[(y*object->Xsize/8+x/8)&0xffff] & ~(0x80>>(x%8)) )
|
||||
| ((color & 0x02) ? (0x80>>(x%8)) : 0);
|
||||
outb(0x3c4, 0x02); outb(0x3c5, 0x04);
|
||||
outb(0x3ce, 0x04); outb(0x3cf, 0x02);
|
||||
object->Bitmap[(y*object->Xsize/8+x/8)&0xffff] =
|
||||
( object->Bitmap[(y*object->Xsize/8+x/8)&0xffff] & ~(0x80>>(x%8)) )
|
||||
| ((color & 0x04) ? (0x80>>(x%8)) : 0);
|
||||
outb(0x3c4, 0x02); outb(0x3c5, 0x08);
|
||||
outb(0x3ce, 0x04); outb(0x3cf, 0x03);
|
||||
object->Bitmap[(y*object->Xsize/8+x/8)&0xffff] =
|
||||
( object->Bitmap[(y*object->Xsize/8+x/8)&0xffff] & ~(0x80>>(x%8)) )
|
||||
| ((color & 0x08) ? (0x80>>(x%8)) : 0);
|
||||
offset = y*VGLAdpInfo.va_line_width + x/8;
|
||||
set_planar:
|
||||
outb(0x3c4, 0x02); outb(0x3c5, 0x0f);
|
||||
outb(0x3ce, 0x00); outb(0x3cf, color & 0x0f); /* set/reset */
|
||||
outb(0x3ce, 0x01); outb(0x3cf, 0x0f); /* set/reset enable */
|
||||
outb(0x3ce, 0x08); outb(0x3cf, 0x80 >> (x%8)); /* bit mask */
|
||||
object->Bitmap[offset] |= color;
|
||||
}
|
||||
}
|
||||
VGLMouseUnFreeze();
|
||||
@ -86,19 +82,42 @@ VGLSetXY(VGLBitmap *object, int x, int y, byte color)
|
||||
byte
|
||||
VGLGetXY(VGLBitmap *object, int x, int y)
|
||||
{
|
||||
int offset;
|
||||
#if 0
|
||||
int i;
|
||||
byte color;
|
||||
byte mask;
|
||||
#endif
|
||||
|
||||
VGLCheckSwitch();
|
||||
if (x<0 || x>=object->VXsize || y<0 || y>=object->VYsize)
|
||||
return 0;
|
||||
switch (object->Type) {
|
||||
case MEMBUF:
|
||||
case VIDBUF8:
|
||||
return object->Bitmap[((y*object->Xsize)+x)];
|
||||
break;
|
||||
return object->Bitmap[((y*object->VXsize)+x)];
|
||||
case VIDBUF8S:
|
||||
return object->Bitmap[VGLSetSegment(y*object->VXsize+x)];
|
||||
case VIDBUF8X:
|
||||
outb(0x3ce, 0x04); outb(0x3cf, x & 0x3);
|
||||
return object->Bitmap[(unsigned)(object->Xsize/2*y)+(x/4)];
|
||||
break;
|
||||
return object->Bitmap[(unsigned)(VGLAdpInfo.va_line_width*y)+(x/4)];
|
||||
case VIDBUF4S:
|
||||
offset = VGLSetSegment(y*VGLAdpInfo.va_line_width + x/8);
|
||||
goto get_planar;
|
||||
case VIDBUF4:
|
||||
return (object->Bitmap[((y*object->Xsize/8)+x/8)]&(0x80>>(x%8))) ? 1 : 0;
|
||||
break;
|
||||
offset = y*VGLAdpInfo.va_line_width + x/8;
|
||||
get_planar:
|
||||
#if 1
|
||||
return (object->Bitmap[offset]&(0x80>>(x%8))) ? 1 : 0; /* XXX */
|
||||
#else
|
||||
color = 0;
|
||||
mask = 0x80 >> (x%8);
|
||||
for (i = 0; i < VGLModeInfo.vi_planes; i++) {
|
||||
outb(0x3ce, 0x04); outb(0x3cf, i);
|
||||
color |= (object->Bitmap[offset] & mask) ? (1 << i) : 0;
|
||||
}
|
||||
return color;
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -234,22 +253,49 @@ VGLFilledEllipse(VGLBitmap *object, int xc, int yc, int a, int b, byte color)
|
||||
void
|
||||
VGLClear(VGLBitmap *object, byte color)
|
||||
{
|
||||
int offset;
|
||||
int len;
|
||||
|
||||
VGLCheckSwitch();
|
||||
VGLMouseFreeze(0, 0, object->Xsize, object->Ysize, color);
|
||||
switch (object->Type) {
|
||||
case MEMBUF:
|
||||
case VIDBUF8:
|
||||
memset(object->Bitmap, color, object->Xsize*object->Ysize);
|
||||
memset(object->Bitmap, color, object->VXsize*object->VYsize);
|
||||
break;
|
||||
|
||||
case VIDBUF8S:
|
||||
for (offset = 0; offset < object->VXsize*object->VYsize; ) {
|
||||
VGLSetSegment(offset);
|
||||
len = min(object->VXsize*object->VYsize - offset,
|
||||
VGLAdpInfo.va_window_size);
|
||||
memset(object->Bitmap, color, len);
|
||||
offset += len;
|
||||
}
|
||||
break;
|
||||
|
||||
case VIDBUF8X:
|
||||
/* XXX works only for Xsize % 4 = 0 */
|
||||
outb(0x3c6, 0xff);
|
||||
outb(0x3c4, 0x02); outb(0x3c5, 0x0f);
|
||||
memset(object->Bitmap, color, object->Xsize*object->Ysize/4);
|
||||
memset(object->Bitmap, color, VGLAdpInfo.va_line_width*object->VYsize);
|
||||
break;
|
||||
|
||||
case VIDBUF4:
|
||||
case VIDBUF4S:
|
||||
/* XXX works only for Xsize % 8 = 0 */
|
||||
memset(object->Bitmap, color, object->Xsize/8*object->Ysize);
|
||||
outb(0x3c4, 0x02); outb(0x3c5, 0x0f);
|
||||
outb(0x3ce, 0x05); outb(0x3cf, 0x02); /* mode 2 */
|
||||
outb(0x3ce, 0x01); outb(0x3cf, 0x00); /* set/reset enable */
|
||||
outb(0x3ce, 0x08); outb(0x3cf, 0xff); /* bit mask */
|
||||
for (offset = 0; offset < VGLAdpInfo.va_line_width*object->VYsize; ) {
|
||||
VGLSetSegment(offset);
|
||||
len = min(object->VXsize*object->VYsize - offset,
|
||||
VGLAdpInfo.va_window_size);
|
||||
memset(object->Bitmap, color, len);
|
||||
offset += len;
|
||||
}
|
||||
outb(0x3ce, 0x05); outb(0x3cf, 0x00);
|
||||
break;
|
||||
}
|
||||
VGLMouseUnFreeze();
|
||||
|
@ -29,6 +29,7 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <machine/console.h>
|
||||
#include "vgl.h"
|
||||
|
||||
static VGLText *VGLTextFont = 0;
|
||||
|
107
lib/libvgl/vgl.3
107
lib/libvgl/vgl.3
@ -25,11 +25,14 @@
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.Dd October 28, 1999
|
||||
.Dd November 7, 1999
|
||||
.Dt VGL 3
|
||||
.Os FreeBSD 3.0
|
||||
.Sh NAME
|
||||
.Nm VGLBitmapAllocateBits ,
|
||||
.Nm VGLBitmapCopy ,
|
||||
.Nm VGLBitmapCreate ,
|
||||
.Nm VGLBitmapDestroy ,
|
||||
.Nm VGLBitmapPutChar ,
|
||||
.Nm VGLBitmapString ,
|
||||
.Nm VGLBlankDisplay ,
|
||||
@ -42,14 +45,19 @@
|
||||
.Nm VGLFilledEllipse ,
|
||||
.Nm VGLInit ,
|
||||
.Nm VGLLine ,
|
||||
.Nm VGLKeyboardInit ,
|
||||
.Nm VGLKeyboardEnd ,
|
||||
.Nm VGLKeyboardGetCh ,
|
||||
.Nm VGLMouseInit ,
|
||||
.Nm VGLMouseMode ,
|
||||
.Nm VGLMouseSetImage ,
|
||||
.Nm VGLMouseSetStdImage ,
|
||||
.Nm VGLMouseStatus ,
|
||||
.Nm VGLPanScreen ,
|
||||
.Nm VGLSetBorder ,
|
||||
.Nm VGLSetPalette ,
|
||||
.Nm VGLSetPaletteIndex ,
|
||||
.Nm VGLSetVScreenSize ,
|
||||
.Nm VGLTextSetFontFile
|
||||
.Nd Video Graphics Library functions (libvgl)
|
||||
.Sh SYNOPSIS
|
||||
@ -62,6 +70,12 @@
|
||||
.Fn VGLCheckSwitch "void"
|
||||
.Ft int
|
||||
.Fn VGLTextSetFontFile "char *filename"
|
||||
.Ft int
|
||||
.Fn VGLKeyboardInit "int code"
|
||||
.Ft void
|
||||
.Fn VGLKeyboardEnd "void"
|
||||
.Ft int
|
||||
.Fn VGLKeyboardGetCh "void"
|
||||
.Ft int
|
||||
.Fn VGLMouseInit "int mode"
|
||||
.Ft void
|
||||
@ -82,6 +96,12 @@
|
||||
.Fn VGLEllipse "VGLBitmap *object" "int xc" "int yc" "int a" "int b" "byte color"
|
||||
.Ft void
|
||||
.Fn VGLFilledEllipse "VGLBitmap *object" "int xc" "int yc" "int a" "int b" "byte color"
|
||||
.Ft VGLBitmap *
|
||||
.Fn VGLBitmapCreate "int type" "int xsize" "int ysize" "byte *bits"
|
||||
.Ft void
|
||||
.Fn VGLBitmapDestroy "VGLBitmap *object"
|
||||
.Ft int
|
||||
.Fn VGLBitmapAllocateBits "VGLBitmap *object"
|
||||
.Ft int
|
||||
.Fn VGLBitmapCopy "VGLBitmap *src" "int srcx" "int srcy" "VGLBitmap *dst" "int dstx" "int dsty" "int width" "int hight"
|
||||
.Ft void
|
||||
@ -96,6 +116,10 @@
|
||||
.Fn VGLSetPaletteIndex "byte color" "byte red" "byte green" "byte blue"
|
||||
.Ft void
|
||||
.Fn VGLSetBorder "byte color"
|
||||
.Ft int
|
||||
.Fn VGLSetVScreenSize "VGLBitmap *object" "int vxsize" "int vysize"
|
||||
.Ft int
|
||||
.Fn VGLPanSreen "VGLBitmap *object" "int x" "int y"
|
||||
.Ft void
|
||||
.Fn VGLBlankDisplay "int blank"
|
||||
.Sh DESCRIPTION
|
||||
@ -136,6 +160,34 @@ instruct the char/string functions to use the font in file
|
||||
.Em filename
|
||||
instead of the builtin font.
|
||||
.Pp
|
||||
.Fn VGLKeyboardInit
|
||||
set up the keyboard in the ``raw'' I/O mode and
|
||||
specify the key code to be used.
|
||||
.Em code
|
||||
must be
|
||||
.Em VGL_XLATEKEYS ,
|
||||
.Em VGL_CODEKEYS ,
|
||||
or
|
||||
.Em VGL_RAWKEYS .
|
||||
When
|
||||
.Em VGL_XLATEKEYS
|
||||
is specified, the keyboard translate the raw keyboard scan code into
|
||||
a character code.
|
||||
If
|
||||
.Em VGL_RAWKEYS
|
||||
is used, the raw keyboard scan code is read as is.
|
||||
.Em VGL_CODEKEYS
|
||||
is the intermediate key code; each key is assigned a unique code whereas
|
||||
more than one raw scan code may be generated when a key is pressed.
|
||||
.Pp
|
||||
.Fn VGLKeyboardEnd
|
||||
when you have finished using the keyboard, call this function.
|
||||
.Pp
|
||||
.Fn VGLKeyboardGetCh
|
||||
read one byte from the keyboard. As the keyboard I/O is in the ``raw''
|
||||
input mode, the function will not block even if there is no input data,
|
||||
and returns 0.
|
||||
.Pp
|
||||
.Fn VGLMouseInit
|
||||
initialize the mouse. The optional on-screen mouse pointer is shown if the
|
||||
argument is
|
||||
@ -204,6 +256,26 @@ pixels wide, and
|
||||
pixels high in color
|
||||
.Em color .
|
||||
.Pp
|
||||
.Fn VGLBitmapCreate
|
||||
create a bitmap object and initialize it with the specified
|
||||
values and bit data.
|
||||
.Em type
|
||||
must be
|
||||
.Em MEMBUF
|
||||
for the in-memory bitmap.
|
||||
.Em bits
|
||||
may be NULL so that bitmap data may be associated later.
|
||||
.Pp
|
||||
There also is a macro,
|
||||
.Fn VGLBITMAP_INITIALIZER "type" "xsize" "ysize" "bits"
|
||||
to initialize a statically declared bitmap object.
|
||||
.Pp
|
||||
.Fn VGLBitmapDestroy
|
||||
free the bitmap data and the bitmap object.
|
||||
.Pp
|
||||
.Fn VGLBitmapAllocateBits
|
||||
allocate a bit data buffer for the specified object.
|
||||
.Pp
|
||||
.Fn VGLBitmapCopy
|
||||
copy a rectangle of pixels from bitmap
|
||||
.Em src
|
||||
@ -264,6 +336,39 @@ to the specified RGB value.
|
||||
set the border color to color
|
||||
.Em color .
|
||||
.Pp
|
||||
.Fn VGLSetVScreenSize
|
||||
change the virtual screen size of the display. Note that this
|
||||
function must be called when our vty is in the foreground.
|
||||
And
|
||||
.Em object
|
||||
must be
|
||||
.Em VGLDisplay .
|
||||
Passing a in-memory bitmap to this function results in error.
|
||||
.Pp
|
||||
The desired virtual screen width may not be achievable because
|
||||
of the video card hardware. In such case the video driver (and
|
||||
underlaying video BIOS) may choose the next largest values.
|
||||
Always examine
|
||||
.Em object->VXsize
|
||||
and
|
||||
.Em VYsize
|
||||
after calling this function, in order to see how the virtual screen
|
||||
is actually set up.
|
||||
.Pp
|
||||
In order to set up the largest possible virtual screen, you may
|
||||
call this function with arbitrary large values.
|
||||
.Pp
|
||||
.Dl VGLSetVScreenSize(10000, 10000);
|
||||
.Pp
|
||||
.Fn VGLPanSreen
|
||||
change the origin of the displayed screen in the virtual screen.
|
||||
Note that this function must be called when our vty is in the
|
||||
foreground.
|
||||
.Em object
|
||||
must be
|
||||
.Em VGLDisplay .
|
||||
Passing a in-memory bitmap to this function results in error.
|
||||
.Pp
|
||||
.Fn VGLBlankDisplay
|
||||
blank the display if the argment
|
||||
.Em blank
|
||||
|
@ -37,9 +37,14 @@ typedef unsigned char byte;
|
||||
typedef struct {
|
||||
byte Type;
|
||||
int Xsize, Ysize;
|
||||
int VXsize, VYsize;
|
||||
int Xorigin, Yorigin;
|
||||
byte *Bitmap;
|
||||
} VGLBitmap;
|
||||
|
||||
#define VGLBITMAP_INITIALIZER(t, x, y, bits) \
|
||||
{ (t), (x), (y), 0, 0, 0, 0, (bits) }
|
||||
|
||||
/*
|
||||
* Defined Type's
|
||||
*/
|
||||
@ -47,6 +52,8 @@ typedef struct {
|
||||
#define VIDBUF4 1
|
||||
#define VIDBUF8 2
|
||||
#define VIDBUF8X 3
|
||||
#define VIDBUF8S 4
|
||||
#define VIDBUF4S 5
|
||||
#define NOBUF 255
|
||||
|
||||
typedef struct VGLText {
|
||||
@ -78,7 +85,10 @@ typedef struct VGLObject {
|
||||
#define VGL_CODEKEYS 2
|
||||
#define VGL_XLATEKEYS 3
|
||||
|
||||
extern VGLBitmap *VGLDisplay;
|
||||
extern video_adapter_info_t VGLAdpInfo;
|
||||
extern video_info_t VGLModeInfo;
|
||||
extern VGLBitmap *VGLDisplay;
|
||||
extern byte *VGLBuf;
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
@ -86,6 +96,9 @@ extern VGLBitmap *VGLDisplay;
|
||||
/* bitmap.c */
|
||||
int __VGLBitmapCopy(VGLBitmap *src, int srcx, int srcy, VGLBitmap *dst, int dstx, int dsty, int width, int hight);
|
||||
int VGLBitmapCopy(VGLBitmap *src, int srcx, int srcy, VGLBitmap *dst, int dstx, int dsty, int width, int hight);
|
||||
VGLBitmap *VGLBitmapCreate(int type, int xsize, int ysize, byte *bits);
|
||||
void VGLBitmapDestroy(VGLBitmap *object);
|
||||
int VGLBitmapAllocateBits(VGLBitmap *object);
|
||||
/* keyboard.c */
|
||||
int VGLKeyboardInit(int mode);
|
||||
void VGLKeyboardEnd(void);
|
||||
@ -94,6 +107,9 @@ int VGLKeyboardGetCh(void);
|
||||
void VGLEnd(void);
|
||||
int VGLInit(int mode);
|
||||
void VGLCheckSwitch(void);
|
||||
int VGLSetVScreenSize(VGLBitmap *object, int VXsize, int VYsize);
|
||||
int VGLPanScreen(VGLBitmap *object, int x, int y);
|
||||
int VGLSetSegment(unsigned int offset);
|
||||
/* mouse.c */
|
||||
void VGLMousePointerShow(void);
|
||||
void VGLMousePointerHide(void);
|
||||
|
@ -36,7 +36,7 @@ int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int x, y, xsize, ysize, i,j;
|
||||
VGLBitmap tmp;
|
||||
VGLBitmap *tmp;
|
||||
|
||||
// set graphics mode, here 320x240 256 colors
|
||||
// supported modes are (from <machine/console.h>):
|
||||
@ -53,9 +53,10 @@ main(int argc, char **argv)
|
||||
xsize=VGLDisplay->Xsize;
|
||||
ysize=VGLDisplay->Ysize;
|
||||
|
||||
// alloc a new bitmap (there should be a function for this)
|
||||
tmp.Type = MEMBUF; tmp.Bitmap = (char*)malloc(256*256);
|
||||
tmp.Xsize = 256; tmp.Ysize = 256;
|
||||
// alloc a new bitmap
|
||||
tmp = VGLBitmapCreate(MEMBUF, 256, 256, NULL);
|
||||
VGLBitmapAllocateBits(tmp);
|
||||
VGLClear(tmp, 0);
|
||||
|
||||
// fill the screen with colored lines
|
||||
for (y=0; y<ysize; y++)
|
||||
@ -86,15 +87,15 @@ main(int argc, char **argv)
|
||||
// now show some simple bitblit
|
||||
for (i=0; i<256; i++)
|
||||
for (j=0; j<256; j++)
|
||||
tmp.Bitmap[i+256*j] = i%16;
|
||||
VGLBitmapCopy(&tmp, 0, 0, VGLDisplay, 0, 0, 128, 128);
|
||||
tmp->Bitmap[i+256*j] = i%16;
|
||||
VGLBitmapCopy(tmp, 0, 0, VGLDisplay, 0, 0, 128, 128);
|
||||
for (i=0; i<256; i++)
|
||||
for (j=0; j<256; j++)
|
||||
tmp.Bitmap[i+256*j] = j%16;
|
||||
VGLBitmapCopy(&tmp, 0, 0, VGLDisplay, 3, 128, 128, 128);
|
||||
tmp->Bitmap[i+256*j] = j%16;
|
||||
VGLBitmapCopy(tmp, 0, 0, VGLDisplay, 3, 128, 128, 128);
|
||||
sleep(2);
|
||||
VGLBitmapCopy(VGLDisplay, 237, 311, &tmp, 64, 64, 128, 128);
|
||||
VGLBitmapCopy(&tmp, 32, 32, VGLDisplay, 400, 128, 128, 128);
|
||||
VGLBitmapCopy(VGLDisplay, 237, 311, tmp, 64, 64, 128, 128);
|
||||
VGLBitmapCopy(tmp, 32, 32, VGLDisplay, 400, 128, 128, 128);
|
||||
sleep(2);
|
||||
VGLBitmapCopy(VGLDisplay, 300, 300, VGLDisplay, 500, 128, 128, 128);
|
||||
sleep(5);
|
||||
|
Loading…
Reference in New Issue
Block a user