mirror of
https://github.com/reactos/reactos.git
synced 2024-11-20 06:15:26 +00:00
VGA software cursor
svn path=/trunk/; revision=1918
This commit is contained in:
parent
02e9af8bda
commit
a91a0d77da
3 changed files with 165 additions and 42 deletions
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* entry.c
|
||||
*
|
||||
* $Revision: 1.12 $
|
||||
* $Revision: 1.13 $
|
||||
* $Author: jfilby $
|
||||
* $Date: 2001/05/02 12:29:07 $
|
||||
* $Date: 2001/05/26 08:21:02 $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -370,6 +370,7 @@ HSURF VGADDIEnableSurface(IN DHPDEV PDev)
|
|||
pdsurf->Scan0 = ppdev->fbScreen;
|
||||
pdsurf->BitmapStart = ppdev->fbScreen;
|
||||
pdsurf->StartBmp = ppdev->fbScreen;
|
||||
|
||||
/* pdsurf->Conv = &ConvertBuffer[0]; */
|
||||
|
||||
if (!InitPointer(ppdev)) {
|
||||
|
|
|
@ -14,13 +14,15 @@ BOOL InitPointer(PPDEV ppdev)
|
|||
ppdev->PointerAttributes = sizeof(VIDEO_POINTER_ATTRIBUTES) +
|
||||
(CursorWidth * CursorHeight) * 2; // space for two cursors (data and mask); we assume 4bpp.. but use 8bpp for speed
|
||||
|
||||
ppdev->pPointerAttributes = EngAllocMem(0, 512, ALLOC_TAG);
|
||||
|
||||
// Allocate memory for pointer attributes
|
||||
ppdev->pPointerAttributes = EngAllocMem(0, ppdev->PointerAttributes, ALLOC_TAG);
|
||||
|
||||
ppdev->pPointerAttributes->Flags = 0; // FIXME: Do this right
|
||||
ppdev->pPointerAttributes->Width = CursorWidth;
|
||||
ppdev->pPointerAttributes->Height = CursorHeight;
|
||||
ppdev->pPointerAttributes->WidthInBytes = CursorWidth;
|
||||
ppdev->pPointerAttributes->WidthInBytes = CursorWidth / 2;
|
||||
ppdev->pPointerAttributes->Enable = 0;
|
||||
ppdev->pPointerAttributes->Column = 0;
|
||||
ppdev->pPointerAttributes->Row = 0;
|
||||
|
@ -56,19 +58,35 @@ ULONG VGADDISetPointerShape(PSURFOBJ pso, PSURFOBJ psoMask, PSURFOBJ psoColor, P
|
|||
PRECTL prcl, ULONG fl)
|
||||
{
|
||||
PPDEV ppdev = (PPDEV)pso->dhpdev;
|
||||
ULONG cursorBytes = ppdev->pPointerAttributes->WidthInBytes * ppdev->pPointerAttributes->Height;
|
||||
PCHAR DFBTmp;
|
||||
ULONG DFBAllocSize;
|
||||
|
||||
// Hide the cursor (if it's there -- FIXME?)
|
||||
if(ppdev->pPointerAttributes->Enable != 0) vgaHideCursor(ppdev);
|
||||
|
||||
// Copy the mask and color bitmaps into the PPDEV
|
||||
RtlCopyMemory(ppdev->pPointerAttributes->Pixels, psoMask->pvBits, cursorBytes);
|
||||
if(psoColor != NULL) RtlCopyMemory(ppdev->pPointerAttributes->Pixels + cursorBytes, psoColor->pvBits, cursorBytes);
|
||||
RtlCopyMemory(ppdev->pPointerAttributes->Pixels, psoMask->pvBits, psoMask->cjBits);
|
||||
if(psoColor != NULL) RtlCopyMemory(ppdev->pPointerAttributes->Pixels + 256, psoColor->pvBits, psoColor->cjBits);
|
||||
ppdev->pPointerAttributes->WidthInBytes = psoMask->lDelta;
|
||||
|
||||
EngFreeMem(behindCursor);
|
||||
behindCursor = EngAllocMem(0, ppdev->pPointerAttributes->WidthInBytes * ppdev->pPointerAttributes->Height, ALLOC_TAG);
|
||||
|
||||
// Set the new cursor position
|
||||
ppdev->xyCursor.x = x;
|
||||
ppdev->xyCursor.y = y;
|
||||
|
||||
// Convert the cursor DIB into a DFB
|
||||
DFBAllocSize = psoMask->cjBits;
|
||||
DFBTmp = EngAllocMem(0, DFBAllocSize, ALLOC_TAG);
|
||||
DIB_BltToDFB(0, 0,
|
||||
ppdev->pPointerAttributes->Width,
|
||||
ppdev->pPointerAttributes->Height,
|
||||
DFBTmp, ppdev->pPointerAttributes->WidthInBytes,
|
||||
ppdev->pPointerAttributes->Pixels, ppdev->pPointerAttributes->WidthInBytes);
|
||||
RtlCopyMemory(ppdev->pPointerAttributes->Pixels, DFBTmp, psoMask->cjBits);
|
||||
EngFreeMem(DFBTmp);
|
||||
|
||||
// Show the cursor
|
||||
vgaShowCursor(ppdev);
|
||||
}
|
||||
|
@ -77,11 +95,15 @@ void vgaHideCursor(PPDEV ppdev)
|
|||
{
|
||||
ULONG i, j, cx, cy, bitpos;
|
||||
|
||||
// Clip so as not to hide where we are just going to be repainting (if called from vgaShowCursor)
|
||||
|
||||
|
||||
// Display what was behind cursor
|
||||
DFB_BltToVGA(oldx, oldx, oldy,
|
||||
ppdev->pPointerAttributes->Width-1,
|
||||
ppdev->pPointerAttributes->Height-1,
|
||||
behindCursor);
|
||||
DFB_BltToVGA(oldx, oldy,
|
||||
ppdev->pPointerAttributes->Width,
|
||||
ppdev->pPointerAttributes->Height,
|
||||
behindCursor,
|
||||
ppdev->pPointerAttributes->WidthInBytes);
|
||||
|
||||
oldx = ppdev->xyCursor.x;
|
||||
oldy = ppdev->xyCursor.y;
|
||||
|
@ -91,31 +113,25 @@ void vgaHideCursor(PPDEV ppdev)
|
|||
|
||||
void vgaShowCursor(PPDEV ppdev)
|
||||
{
|
||||
ULONG i, j, cx, cy, bitpos;
|
||||
ULONG i, j, cx, cy;
|
||||
|
||||
if(ppdev->pPointerAttributes->Enable != 0) vgaHideCursor(ppdev);
|
||||
|
||||
// Capture pixels behind the cursor
|
||||
cx = ppdev->xyCursor.x;
|
||||
cy = ppdev->xyCursor.y;
|
||||
bitpos = 0;
|
||||
for (j=0; j<ppdev->pPointerAttributes->Height; j++)
|
||||
{
|
||||
cx = ppdev->xyCursor.x;
|
||||
for (i=0; i<ppdev->pPointerAttributes->Width; i++)
|
||||
{
|
||||
behindCursor[bitpos] = vgaGetPixel(cx, cy);
|
||||
bitpos++;
|
||||
cx++;
|
||||
}
|
||||
cy++;
|
||||
}
|
||||
|
||||
// repaint background
|
||||
DFB_BltFromVGA(ppdev->xyCursor.x, ppdev->xyCursor.y,
|
||||
ppdev->pPointerAttributes->Width, ppdev->pPointerAttributes->Height,
|
||||
behindCursor, ppdev->pPointerAttributes->WidthInBytes);
|
||||
|
||||
// Display the cursor
|
||||
DIB_BltToVGA(ppdev->xyCursor.x, ppdev->xyCursor.x, ppdev->xyCursor.y,
|
||||
ppdev->pPointerAttributes->Width-1,
|
||||
ppdev->pPointerAttributes->Height-1,
|
||||
ppdev->pPointerAttributes->Pixels);
|
||||
DFB_BltToVGA_Transparent(ppdev->xyCursor.x, ppdev->xyCursor.y,
|
||||
ppdev->pPointerAttributes->Width,
|
||||
ppdev->pPointerAttributes->Height,
|
||||
ppdev->pPointerAttributes->Pixels,
|
||||
ppdev->pPointerAttributes->WidthInBytes);
|
||||
|
||||
ppdev->pPointerAttributes->Enable = 1;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,3 @@
|
|||
//
|
||||
// The current VGA bitblt routines work just fine. However, they put the 4bpp data into 1 byte each.
|
||||
// To solve the problem, whenever assigning to or retrieving data from the buffer, it must pass through
|
||||
// a macro which packs it appropriately.
|
||||
//
|
||||
// Possible future enhancements:
|
||||
// * Use putByte function for middlepix when bitbltting to the VGA
|
||||
//
|
||||
|
||||
// PROCESS 1: Use 4bpp bitblt instead of 8bpp-bitmap/4bpp-display
|
||||
//
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <ddk/ntddvid.h>
|
||||
#include <ddk/winddi.h>
|
||||
|
@ -451,8 +439,8 @@ void DIB_BltToVGA(int x, int y, int w, int h, void *b, int Source_lDelta)
|
|||
pb++;
|
||||
}
|
||||
|
||||
opb += Source_lDelta; // new test code
|
||||
pb = opb; // new test code
|
||||
opb += Source_lDelta;
|
||||
pb = opb;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -494,7 +482,7 @@ void DIB_TransparentBltToVGA(int x, int y, int w, int h, void *b, int Source_lDe
|
|||
pb++;
|
||||
}
|
||||
|
||||
opb += Source_lDelta; // new test code
|
||||
opb += Source_lDelta;
|
||||
pb = opb; // new test code
|
||||
|
||||
}
|
||||
|
@ -636,3 +624,121 @@ void DFB_BltToVGA(int x, int y, int w, int h, void *b, int bw)
|
|||
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);
|
||||
WRITE_PORT_UCHAR((PUCHAR)GRA_D, saved_GC_mode);
|
||||
}
|
||||
|
||||
void DFB_BltToVGA_Transparent(int x, int y, int w, int h, void *b, int bw)
|
||||
|
||||
// This algorithm goes from goes from left to right, and inside that loop, top to bottom.
|
||||
// It also stores each 4BPP pixel in an entire byte.
|
||||
{
|
||||
unsigned char *bp, *bpX;
|
||||
unsigned char *vp, *vpX;
|
||||
unsigned char mask;
|
||||
volatile unsigned char dummy;
|
||||
int byte_per_line;
|
||||
int i, j;
|
||||
|
||||
bpX = b;
|
||||
ASSIGNVP4(x, y, vpX)
|
||||
ASSIGNMK4(x, y, mask)
|
||||
byte_per_line = SCREEN_X >> 3;
|
||||
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05); // write mode 2
|
||||
saved_GC_mode = READ_PORT_UCHAR((PUCHAR)GRA_D);
|
||||
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
|
||||
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03); // replace
|
||||
saved_GC_fun = READ_PORT_UCHAR((PUCHAR)GRA_D);
|
||||
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
|
||||
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08); // bit mask
|
||||
saved_GC_mask = READ_PORT_UCHAR((PUCHAR)GRA_D);
|
||||
|
||||
for (i=w; i>0; i--) {
|
||||
WRITE_PORT_UCHAR((PUCHAR)GRA_D, mask);
|
||||
bp = bpX;
|
||||
vp = vpX;
|
||||
for (j=h; j>0; j--) {
|
||||
if (*bp != 0)
|
||||
{
|
||||
dummy = *vp;
|
||||
*vp = *bp;
|
||||
}
|
||||
bp += bw;
|
||||
vp += byte_per_line;
|
||||
}
|
||||
bpX++;
|
||||
if ((mask >>= 1) == 0) {
|
||||
vpX++;
|
||||
mask = 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
// reset GC register
|
||||
WRITE_PORT_UCHAR((PUCHAR)GRA_D, saved_GC_mask);
|
||||
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03);
|
||||
WRITE_PORT_UCHAR((PUCHAR)GRA_D, saved_GC_fun);
|
||||
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05);
|
||||
WRITE_PORT_UCHAR((PUCHAR)GRA_D, saved_GC_mode);
|
||||
}
|
||||
|
||||
void DFB_BltToDIB(int x, int y, int w, int h, void *b, int bw, void *bdib, int dibw)
|
||||
|
||||
// This algorithm converts a DFB into a DIB
|
||||
// WARNING: This algorithm is buggy
|
||||
{
|
||||
unsigned char *bp, *bpX, *dib, *dibTmp;
|
||||
int i, j, dib_shift;
|
||||
|
||||
bpX = b;
|
||||
dib = bdib + y * dibw + (x / 2);
|
||||
|
||||
for (i=w; i>0; i--) {
|
||||
|
||||
// determine the bit shift for the DIB pixel
|
||||
dib_shift = mod(w-i, 2);
|
||||
if(dib_shift > 0) dib_shift = 4;
|
||||
dibTmp = dib;
|
||||
|
||||
bp = bpX;
|
||||
for (j=h; j>0; j--) {
|
||||
*dibTmp = *bp << dib_shift | *(bp + 1);
|
||||
dibTmp += dibw;
|
||||
bp += bw;
|
||||
}
|
||||
bpX++;
|
||||
if(dib_shift == 0) dib++;
|
||||
}
|
||||
}
|
||||
|
||||
void DIB_BltToDFB(int x, int y, int w, int h, void *b, int bw, void *bdib, int dibw)
|
||||
|
||||
// This algorithm converts a DIB into a DFB
|
||||
{
|
||||
unsigned char *bp, *bpX, *dib, *dibTmp;
|
||||
int i, j, dib_shift, dib_and;
|
||||
|
||||
bpX = b;
|
||||
dib = bdib + y * dibw + (x / 2);
|
||||
|
||||
for (i=w; i>0; i--) {
|
||||
|
||||
// determine the bit shift for the DIB pixel
|
||||
dib_shift = mod(w-i, 2);
|
||||
if(dib_shift > 0) {
|
||||
dib_shift = 0;
|
||||
dib_and = 0x0f;
|
||||
} else {
|
||||
dib_shift = 4;
|
||||
dib_and = 0xf0;
|
||||
}
|
||||
|
||||
dibTmp = dib;
|
||||
bp = bpX;
|
||||
|
||||
for (j=h; j>0; j--) {
|
||||
*bp = (*dibTmp & dib_and) >> dib_shift;
|
||||
dibTmp += dibw;
|
||||
bp += bw;
|
||||
}
|
||||
|
||||
bpX++;
|
||||
if(dib_shift == 0) dib++;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue