- 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:
Kazutaka YOKOTA 1999-11-08 11:37:46 +00:00
parent d7ccb880d1
commit 5acf51ea02
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=53013
9 changed files with 698 additions and 162 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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();

View File

@ -29,6 +29,7 @@
*/
#include <stdio.h>
#include <machine/console.h>
#include "vgl.h"
static VGLText *VGLTextFont = 0;

View File

@ -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

View File

@ -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);

View File

@ -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);