diff --git a/lib/libvgl/bitmap.c b/lib/libvgl/bitmap.c index 9c21914d36ce..17896a595d85 100644 --- a/lib/libvgl/bitmap.c +++ b/lib/libvgl/bitmap.c @@ -274,3 +274,27 @@ VGLBitmapAllocateBits(VGLBitmap *object) return -1; return 0; } + +void +VGLBitmapCvt(VGLBitmap *src, VGLBitmap *dst) +{ + u_long color; + int dstpos, i, pb, size, srcpb, srcpos; + + size = src->VXsize * src->VYsize; + srcpb = src->PixelBytes; + if (srcpb <= 0) + srcpb = 1; + pb = dst->PixelBytes; + if (pb == srcpb) { + bcopy(src->Bitmap, dst->Bitmap, size * pb); + return; + } + if (srcpb != 1) + return; /* not supported */ + for (srcpos = dstpos = 0; srcpos < size; srcpos++) { + color = VGLrgb332ToNative(src->Bitmap[srcpos]); + for (i = 0; i < pb; i++, color >>= 8) + dst->Bitmap[dstpos++] = color; + } +} diff --git a/lib/libvgl/mouse.c b/lib/libvgl/mouse.c index e4dfef04f5cb..ca30102b853a 100644 --- a/lib/libvgl/mouse.c +++ b/lib/libvgl/mouse.c @@ -39,7 +39,11 @@ __FBSDID("$FreeBSD$"); #include #include "vgl.h" -#define X 0xff +#define BORDER 0xff /* default border -- light white in rgb 3:3:2 */ +#define INTERIOR 0xa0 /* default interior -- red in rgb 3:3:2 */ +#define X 0xff /* any nonzero in And mask means part of cursor */ +#define B BORDER +#define I INTERIOR 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, X,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -49,34 +53,36 @@ static byte StdAndMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = { X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0, X,X,X,X,X,X,X,X,0,0,0,0,0,0,0,0, X,X,X,X,X,X,X,X,X,0,0,0,0,0,0,0, + X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0, + X,X,X,X,X,X,X,X,X,X,0,0,0,0,0,0, X,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0, - 0,0,0,X,X,X,X,0,0,0,0,0,0,0,0,0, - 0,0,0,X,X,X,X,X,0,0,0,0,0,0,0,0, - 0,0,0,0,X,X,X,X,0,0,0,0,0,0,0,0, - 0,0,0,0,X,X,X,X,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + X,X,X,0,X,X,X,X,0,0,0,0,0,0,0,0, + X,X,0,0,X,X,X,X,0,0,0,0,0,0,0,0, + 0,0,0,0,0,X,X,X,X,0,0,0,0,0,0,0, + 0,0,0,0,0,X,X,X,X,0,0,0,0,0,0,0, + 0,0,0,0,0,0,X,X,0,0,0,0,0,0,0,0, }; static byte StdOrMask[MOUSE_IMG_SIZE*MOUSE_IMG_SIZE] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,X,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,X,X,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,X,X,X,0,0,0,0,0,0,0,0,0,0,0,0, - 0,X,X,X,X,0,0,0,0,0,0,0,0,0,0,0, - 0,X,X,X,X,X,0,0,0,0,0,0,0,0,0,0, - 0,X,X,X,X,X,X,0,0,0,0,0,0,0,0,0, - 0,X,X,0,X,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,X,X,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,X,X,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + B,B,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + B,I,B,0,0,0,0,0,0,0,0,0,0,0,0,0, + B,I,I,B,0,0,0,0,0,0,0,0,0,0,0,0, + B,I,I,I,B,0,0,0,0,0,0,0,0,0,0,0, + B,I,I,I,I,B,0,0,0,0,0,0,0,0,0,0, + B,I,I,I,I,I,B,0,0,0,0,0,0,0,0,0, + B,I,I,I,I,I,I,B,0,0,0,0,0,0,0,0, + B,I,I,I,I,I,I,I,B,0,0,0,0,0,0,0, + B,I,I,I,I,I,I,I,I,B,0,0,0,0,0,0, + B,I,I,I,I,I,B,B,B,B,0,0,0,0,0,0, + B,I,I,B,I,I,B,0,0,0,0,0,0,0,0,0, + B,I,B,0,B,I,I,B,0,0,0,0,0,0,0,0, + B,B,0,0,B,I,I,B,0,0,0,0,0,0,0,0, + 0,0,0,0,0,B,I,I,B,0,0,0,0,0,0,0, + 0,0,0,0,0,B,I,I,B,0,0,0,0,0,0,0, + 0,0,0,0,0,0,B,B,0,0,0,0,0,0,0,0, }; #undef X +#undef B +#undef I static VGLBitmap VGLMouseStdAndMask = VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, StdAndMask); static VGLBitmap VGLMouseStdOrMask = @@ -103,7 +109,7 @@ VGLMousePointerShow() VGLBitmap buffer = VGLBITMAP_INITIALIZER(MEMBUF, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE, buf); byte crtcidx, crtcval, gdcidx, gdcval; - int i, pos, pos1; + int pos; if (!VGLMouseVisible) { INTOFF(); @@ -118,12 +124,10 @@ VGLMousePointerShow() __VGLBitmapCopy(&VGLVDisplay, VGLMouseXpos, VGLMouseYpos, &buffer, 0, 0, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE); for (pos = 0; pos < MOUSE_IMG_SIZE*MOUSE_IMG_SIZE; pos++) - for (i = 0; i < VGLDisplay->PixelBytes; i++) { - pos1 = pos * VGLDisplay->PixelBytes + i; - buffer.Bitmap[pos1] = (buffer.Bitmap[pos1] & - ~VGLMouseAndMask->Bitmap[pos]) | - VGLMouseOrMask->Bitmap[pos]; - } + if (VGLMouseAndMask->Bitmap[pos]) + bcopy(&VGLMouseOrMask->Bitmap[pos*VGLDisplay->PixelBytes], + &buffer.Bitmap[pos*VGLDisplay->PixelBytes], + VGLDisplay->PixelBytes); __VGLBitmapCopy(&buffer, 0, 0, VGLDisplay, VGLMouseXpos, VGLMouseYpos, MOUSE_IMG_SIZE, MOUSE_IMG_SIZE); if (VGLModeInfo.vi_mem_model != V_INFO_MM_DIRECT) { @@ -216,8 +220,17 @@ VGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask) { if (VGLMouseShown == VGL_MOUSESHOW) VGLMousePointerHide(); + VGLMouseAndMask = AndMask; - VGLMouseOrMask = OrMask; + + if (VGLMouseOrMask != NULL) { + free(VGLMouseOrMask->Bitmap); + free(VGLMouseOrMask); + } + VGLMouseOrMask = VGLBitmapCreate(MEMBUF, OrMask->VXsize, OrMask->VYsize, 0); + VGLBitmapAllocateBits(VGLMouseOrMask); + VGLBitmapCvt(OrMask, VGLMouseOrMask); + if (VGLMouseShown == VGL_MOUSESHOW) VGLMousePointerShow(); } @@ -225,34 +238,42 @@ VGLMouseSetImage(VGLBitmap *AndMask, VGLBitmap *OrMask) void VGLMouseSetStdImage() { - if (VGLMouseShown == VGL_MOUSESHOW) - VGLMousePointerHide(); - VGLMouseAndMask = &VGLMouseStdAndMask; - VGLMouseOrMask = &VGLMouseStdOrMask; - if (VGLMouseShown == VGL_MOUSESHOW) - VGLMousePointerShow(); + VGLMouseSetImage(&VGLMouseStdAndMask, &VGLMouseStdOrMask); } int VGLMouseInit(int mode) { struct mouse_info mouseinfo; - int error, i, mask; + int andmask, border, error, i, interior; switch (VGLModeInfo.vi_mem_model) { case V_INFO_MM_PACKED: case V_INFO_MM_PLANAR: - mask = 0x0f; + andmask = 0x0f; + border = 0x0f; + interior = 0x04; break; case V_INFO_MM_VGAX: - mask = 0x3f; + andmask = 0x3f; + border = 0x3f; + interior = 0x24; break; default: - mask = 0xff; + andmask = 0xff; + border = BORDER; + interior = INTERIOR; break; } - for (i = 0; i < 256; i++) - VGLMouseStdOrMask.Bitmap[i] &= mask; + if (VGLModeInfo.vi_mode == M_BG640x480) + border = 0; /* XXX (palette makes 0x04 look like 0x0f) */ + if (getenv("VGLMOUSEBORDERCOLOR") != NULL) + border = strtoul(getenv("VGLMOUSEBORDERCOLOR"), NULL, 0); + if (getenv("VGLMOUSEINTERIORCOLOR") != NULL) + interior = strtoul(getenv("VGLMOUSEINTERIORCOLOR"), NULL, 0); + for (i = 0; i < MOUSE_IMG_SIZE*MOUSE_IMG_SIZE; i++) + VGLMouseStdOrMask.Bitmap[i] = VGLMouseStdOrMask.Bitmap[i] == BORDER ? + border : VGLMouseStdOrMask.Bitmap[i] == INTERIOR ? interior : 0; VGLMouseSetStdImage(); mouseinfo.operation = MOUSE_MODE; mouseinfo.u.mode.signal = SIGUSR2; diff --git a/lib/libvgl/simple.c b/lib/libvgl/simple.c index d59893e721fd..d5c36a84ed39 100644 --- a/lib/libvgl/simple.c +++ b/lib/libvgl/simple.c @@ -513,6 +513,31 @@ VGLClear(VGLBitmap *object, u_long color) VGLMouseUnFreeze(); } +static inline u_long +VGLrgbToNative(uint16_t r, uint16_t g, uint16_t b) +{ + int nr, ng, nb; + + nr = VGLModeInfo.vi_pixel_fsizes[2]; + ng = VGLModeInfo.vi_pixel_fsizes[1]; + nb = VGLModeInfo.vi_pixel_fsizes[0]; + return (r >> (16 - nr) << (ng + nb)) | (g >> (16 - ng) << nb) | + (b >> (16 - nb) << 0); +} + +u_long +VGLrgb332ToNative(byte c) +{ + uint16_t r, g, b; + + /* 3:3:2 to 16:16:16 */ + r = ((c & 0xe0) >> 5) * 0xffff / 7; + g = ((c & 0x1c) >> 2) * 0xffff / 7; + b = ((c & 0x03) >> 0) * 0xffff / 3; + + return VGLrgbToNative(r, g, b); +} + void VGLRestorePalette() { diff --git a/lib/libvgl/vgl.h b/lib/libvgl/vgl.h index cd7717d8773e..31d2f93f6ccd 100644 --- a/lib/libvgl/vgl.h +++ b/lib/libvgl/vgl.h @@ -112,6 +112,7 @@ int VGLBitmapCopy(VGLBitmap *src, int srcx, int srcy, VGLBitmap *dst, int dstx, VGLBitmap *VGLBitmapCreate(int type, int xsize, int ysize, byte *bits); void VGLBitmapDestroy(VGLBitmap *object); int VGLBitmapAllocateBits(VGLBitmap *object); +void VGLBitmapCvt(VGLBitmap *src, VGLBitmap *dst); /* keyboard.c */ int VGLKeyboardInit(int mode); void VGLKeyboardEnd(void); @@ -144,6 +145,7 @@ void VGLFilledBox(VGLBitmap *object, int x1, int y1, int x2, int y2, u_long colo void VGLEllipse(VGLBitmap *object, int xc, int yc, int a, int b, u_long color); void VGLFilledEllipse(VGLBitmap *object, int xc, int yc, int a, int b, u_long color); void VGLClear(VGLBitmap *object, u_long color); +u_long VGLrgb332ToNative(byte c); void VGLRestoreBlank(void); void VGLRestoreBorder(void); void VGLRestorePalette(void);