aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKazutaka YOKOTA <yokota@FreeBSD.org>1999-11-08 11:37:46 +0000
committerKazutaka YOKOTA <yokota@FreeBSD.org>1999-11-08 11:37:46 +0000
commit5acf51ea02ea31f47358e87bacdaaaa6c9ed7dc4 (patch)
tree2fd4989fd857b909af28670ef7714168fdbf0cea
parentd7ccb880d1a6f6c4e6531dd51f2942a08abf4bb1 (diff)
downloadsrc-5acf51ea02ea31f47358e87bacdaaaa6c9ed7dc4.tar.gz
src-5acf51ea02ea31f47358e87bacdaaaa6c9ed7dc4.zip
- 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.)
Notes
Notes: svn path=/head/; revision=53013
-rw-r--r--lib/libvgl/Makefile2
-rw-r--r--lib/libvgl/bitmap.c207
-rw-r--r--lib/libvgl/main.c371
-rw-r--r--lib/libvgl/mouse.c13
-rw-r--r--lib/libvgl/simple.c112
-rw-r--r--lib/libvgl/text.c1
-rw-r--r--lib/libvgl/vgl.3107
-rw-r--r--lib/libvgl/vgl.h18
-rw-r--r--share/examples/libvgl/demo.c21
9 files changed, 694 insertions, 158 deletions
diff --git a/lib/libvgl/Makefile b/lib/libvgl/Makefile
index fe71c3510171..11b0b7533469 100644
--- a/lib/libvgl/Makefile
+++ b/lib/libvgl/Makefile
@@ -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
diff --git a/lib/libvgl/bitmap.c b/lib/libvgl/bitmap.c
index e66150ca2348..2714e890a506 100644
--- a/lib/libvgl/bitmap.c
+++ b/lib/libvgl/bitmap.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 VIDBUF4S:
+ 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);
+ 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 + (src->Xsize/8 * y) + x/8;
+ address = src->Bitmap + VGLAdpInfo.va_line_width * y + x/8;
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);
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];
+ 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, buffer);
- WriteVerticalLine(dst, dstx, dstline, width, buffer);
+ 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;
+}
diff --git a/lib/libvgl/main.c b/lib/libvgl/main.c
index fc13f46b0c43..8211842ddc98 100644
--- a/lib/libvgl/main.c
+++ b/lib/libvgl/main.c
@@ -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);
-
- VGLMem = (byte*)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_FILE,
- open("/dev/mem", O_RDWR), 0xA0000);
- if (VGLMem <= (byte*)0)
- return 1;
+ 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;
- VGLBuf = (byte*)malloc(256*1024);
- if (VGLBuf == NULL)
- return 1;
+ VGLDisplay = (VGLBitmap *)malloc(sizeof(VGLBitmap));
+ if (VGLDisplay == NULL)
+ return -2;
- 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);
- }
- 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;
+ 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 SW_VGA_MODEX:
- VGLDisplay->Type = VIDBUF8X;
+ 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:
- VGLDisplay->Type = VIDBUF8; /* XXX */
+ /* 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);
}
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;
+}
diff --git a/lib/libvgl/mouse.c b/lib/libvgl/mouse.c
index a5ded2f2a424..390ec6cd86d2 100644
--- a/lib/libvgl/mouse.c
+++ b/lib/libvgl/mouse.c
@@ -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;
diff --git a/lib/libvgl/simple.c b/lib/libvgl/simple.c
index 2ca923ca7ff7..0dfc23704210 100644
--- a/lib/libvgl/simple.c
+++ b/lib/libvgl/simple.c
@@ -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();
diff --git a/lib/libvgl/text.c b/lib/libvgl/text.c
index a2c6417301e5..09b09644a3e9 100644
--- a/lib/libvgl/text.c
+++ b/lib/libvgl/text.c
@@ -29,6 +29,7 @@
*/
#include <stdio.h>
+#include <machine/console.h>
#include "vgl.h"
static VGLText *VGLTextFont = 0;
diff --git a/lib/libvgl/vgl.3 b/lib/libvgl/vgl.3
index 5a25a02e806c..c63503ffd6f6 100644
--- a/lib/libvgl/vgl.3
+++ b/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
diff --git a/lib/libvgl/vgl.h b/lib/libvgl/vgl.h
index 8704ac97ecdf..4aa34c6ca066 100644
--- a/lib/libvgl/vgl.h
+++ b/lib/libvgl/vgl.h
@@ -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);
diff --git a/share/examples/libvgl/demo.c b/share/examples/libvgl/demo.c
index 3147c47687c7..f2a28d31a2ba 100644
--- a/share/examples/libvgl/demo.c
+++ b/share/examples/libvgl/demo.c
@@ -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);