From 51ee9ffb3d76f1a71f734011ea4181713998ee89 Mon Sep 17 00:00:00 2001 From: David Welch Date: Wed, 25 Sep 2002 21:21:36 +0000 Subject: [PATCH] Added nicer looking default mouse cursor. Draw a mouse cursor as a pair of AND and XOR masks. Speedup saving the screen area behind the mouse cursor by blitting it to a non-displayed part of the frame buffer. svn path=/trunk/; revision=3569 --- reactos/drivers/dd/vga/display/main/enable.c | 10 +- reactos/drivers/dd/vga/display/makefile | 5 +- .../dd/vga/display/objects/offscreen.c | 191 ++++++++++ .../drivers/dd/vga/display/objects/pointer.c | 350 ++++++++++++++---- reactos/drivers/dd/vga/display/vgaddi.h | 31 +- .../dd/vga/display/vgavideo/vgavideo.c | 31 ++ .../dd/vga/display/vgavideo/vgavideo.h | 21 +- reactos/lib/user32/windows/defwnd.c | 10 +- reactos/subsys/win32k/eng/mouse.c | 108 ++++-- 9 files changed, 629 insertions(+), 128 deletions(-) create mode 100644 reactos/drivers/dd/vga/display/objects/offscreen.c diff --git a/reactos/drivers/dd/vga/display/main/enable.c b/reactos/drivers/dd/vga/display/main/enable.c index 972ae98e66e..f0719c49f66 100644 --- a/reactos/drivers/dd/vga/display/main/enable.c +++ b/reactos/drivers/dd/vga/display/main/enable.c @@ -1,9 +1,9 @@ /* * entry.c * - * $Revision: 1.22 $ - * $Author: chorns $ - * $Date: 2002/09/08 10:22:07 $ + * $Revision: 1.23 $ + * $Author: dwelch $ + * $Date: 2002/09/25 21:21:35 $ * */ @@ -72,6 +72,8 @@ DrvEnableDriver(IN ULONG EngineVersion, // FIXME: Use Vidport to map the memory properly vidmem = (char *)(0xd0000000 + 0xa0000); + VGADDI_InitializeOffScreenMem((640 * 480) >> 3, 65536 - ((640 * 480) >> 3)); + DriveEnableData->pdrvfn = FuncList; DriveEnableData->c = sizeof(FuncList) / sizeof(DRVFN); DriveEnableData->iDriverVersion = DDI_DRIVER_VERSION; @@ -257,6 +259,7 @@ DrvDisableSurface(IN DHPDEV PDev) } CHECKPOINT; // free any pending saved screen bit blocks +#if 0 pSSB = pdsurf->ssbList; while (pSSB != (PSAVED_SCREEN_BITS) NULL) { @@ -267,6 +270,7 @@ DrvDisableSurface(IN DHPDEV PDev) EngFreeMem(pSSB); pSSB = pSSBNext; } +#endif EngDeleteSurface((HSURF) ppdev->SurfHandle); // EngFreeMem(pdsurf); // free the surface } diff --git a/reactos/drivers/dd/vga/display/makefile b/reactos/drivers/dd/vga/display/makefile index 7240f796b8e..529530c06e5 100644 --- a/reactos/drivers/dd/vga/display/makefile +++ b/reactos/drivers/dd/vga/display/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.18 2001/08/21 20:13:12 chorns Exp $ +# $Id: makefile,v 1.19 2002/09/25 21:21:35 dwelch Exp $ PATH_TO_TOP = ../../../.. @@ -17,7 +17,8 @@ OTHER_OBJECTS = \ objects/lineto.o \ objects/paint.o \ objects/bitblt.o \ - objects/transblt.o + objects/transblt.o \ + objects/offscreen.o VGAVIDEO_OBJECTS = \ vgavideo/vgavideo.o diff --git a/reactos/drivers/dd/vga/display/objects/offscreen.c b/reactos/drivers/dd/vga/display/objects/offscreen.c new file mode 100644 index 00000000000..27c5302c0de --- /dev/null +++ b/reactos/drivers/dd/vga/display/objects/offscreen.c @@ -0,0 +1,191 @@ +/* + * ReactOS kernel + * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id: offscreen.c,v 1.1 2002/09/25 21:21:35 dwelch Exp $ + * + * PROJECT: ReactOS VGA16 display driver + * FILE: drivers/dd/vga/display/objects/offscreen.c + * PURPOSE: Manages off-screen video memory. + */ + +/* INCLUDES ******************************************************************/ + +#include "../vgaddi.h" +#include "../vgavideo/vgavideo.h" +#include + +/* GLOBALS *******************************************************************/ + +static LIST_ENTRY SavedBitsList; + +/* FUNCTIONS *****************************************************************/ + +VOID +VGADDI_BltFromSavedScreenBits(ULONG DestX, + ULONG DestY, + PSAVED_SCREEN_BITS Src, + ULONG SizeX, + ULONG SizeY) +{ + PUCHAR DestOffset; + PUCHAR SrcOffset; + ULONG i, j; + + /* Select write mode 1. */ + WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5); + WRITE_PORT_UCHAR((PUCHAR)GRA_D, 1); + + SrcOffset = (PUCHAR)vidmem + Src->Offset; + for (i = 0; i < SizeY; i++) + { + DestOffset = (PUCHAR)vidmem + (i + DestY) * 80 + (DestX >> 3); + for (j = 0; j < SizeX; j++, SrcOffset++, DestOffset++) + { + (VOID)READ_REGISTER_UCHAR(SrcOffset); + WRITE_REGISTER_UCHAR(DestOffset, 0); + } + } + + /* Select write mode 2. */ + WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5); + WRITE_PORT_UCHAR((PUCHAR)GRA_D, 2); +} + +VOID +VGADDI_BltToSavedScreenBits(PSAVED_SCREEN_BITS Dest, + ULONG SourceX, + ULONG SourceY, + ULONG SizeX, + ULONG SizeY) +{ + PUCHAR DestOffset; + PUCHAR SrcOffset; + ULONG i, j; + + /* Select write mode 1. */ + WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5); + WRITE_PORT_UCHAR((PUCHAR)GRA_D, 1); + + DestOffset = (PUCHAR)vidmem + Dest->Offset; + + for (i = 0; i < SizeY; i++) + { + SrcOffset = (PUCHAR)vidmem + (SourceY + i) * 80 + (SourceX >> 3); + for (j = 0; j < SizeX; j++, SrcOffset++, DestOffset++) + { + (VOID)READ_REGISTER_UCHAR(SrcOffset); + WRITE_REGISTER_UCHAR(DestOffset, 0); + } + } + + /* Select write mode 2. */ + WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5); + WRITE_PORT_UCHAR((PUCHAR)GRA_D, 2); +} + +VOID +VGADDI_FreeSavedScreenBits(PSAVED_SCREEN_BITS SavedBits) +{ + SavedBits->Free = TRUE; + + if (SavedBits->ListEntry.Blink != &SavedBitsList) + { + PSAVED_SCREEN_BITS Previous; + + Previous = CONTAINING_RECORD(SavedBits->ListEntry.Blink, + SAVED_SCREEN_BITS, ListEntry); + if (Previous->Free) + { + Previous->Size += SavedBits->Size; + RemoveEntryList(&SavedBits->ListEntry); + EngFreeMem(SavedBits); + SavedBits = Previous; + } + } + if (SavedBits->ListEntry.Flink != &SavedBitsList) + { + PSAVED_SCREEN_BITS Next; + + Next = CONTAINING_RECORD(SavedBits->ListEntry.Flink, SAVED_SCREEN_BITS, + ListEntry); + if (Next->Free) + { + SavedBits->Size += Next->Size; + RemoveEntryList(&SavedBits->ListEntry); + EngFreeMem(SavedBits); + } + } +} + +PSAVED_SCREEN_BITS +VGADDI_AllocSavedScreenBits(ULONG Size) +{ + PSAVED_SCREEN_BITS Current; + PLIST_ENTRY CurrentEntry; + PSAVED_SCREEN_BITS Best; + PSAVED_SCREEN_BITS New; + + Best = NULL; + CurrentEntry = SavedBitsList.Flink; + while (CurrentEntry != &SavedBitsList) + { + Current = CONTAINING_RECORD(CurrentEntry, SAVED_SCREEN_BITS, ListEntry); + + if (Current->Free && Current->Size >= Size && + (Best == NULL || (Current->Size - Size) < (Best->Size - Size))) + { + Best = Current; + } + + CurrentEntry = CurrentEntry->Flink; + } + + if (Best == NULL) + { + return(NULL); + } + if (Best->Size == Size) + { + Best->Free = FALSE; + return(Best); + } + else + { + New = EngAllocMem(0, sizeof(SAVED_SCREEN_BITS), ALLOC_TAG); + New->Free = FALSE; + New->Offset = Best->Offset + Size; + New->Size = Size; + Best->Size -= Size; + InsertHeadList(&Best->ListEntry, &New->ListEntry); + return(New); + } +} + +VOID +VGADDI_InitializeOffScreenMem(ULONG Start, ULONG Length) +{ + PSAVED_SCREEN_BITS FreeBits; + + InitializeListHead(&SavedBitsList); + + FreeBits = EngAllocMem(0, sizeof(SAVED_SCREEN_BITS), ALLOC_TAG); + FreeBits->Free = TRUE; + FreeBits->Offset = Start; + FreeBits->Size = Length; + InsertHeadList(&SavedBitsList, &FreeBits->ListEntry); +} diff --git a/reactos/drivers/dd/vga/display/objects/pointer.c b/reactos/drivers/dd/vga/display/objects/pointer.c index 3d6897aeed9..fc7e0825296 100644 --- a/reactos/drivers/dd/vga/display/objects/pointer.c +++ b/reactos/drivers/dd/vga/display/objects/pointer.c @@ -1,35 +1,180 @@ +/* + * ReactOS kernel + * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id: pointer.c,v 1.11 2002/09/25 21:21:35 dwelch Exp $ + * + * PROJECT: ReactOS VGA16 display driver + * FILE: drivers/dd/vga/display/objects/pointer.c + * PURPOSE: Draws the mouse pointer. + */ + +/* INCLUDES ******************************************************************/ + #include "../vgaddi.h" +#include "../vgavideo/vgavideo.h" -ULONG oldx, oldy; -static PUCHAR ImageBehindCursor; +/* GLOBALS *******************************************************************/ -void vgaHideCursor(PPDEV ppdev); -void vgaShowCursor(PPDEV ppdev); +static ULONG oldx, oldy; +static PSAVED_SCREEN_BITS ImageBehindCursor = NULL; +VOID VGADDI_HideCursor(PPDEV ppdev); +VOID VGADDI_ShowCursor(PPDEV ppdev); + +/* FUNCTIONS *****************************************************************/ + +VOID +VGADDI_BltPointerToVGA(ULONG StartX, ULONG StartY, ULONG SizeX, + ULONG SizeY, PUCHAR MaskBits, ULONG MaskOp) +{ + ULONG EndX, EndY; + UCHAR Mask; + PUCHAR Video; + PUCHAR Src; + ULONG MaskPitch; + UCHAR SrcValue; + ULONG i, j; + ULONG Left; + ULONG Length; + + EndX = StartX + SizeX; + EndY = StartY + SizeY; + MaskPitch = SizeX >> 3; + + /* Set write mode zero. */ + WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5); + WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0); + + /* Select raster op. */ + WRITE_PORT_UCHAR((PUCHAR)GRA_I, 3); + WRITE_PORT_UCHAR((PUCHAR)GRA_D, MaskOp); + + if ((StartX % 8) != 0) + { + /* Disable writes to pixels outside of the destination rectangle. */ + Mask = (1 << (8 - (StartX % 8))) - 1; + if ((EndX - StartX) < (8 - (StartX % 8))) + { + Mask &= ~((1 << (8 - (EndX % 8))) - 1); + } + WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x8); + WRITE_PORT_UCHAR((PUCHAR)GRA_D, Mask); + + /* Write the mask. */ + Video = (PUCHAR)vidmem + StartY * 80 + (StartX >> 3); + Src = MaskBits; + for (i = 0; i < SizeY; i++, Video+=80, Src+=MaskPitch) + { + SrcValue = (*Src) << (StartX % 8); + (VOID)READ_REGISTER_UCHAR(Video); + WRITE_REGISTER_UCHAR(Video, PreCalcReverseByte[SrcValue]); + } + } + + /* Enable writes to all pixels. */ + WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x8); + WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0xFF); + + /* Have we finished. */ + if ((EndX - StartX) < (8 - (StartX % 8))) + { + return; + } + + /* Fill any whole rows of eight pixels. */ + Left = (StartX + 7) & ~0x7; + Length = (EndX >> 3) - (Left >> 3); + for (i = StartY; i < EndY; i++) + { + Video = (PUCHAR)vidmem + i * 80 + (Left >> 3); + Src = MaskBits + (i - StartY) * MaskPitch; + for (j = 0; j < Length; j++, Video++, Src++) + { + if ((StartX % 8) != 0) + { + SrcValue = (Src[0] >> (8 - (StartX % 8))); + SrcValue |= (Src[1] << (StartX % 8)); + } + else + { + SrcValue = Src[0]; + } + (VOID)READ_REGISTER_UCHAR(Video); + WRITE_REGISTER_UCHAR(Video, PreCalcReverseByte[SrcValue]); + } + } + + /* Fill any pixels on the right which don't fall into a complete row. */ + if ((EndX % 8) != 0) + { + /* Disable writes to pixels outside the destination rectangle. */ + Mask = ~((1 << (8 - (EndX % 8))) - 1); + WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x8); + WRITE_PORT_UCHAR((PUCHAR)GRA_D, Mask); + + Video = (PUCHAR)vidmem + StartY * 80 + (EndX >> 3); + Src = MaskBits + (SizeX >> 3) - 1; + for (i = StartY; i < EndY; i++, Video+=80, Src+=MaskPitch) + { + SrcValue = (Src[0] >> (8 - (StartX % 8))); + (VOID)READ_REGISTER_UCHAR(Video); + WRITE_REGISTER_UCHAR(Video, PreCalcReverseByte[SrcValue]); + } + + /* Restore the default write masks. */ + WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x8); + WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0xFF); + } + + /* Set write mode two. */ + WRITE_PORT_UCHAR((PUCHAR)GRA_I, 5); + WRITE_PORT_UCHAR((PUCHAR)GRA_D, 2); + + /* Select raster op replace. */ + WRITE_PORT_UCHAR((PUCHAR)GRA_I, 3); + WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0); +} BOOL InitPointer(PPDEV ppdev) { - ULONG CursorWidth = 16, CursorHeight = 16; + ULONG CursorWidth = 32, CursorHeight = 32; + ULONG PointerAttributesSize; + ULONG SavedMemSize; - // Determine the size of the pointer attributes - ppdev->PointerAttributes = sizeof(VIDEO_POINTER_ATTRIBUTES) + - (CursorWidth * CursorHeight) * 2; // space for two cursors (data and mask); we assume 4bpp.. but use 8bpp for speed + /* Determine the size of the pointer attributes */ + PointerAttributesSize = sizeof(VIDEO_POINTER_ATTRIBUTES) + + ((CursorWidth * CursorHeight * 2) >> 3); - // Allocate memory for pointer attributes - ppdev->pPointerAttributes = EngAllocMem(0, ppdev->PointerAttributes, ALLOC_TAG); + /* Allocate memory for pointer attributes */ + ppdev->pPointerAttributes = EngAllocMem(0, PointerAttributesSize, ALLOC_TAG); - ppdev->pPointerAttributes->Flags = 0; // FIXME: Do this right + ppdev->pPointerAttributes->Flags = 0; /* FIXME: Do this right */ ppdev->pPointerAttributes->Width = CursorWidth; ppdev->pPointerAttributes->Height = CursorHeight; - ppdev->pPointerAttributes->WidthInBytes = CursorWidth / 2; + ppdev->pPointerAttributes->WidthInBytes = CursorWidth >> 3; ppdev->pPointerAttributes->Enable = 0; ppdev->pPointerAttributes->Column = 0; ppdev->pPointerAttributes->Row = 0; - // Allocate memory for the pixels behind the cursor - ImageBehindCursor = - EngAllocMem(0, ppdev->pPointerAttributes->WidthInBytes * ppdev->pPointerAttributes->Height, ALLOC_TAG); + /* Allocate memory for the pixels behind the cursor */ + SavedMemSize = ((((CursorWidth + 7) & ~0x7) + 16) * CursorHeight) >> 3; + ImageBehindCursor = VGADDI_AllocSavedScreenBits(SavedMemSize); - return TRUE; + return(TRUE); } @@ -40,21 +185,21 @@ DrvMovePointer(IN PSURFOBJ pso, IN PRECTL prcl) { PPDEV ppdev = (PPDEV)pso->dhpdev; - - if(x == -1) - { - // x == -1 and y == -1 indicates we must hide the cursor - vgaHideCursor(ppdev); - return; - } - + + if (x == -1) + { + /* x == -1 and y == -1 indicates we must hide the cursor */ + VGADDI_HideCursor(ppdev); + return; + } + ppdev->xyCursor.x = x; ppdev->xyCursor.y = y; - vgaShowCursor(ppdev); - - // Give feedback on the new cursor rectangle -// if (prcl != NULL) ComputePointerRect(ppdev, prcl); + VGADDI_ShowCursor(ppdev); + + /* Give feedback on the new cursor rectangle */ + /*if (prcl != NULL) ComputePointerRect(ppdev, prcl);*/ } @@ -71,77 +216,138 @@ DrvSetPointerShape(PSURFOBJ pso, ULONG fl) { PPDEV ppdev = (PPDEV)pso->dhpdev; - PCHAR DFBTmp; - ULONG DFBAllocSize; + ULONG NewWidth, NewHeight; + PUCHAR Src, Dest; + ULONG i, j; - // Hide the cursor - if(ppdev->pPointerAttributes->Enable != 0) vgaHideCursor(ppdev); + NewWidth = psoMask->lDelta << 3; + NewHeight = (psoMask->cjBits / psoMask->lDelta) / 2; - // Copy the mask and color bitmaps into the PPDEV - 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; + /* Hide the cursor */ + if(ppdev->pPointerAttributes->Enable != 0) + { + VGADDI_HideCursor(ppdev); + } - EngFreeMem(ImageBehindCursor); - ImageBehindCursor = EngAllocMem(0, ppdev->pPointerAttributes->WidthInBytes * ppdev->pPointerAttributes->Height, ALLOC_TAG); + /* Reallocate the space for the cursor if necessary. */ + if (ppdev->pPointerAttributes->Width != NewWidth || + ppdev->pPointerAttributes->Height != NewHeight) + { + ULONG PointerAttributesSize; + PVIDEO_POINTER_ATTRIBUTES NewPointerAttributes; + ULONG SavedMemSize; - // Set the new cursor position + /* Determine the size of the pointer attributes */ + PointerAttributesSize = sizeof(VIDEO_POINTER_ATTRIBUTES) + + ((NewWidth * NewHeight * 2) >> 3); + + /* Allocate memory for pointer attributes */ + NewPointerAttributes = EngAllocMem(0, PointerAttributesSize, ALLOC_TAG); + *NewPointerAttributes = *ppdev->pPointerAttributes; + NewPointerAttributes->Width = NewWidth; + NewPointerAttributes->Height = NewHeight; + NewPointerAttributes->WidthInBytes = NewWidth >> 3; + EngFreeMem(ppdev->pPointerAttributes); + ppdev->pPointerAttributes = NewPointerAttributes; + + /* Reallocate the space for the saved bits. */ + VGADDI_FreeSavedScreenBits(ImageBehindCursor); + SavedMemSize = ((((NewWidth + 7) & ~0x7) + 16) * NewHeight) >> 3; + ImageBehindCursor = VGADDI_AllocSavedScreenBits(SavedMemSize); + } + + /* Copy the new cursor in. */ + for (i = 0; i < (NewHeight * 2); i++) + { + Src = (PUCHAR)psoMask->pvBits; + Src += (i * (NewWidth >> 3)); + Dest = (PUCHAR)ppdev->pPointerAttributes->Pixels; + if (i >= NewHeight) + { + Dest += (((NewHeight * 3) - i - 1) * (NewWidth >> 3)); + } + else + { + Dest += ((NewHeight - i - 1) * (NewWidth >> 3)); + } + for (j = 0; j < (NewWidth >> 3); j++) + { + Dest[j] = PreCalcReverseByte[Src[j]]; + } + } + + /* 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); + /* Show the cursor */ + VGADDI_ShowCursor(ppdev); } -void vgaHideCursor(PPDEV ppdev) +VOID +VGADDI_HideCursor(PPDEV ppdev) { ULONG i, j, cx, cy, bitpos; + ULONG SizeX; - // Display what was behind cursor - DFB_BltToVGA(oldx, oldy, - ppdev->pPointerAttributes->Width, - ppdev->pPointerAttributes->Height, - ImageBehindCursor, - ppdev->pPointerAttributes->WidthInBytes); + /* Display what was behind cursor */ + SizeX = ((oldx + ppdev->pPointerAttributes->Width) + 7) & ~0x7; + SizeX -= (oldx & ~0x7); + VGADDI_BltFromSavedScreenBits(oldx & ~0x7, + oldy, + ImageBehindCursor, + SizeX, + ppdev->pPointerAttributes->Height); ppdev->pPointerAttributes->Enable = 0; } -void vgaShowCursor(PPDEV ppdev) +VOID +VGADDI_ShowCursor(PPDEV ppdev) { ULONG i, j, cx, cy; + PUCHAR AndMask; + ULONG SizeX; - if(ppdev->pPointerAttributes->Enable != 0) vgaHideCursor(ppdev); + if (ppdev->pPointerAttributes->Enable != 0) + { + VGADDI_HideCursor(ppdev); + } - // Capture pixels behind the cursor + /* Capture pixels behind the cursor */ cx = ppdev->xyCursor.x; cy = ppdev->xyCursor.y; - // Used to repaint background - DFB_BltFromVGA(ppdev->xyCursor.x, ppdev->xyCursor.y, - ppdev->pPointerAttributes->Width, ppdev->pPointerAttributes->Height, - ImageBehindCursor, ppdev->pPointerAttributes->WidthInBytes); + /* Used to repaint background */ + SizeX = ((cx + ppdev->pPointerAttributes->Width) + 7) & ~0x7; + SizeX -= (cx & ~0x7); + VGADDI_BltToSavedScreenBits(ImageBehindCursor, + cx & ~0x7, + cy, + SizeX, + ppdev->pPointerAttributes->Height); - // Display the cursor - DFB_BltToVGA_Transparent(ppdev->xyCursor.x, ppdev->xyCursor.y, - ppdev->pPointerAttributes->Width, - ppdev->pPointerAttributes->Height, - ppdev->pPointerAttributes->Pixels, - ppdev->pPointerAttributes->WidthInBytes, 5); + /* Display the cursor. */ + AndMask = ppdev->pPointerAttributes->Pixels + + ppdev->pPointerAttributes->WidthInBytes * + ppdev->pPointerAttributes->Height; + VGADDI_BltPointerToVGA(ppdev->xyCursor.x, + ppdev->xyCursor.y, + ppdev->pPointerAttributes->Width, + ppdev->pPointerAttributes->Height, + AndMask, + VGA_AND); + VGADDI_BltPointerToVGA(ppdev->xyCursor.x, + ppdev->xyCursor.y, + ppdev->pPointerAttributes->Width, + ppdev->pPointerAttributes->Height, + ppdev->pPointerAttributes->Pixels, + VGA_XOR); + /* Save the new cursor location. */ oldx = ppdev->xyCursor.x; oldy = ppdev->xyCursor.y; + /* Mark the cursor as currently displayed. */ ppdev->pPointerAttributes->Enable = 1; } diff --git a/reactos/drivers/dd/vga/display/vgaddi.h b/reactos/drivers/dd/vga/display/vgaddi.h index ce1d05659f2..64ddc4abc34 100644 --- a/reactos/drivers/dd/vga/display/vgaddi.h +++ b/reactos/drivers/dd/vga/display/vgaddi.h @@ -2,8 +2,6 @@ #include #include -HANDLE GdiHeap; - #define DS_SOLIDBRUSH 0x00000001 #define DS_GREYBRUSH 0x00000002 #define DS_BRUSH 0x00000004 @@ -94,6 +92,7 @@ typedef enum { //typedef VOID (*PFN_BankControl)(PDEVSURF, ULONG, BANK_JUST); typedef VOID (*PFN_BankControl)(PVOID, ULONG, BANK_JUST); +#if 0 // descriptor for a saved screen bits block typedef struct _SAVED_SCREEN_BITS @@ -109,6 +108,15 @@ typedef struct _SAVED_SCREEN_BITS // for system memory blocks, saved bits start immediately // after this structure } SAVED_SCREEN_BITS, *PSAVED_SCREEN_BITS; +#else +typedef struct _SAVED_SCREEN_BITS +{ + BOOL Free; + DWORD Offset; + ULONG Size; + LIST_ENTRY ListEntry; +} SAVED_SCREEN_BITS, *PSAVED_SCREEN_BITS; +#endif // DEVSURF -- definition of a surface as seen and used by the various VGA // drivers @@ -206,3 +214,22 @@ BOOL InitVGA(PPDEV ppdev, BOOL bFirst); // screen.c: initialize VGA mode BOOL VGAtoGDI( SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, XLATEOBJ *ColorTranslation, RECTL *DestRect, POINTL *SourcePoint); + +VOID +VGADDI_BltFromSavedScreenBits(ULONG DestX, + ULONG DestY, + PSAVED_SCREEN_BITS Src, + ULONG SizeX, + ULONG SizeY); +VOID +VGADDI_BltToSavedScreenBits(PSAVED_SCREEN_BITS Dest, + ULONG SourceX, + ULONG SourceY, + ULONG SizeX, + ULONG SizeY); +VOID +VGADDI_FreeSavedScreenBits(PSAVED_SCREEN_BITS SavedBits); +PSAVED_SCREEN_BITS +VGADDI_AllocSavedScreenBits(ULONG Size); +VOID +VGADDI_InitializeOffScreenMem(ULONG Start, ULONG Length); diff --git a/reactos/drivers/dd/vga/display/vgavideo/vgavideo.c b/reactos/drivers/dd/vga/display/vgavideo/vgavideo.c index 26d5940affb..ca644f1fd07 100644 --- a/reactos/drivers/dd/vga/display/vgavideo/vgavideo.c +++ b/reactos/drivers/dd/vga/display/vgavideo/vgavideo.c @@ -4,6 +4,24 @@ #include #include "vgavideo.h" +UCHAR PreCalcReverseByte[256]; +int maskbit[640]; +int y80[480]; +int xconv[640]; +int bit8[640]; +int startmasks[8]; +int endmasks[8]; +char* vidmem; + +static unsigned char saved_SEQ_mask; /* 0x02 */ +static unsigned char saved_GC_eSR; /* 0x01 */ +static unsigned char saved_GC_fun; /* 0x03 */ +static unsigned char saved_GC_rmap; /* 0x04 */ +static unsigned char saved_GC_mode; /* 0x05 */ +static unsigned char saved_GC_mask; /* 0x08 */ +static unsigned char leftMask; +static int byteCounter; +static unsigned char rightMask; INT abs(INT nm) { @@ -128,6 +146,19 @@ VOID vgaPreCalc() { xconv[j] = j >> 3; } + + for (j = 0; j < 256; j++) + { + PreCalcReverseByte[j] = + (((j >> 0) & 0x1) << 7) | + (((j >> 1) & 0x1) << 6) | + (((j >> 2) & 0x1) << 5) | + (((j >> 3) & 0x1) << 4) | + (((j >> 4) & 0x1) << 3) | + (((j >> 5) & 0x1) << 2) | + (((j >> 6) & 0x1) << 1) | + (((j >> 7) & 0x1) << 0); + } } void diff --git a/reactos/drivers/dd/vga/display/vgavideo/vgavideo.h b/reactos/drivers/dd/vga/display/vgavideo/vgavideo.h index c3bb59d8c65..0a4e97d4546 100644 --- a/reactos/drivers/dd/vga/display/vgavideo/vgavideo.h +++ b/reactos/drivers/dd/vga/display/vgavideo/vgavideo.h @@ -10,9 +10,16 @@ //This is in mingw standard headers //typedef struct { int quot, rem; } div_t; -int maskbit[640], y80[480], xconv[640], bit8[640], startmasks[8], endmasks[8]; +extern int maskbit[640]; +extern int y80[480]; +extern int xconv[640]; +extern int bit8[640]; +extern int startmasks[8]; +extern int endmasks[8]; -char* vidmem; +extern UCHAR PreCalcReverseByte[256]; + +extern char* vidmem; #define MISC 0x3c2 #define SEQ 0x3c4 @@ -56,14 +63,4 @@ BOOL VGADDIIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2); #define ASSIGNVP4(x, y, vp) vp = vidmem /* VBUF */ + (((x) + (y)*SCREEN_X) >> 3); #define ASSIGNMK4(x, y, mask) mask = 0x80 >> ((x) & 7); -static unsigned char saved_SEQ_mask; /* 0x02 */ -static unsigned char saved_GC_eSR; /* 0x01 */ -static unsigned char saved_GC_fun; /* 0x03 */ -static unsigned char saved_GC_rmap; /* 0x04 */ -static unsigned char saved_GC_mode; /* 0x05 */ -static unsigned char saved_GC_mask; /* 0x08 */ -static unsigned char leftMask; -static int byteCounter; -static unsigned char rightMask; - void get_masks(int x, int w); diff --git a/reactos/lib/user32/windows/defwnd.c b/reactos/lib/user32/windows/defwnd.c index 409d4e3d840..383b45d4271 100644 --- a/reactos/lib/user32/windows/defwnd.c +++ b/reactos/lib/user32/windows/defwnd.c @@ -1,4 +1,4 @@ -/* $Id: defwnd.c,v 1.11 2002/09/20 21:55:15 jfilby Exp $ +/* $Id: defwnd.c,v 1.12 2002/09/25 21:21:36 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -204,7 +204,8 @@ static void UserGetInsideRectNC( HWND hwnd, RECT *rect ) { if (UserHasThinFrameStyle(Style, ExStyle)) { - InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) ); + InflateRect(rect, -GetSystemMetrics(SM_CXBORDER), + -GetSystemMetrics(SM_CYBORDER)); } } } @@ -221,8 +222,9 @@ void UserDrawSysButton( HWND hwnd, HDC hdc, BOOL down ) UserGetInsideRectNC( hwnd, &rect ); hdcMem = CreateCompatibleDC( hdc ); hbitmap = SelectObject( hdcMem, hbitmapClose ); - BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE), - hdcMem, (Style & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0, + BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), + GetSystemMetrics(SM_CYSIZE), hdcMem, + (Style & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0, down ? NOTSRCCOPY : SRCCOPY ); SelectObject( hdcMem, hbitmap ); DeleteDC( hdcMem ); diff --git a/reactos/subsys/win32k/eng/mouse.c b/reactos/subsys/win32k/eng/mouse.c index 983f1fee055..2d50475eb04 100644 --- a/reactos/subsys/win32k/eng/mouse.c +++ b/reactos/subsys/win32k/eng/mouse.c @@ -8,6 +8,72 @@ static BOOLEAN SafetySwitch2 = FALSE; static BOOLEAN MouseEnabled = FALSE; static LONG mouse_x, mouse_y; static UINT mouse_width = 0, mouse_height = 0; +static UCHAR DefaultCursor[256] = { + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0xC0, 0x00, 0x00, + 0x00, 0xC0, 0x00, 0x00, + 0x01, 0x80, 0x00, 0x00, + 0x01, 0x80, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, + 0x43, 0x00, 0x00, 0x00, + 0x66, 0x00, 0x00, 0x00, + 0x76, 0x00, 0x00, 0x00, + 0x7E, 0x00, 0x00, 0x00, + 0x7F, 0xC0, 0x00, 0x00, + 0x7F, 0x80, 0x00, 0x00, + 0x7F, 0x00, 0x00, 0x00, + 0x7E, 0x00, 0x00, 0x00, + 0x7C, 0x00, 0x00, 0x00, + 0x78, 0x00, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x3F, 0xFF, 0xFF, + 0xFE, 0x1F, 0xFF, 0xFF, + 0xFE, 0x1F, 0xFF, 0xFF, + 0xFC, 0x3F, 0xFF, 0xFF, + 0x7C, 0x3F, 0xFF, 0xFF, + 0x38, 0x7F, 0xFF, 0xFF, + 0x18, 0x7F, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x1F, 0xFF, 0xFF, + 0x00, 0x3F, 0xFF, 0xFF, + 0x00, 0x7F, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, + 0x01, 0xFF, 0xFF, 0xFF, + 0x03, 0xFF, 0xFF, 0xFF, + 0x07, 0xFF, 0xFF, 0xFF, + 0x0F, 0xFF, 0xFF, 0xFF, + 0x1F, 0xFF, 0xFF, 0xFF, + 0x3F, 0xFF, 0xFF, 0xFF}; INT MouseSafetyOnDrawStart(PSURFOBJ SurfObj, PSURFGDI SurfGDI, LONG HazardX1, LONG HazardY1, LONG HazardX2, LONG HazardY2) { @@ -117,41 +183,17 @@ VOID EnableMouse(HDC hDisplayDC) POINTL ZeroPoint; RECTL MouseRect; - // Draw a test mouse cursor - mouse_width = 16; - mouse_height = 16; - - // Draw transparent colored rectangle - Brush.iSolidColor = 5; - for (i = 0; i < 17; i++) - EngLineTo(SurfObj, NULL, &Brush, 0, i, 17, i, NULL, 0); - - // Draw white interior - Brush.iSolidColor = 15; - for (i = 1; i < 16; i++) - EngLineTo(SurfObj, NULL, &Brush, 0, i-1, 16-i, i-1, NULL, 0); - - // Draw black outline - Brush.iSolidColor = 0; - EngLineTo(SurfObj, NULL, &Brush, 0, 0, 15, 0, NULL, 0); - EngLineTo(SurfObj, NULL, &Brush, 0, 16, 15, 0, NULL, 0); - EngLineTo(SurfObj, NULL, &Brush, 0, 15, 0, 0, NULL, 0); - - // Create the bitmap for the mouse cursor data - MouseSize.cx = 16; - MouseSize.cy = 16; - hMouseSurf = EngCreateBitmap(MouseSize, 16, BMF_4BPP, 0, NULL); + /* Create the default mouse cursor. */ + mouse_width = 32; + mouse_height = 32; + MouseSize.cx = 32; + MouseSize.cy = 64; + hMouseSurf = EngCreateBitmap(MouseSize, 4, BMF_1BPP, 0, DefaultCursor); MouseSurf = (PSURFOBJ)AccessUserObject(hMouseSurf); - // Capture the cursor we drew in the mouse cursor buffer - ZeroPoint.x = 0; - ZeroPoint.y = 0; - MouseRect.top = 0; - MouseRect.left = 0; - MouseRect.bottom = 16; - MouseRect.right = 16; - EngBitBlt(MouseSurf, SurfObj, NULL, NULL, NULL, &MouseRect, &ZeroPoint, NULL, NULL, NULL, SRCCOPY); - SurfGDI->SetPointerShape(SurfObj, MouseSurf, NULL, NULL, 0, 0, 50, 50, &MouseRect, 0); + /* Tell the display driver to set the pointer shape. */ + SurfGDI->SetPointerShape(SurfObj, MouseSurf, NULL, NULL, 0, 0, 320, 240, + &MouseRect, 0); mouse_x = 320; mouse_y = 240;