Win32k fixes including better 1BPP support

svn path=/trunk/; revision=3561
This commit is contained in:
Jason Filby 2002-09-24 20:22:10 +00:00
parent 25c608fd37
commit bf2d96d820
11 changed files with 261 additions and 31 deletions

View file

@ -64,7 +64,7 @@ void DIBTest(void)
// 1BPP Test
Test1BPP(Desktop);
Sleep(10000);
Sleep(50000);
// Free up everything
DeleteDC(Desktop);

View file

@ -22,6 +22,7 @@ typedef struct _BITMAPOBJ
/* For device-independent bitmaps: */
DIBSECTION *dib;
RGBQUAD *ColorMap;
} BITMAPOBJ, *PBITMAPOBJ;
/* Internal interface */

View file

@ -110,6 +110,7 @@ copy apps\tests\pteb\pteb.exe %ROS_INSTALL%\bin
copy apps\tests\consume\consume.exe %ROS_INSTALL%\bin
copy apps\tests\vmtest\vmtest.exe %ROS_INSTALL%\bin
copy apps\tests\gditest\gditest.exe %ROS_INSTALL%\bin
copy apps\tests\dibtest\dibtest.exe %ROS_INSTALL%\bin
copy apps\tests\mstest\msserver.exe %ROS_INSTALL%\bin
copy apps\tests\mstest\msclient.exe %ROS_INSTALL%\bin
copy apps\tests\nptest\npserver.exe %ROS_INSTALL%\bin

View file

@ -16,13 +16,13 @@ PFN_DIB_PutPixel DIB_1BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c)
addr += y * SurfObj->lDelta + (x >> 3);
if(c == 1)
if(c == 0)
{
*addr = (*addr | mask1Bpp[mod(x, 8)]);
*addr = (*addr ^ mask1Bpp[mod(x, 8)]);
}
else
{
*addr = (*addr ^ mask1Bpp[mod(x, 8)]);
*addr = (*addr | mask1Bpp[mod(x, 8)]);
}
}
@ -36,17 +36,17 @@ PFN_DIB_GetPixel DIB_1BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y)
PFN_DIB_HLine DIB_1BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
{
LONG cx = x1;
while(cx <= x2) {
DIB_1BPP_PutPixel(SurfObj, cx, y, c);
while(x1 <= x2) {
DIB_1BPP_PutPixel(SurfObj, x1, y, c);
x1++;
}
}
PFN_DIB_VLine DIB_1BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
{
while(y1++ <= y2) {
while(y1 <= y2) {
DIB_1BPP_PutPixel(SurfObj, x, y1, c);
y1++;
}
}

View file

@ -34,6 +34,11 @@ BOOLEAN CopyBitsCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
// Assign GetPixel DIB function according to bytes per pixel
switch(DestGDI->BitsPerPixel)
{
case 1:
return DIB_To_1BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI,
DestRect, SourcePoint, Delta, ColorTranslation);
break;
case 4:
return DIB_To_4BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI,
DestRect, SourcePoint, Delta, ColorTranslation);

View file

@ -42,6 +42,12 @@ EngLineTo(SURFOBJ *Surface,
// Assign DIB functions according to bytes per pixel
switch(BitsPerFormat(Surface->iBitmapFormat))
{
case 1:
DIB_PutPixel = (PFN_DIB_PutPixel)DIB_1BPP_PutPixel;
DIB_HLine = (PFN_DIB_HLine)DIB_1BPP_HLine;
DIB_VLine = (PFN_DIB_VLine)DIB_1BPP_VLine;
break;
case 4:
DIB_PutPixel = (PFN_DIB_PutPixel)DIB_4BPP_PutPixel;
DIB_HLine = (PFN_DIB_HLine)DIB_4BPP_HLine;

View file

@ -37,16 +37,17 @@ EngFreeMem(PVOID Mem)
PVOID STDCALL
EngAllocUserMem(ULONG cj, ULONG tag)
{
/* PVOID newMem;
PVOID newMem = NULL;
NTSTATUS status;
return ZwAllocateVirtualMemory(mycurrentprocess, newMem, 0, cj,
MEM_COMMIT, PAGE_READWRITE); */
status = ZwAllocateVirtualMemory(NtCurrentProcess(), &newMem, 0, &cj, MEM_COMMIT, PAGE_READWRITE);
return NULL;
if(status != STATUS_SUCCESS) return NULL;
return newMem;
}
VOID STDCALL
EngFreeUserMem(PVOID pv)
{
/* ZwFreeVirtualMemory (mycurrentprocess, pv, 0, MEM_DECOMMIT); */
ZwFreeVirtualMemory (NtCurrentProcess(), &pv, 0, MEM_DECOMMIT);
}

View file

@ -53,7 +53,7 @@ ULONG ClosestColorMatch(ULONG SourceColor, ULONG *DestColors,
PVIDEO_CLUTDATA cSourceColor;
PVIDEO_CLUTDATA cDestColors;
LONG idx = 0, i, rt;
ULONG cxRed, cxGreen, cxBlue, BestMatch = 65535;
ULONG cxRed, cxGreen, cxBlue, BestMatch = 16777215;
// Simple cache -- only one value because we don't want to waste time
// if the colors aren't very sequential

View file

@ -1,4 +1,4 @@
/* $Id: dc.c,v 1.41 2002/09/19 22:41:57 jfilby Exp $
/* $Id: dc.c,v 1.42 2002/09/24 20:22:10 jfilby Exp $
*
* DC.C - Device context functions
*
@ -939,6 +939,7 @@ HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj)
PXLATEOBJ XlateObj;
PPALGDI PalGDI;
WORD objectMagic;
ULONG NumColors;
if(!hDC || !hGDIObj) return NULL;
@ -998,6 +999,16 @@ HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj)
// if we're working with a DIB, get the palette [fixme: only create if the selected palette is null]
if(pb->dib)
{
dc->w.bitsPerPixel = pb->dib->dsBmih.biBitCount;
if(pb->dib->dsBmih.biBitCount <= 8)
{
if(pb->dib->dsBmih.biBitCount == 1) { NumColors = 2; } else
if(pb->dib->dsBmih.biBitCount == 4) { NumColors = 16; } else
if(pb->dib->dsBmih.biBitCount == 8) { NumColors = 256; }
dc->w.hPalette = EngCreatePalette(PAL_INDEXED, NumColors, pb->ColorMap, 0, 0, 0);
} else
if((pb->dib->dsBmih.biBitCount > 8) && (pb->dib->dsBmih.biBitCount < 24))
{
dc->w.hPalette = EngCreatePalette(PAL_BITFIELDS, pb->dib->dsBmih.biClrUsed, NULL, 0, 0, 0);
@ -1006,6 +1017,8 @@ HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj)
{
dc->w.hPalette = EngCreatePalette(PAL_RGB, pb->dib->dsBmih.biClrUsed, NULL, 0, 0, 0);
}
} else {
dc->w.bitsPerPixel = pb->bitmap.bmBitsPixel;
}
break;
#if UPDATEREGIONS

View file

@ -402,7 +402,7 @@ HBITMAP STDCALL W32kCreateDIBSection(HDC hDC,
if ((dc = DC_HandleToPtr(hDC)))
{
hbitmap = DIB_CreateDIBSection(dc, bmi, Usage, Bits, hSection, dwOffset, 0);
DC_ReleasePtr( hDC );
DC_ReleasePtr(hDC);
}
if (bDesktopDC)
@ -419,12 +419,11 @@ HBITMAP DIB_CreateDIBSection(
HBITMAP res = 0;
BITMAPOBJ *bmp = NULL;
DIBSECTION *dib = NULL;
int *colorMap = NULL;
int nColorMap;
// Fill BITMAP32 structure with DIB data
BITMAPINFOHEADER *bi = &bmi->bmiHeader;
INT effHeight, totalSize;
UINT Entries = 0;
BITMAP bm;
DbgPrint("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
@ -446,27 +445,27 @@ HBITMAP DIB_CreateDIBSection(
totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
? bi->biSizeImage : bm.bmWidthBytes * effHeight;
/*
if (section)
bm.bmBits = MapViewOfFile(section, FILE_MAP_ALL_ACCESS,
0L, offset, totalSize);
/* bm.bmBits = MapViewOfFile(section, FILE_MAP_ALL_ACCESS,
0L, offset, totalSize); */
DbgPrint("DIB_CreateDIBSection: Cannot yet handle section DIBs\n");
else if (ovr_pitch && offset)
bm.bmBits = (LPVOID) offset;
else { */
else {
offset = 0;
/* bm.bmBits = VirtualAlloc(NULL, totalSize,
MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); */
bm.bmBits = EngAllocUserMem(totalSize, 0);
}
bm.bmBits = ExAllocatePool(NonPagedPool, totalSize);
/* bm.bmBits = ExAllocatePool(NonPagedPool, totalSize); */
/* } */
if (usage == DIB_PAL_COLORS) memcpy(bmi->bmiColors, (UINT *)DIB_MapPaletteColors(dc, bmi), sizeof(UINT *));
if(usage == DIB_PAL_COLORS) memcpy(bmi->bmiColors, (UINT *)DIB_MapPaletteColors(dc, bmi), sizeof(UINT *));
// Allocate Memory for DIB and fill structure
if (bm.bmBits)
{
dib = ExAllocatePool(PagedPool, sizeof(DIBSECTION));
RtlZeroMemory(dib, sizeof(DIBSECTION));
}
if (dib)
{
@ -515,10 +514,20 @@ HBITMAP DIB_CreateDIBSection(
bmp->dib = (DIBSECTION *) dib;
}
}
/* WINE NOTE: WINE makes use of a colormap, which is a color translation table between the DIB and the X physical
device. Obviously, this is left out of the ReactOS implementation. Instead, we call
W32kSetDIBColorTable. */
if(bi->biBitCount == 1) { Entries = 2; } else
if(bi->biBitCount == 4) { Entries = 16; } else
if(bi->biBitCount == 8) { Entries = 256; }
bmp->ColorMap = ExAllocatePool(NonPagedPool, sizeof(RGBQUAD)*Entries);
RtlCopyMemory(bmp->ColorMap, bmi->bmiColors, sizeof(RGBQUAD)*Entries);
}
// Clean up in case of errors
if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
if (!res || !bmp || !dib || !bm.bmBits)
{
DbgPrint("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n", res, bmp, dib, bm.bmBits);
/* if (bm.bmBits)
@ -529,7 +538,6 @@ HBITMAP DIB_CreateDIBSection(
VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
} */
if (colorMap) { ExFreePool(colorMap); colorMap = NULL; }
if (dib) { ExFreePool(dib); dib = NULL; }
if (bmp) { bmp = NULL; }
if (res) { GDIOBJ_FreeObj(res, GO_BITMAP_MAGIC); res = 0; }
@ -558,6 +566,7 @@ HBITMAP DIB_CreateDIBSection(
// Return BITMAP handle and storage location
if (bm.bmBits && bits) *bits = bm.bmBits;
return res;
}

View file

@ -4,6 +4,7 @@
#include <win32k/bitmaps.h>
#include <win32k/color.h>
#include <debug.h>
#include "../include/palette.h"
static int PALETTE_firstFree = 0;
static unsigned char PALETTE_freeList[256];
@ -57,6 +58,8 @@ HPALETTE PALETTE_Init(void)
// GDI_ReleaseObj( hpalette );
}
/* palette_size = visual->map_entries; */
return hpalette;
}
@ -80,6 +83,61 @@ static void PALETTE_FormatSystemPalette(void)
PALETTE_freeList[j] = 0;
}
/* Ported from WINE 20020804 (graphics\x11drv\palette.c) */
static int SysPaletteLookupPixel( COLORREF col, BOOL skipReserved )
{
int i, best = 0, diff = 0x7fffffff;
int r,g,b;
for( i = 0; i < palette_size && diff ; i++ )
{
if( !(COLOR_sysPal[i].peFlags & PC_SYS_USED) || (skipReserved && COLOR_sysPal[i].peFlags & PC_SYS_RESERVED) )
continue;
r = COLOR_sysPal[i].peRed - GetRValue(col);
g = COLOR_sysPal[i].peGreen - GetGValue(col);
b = COLOR_sysPal[i].peBlue - GetBValue(col);
r = r*r + g*g + b*b;
if( r < diff ) { best = i; diff = r; }
}
return best;
}
/* Ported from WINE 20020804 (graphics\x11drv\palette.c) */
/* Make sure this is required - ROS's xlate may make this redundant */
UINT WINAPI GetNearestPaletteIndex(
HPALETTE hpalette, /* [in] Handle of logical color palette */
COLORREF color) /* [in] Color to be matched */
{
PPALOBJ palObj = (PPALOBJ)AccessUserObject(hpalette);
UINT index = 0;
if( palObj )
{
int i, diff = 0x7fffffff;
int r,g,b;
PALETTEENTRY* entry = palObj->logpalette->palPalEntry;
for( i = 0; i < palObj->logpalette->palNumEntries && diff ; i++, entry++)
{
if (!(entry->peFlags & PC_SYS_USED)) continue;
r = entry->peRed - GetRValue(color);
g = entry->peGreen - GetGValue(color);
b = entry->peBlue - GetBValue(color);
r = r*r + g*g + b*b;
if( r < diff ) { index = i; diff = r; }
}
// GDI_ReleaseObj( hpalette );
}
DPRINT("(%04x,%06lx): returning %d\n", hpalette, color, index );
return index;
}
void PALETTE_ValidateFlags(PALETTEENTRY* lpPalE, int size)
{
int i = 0;
@ -190,3 +248,139 @@ int PALETTE_SetMapping(PPALOBJ palPtr, UINT uStart, UINT uNum, BOOL mapOnly)
}
return iRemapped;
}
/* Return the physical color closest to 'color'. */
/* Ported from WINE 20020804 (graphics\x11drv\palette.c) */
int PALETTE_ToPhysical( PDC dc, COLORREF color )
{
WORD index = 0;
HPALETTE hPal = (dc)? dc->w.hPalette: W32kGetStockObject(DEFAULT_PALETTE);
unsigned char spec_type = color >> 24;
PPALOBJ palPtr = (PPALOBJ)AccessUserObject(hPal);
/* palPtr can be NULL when DC is being destroyed */
if( !palPtr ) return 0;
if ( PALETTE_PaletteFlags & PALETTE_FIXED )
{
/* there is no colormap limitation; we are going to have to compute
* the pixel value from the visual information stored earlier
*/
unsigned long red, green, blue;
unsigned idx = 0;
switch(spec_type)
{
case 1: /* PALETTEINDEX */
if( (idx = color & 0xffff) >= palPtr->logpalette->palNumEntries)
{
DPRINT("RGB(%lx) : idx %d is out of bounds, assuming black\n", color, idx);
// GDI_ReleaseObj( hPal );
return 0;
}
if( palPtr->mapping )
{
int ret = palPtr->mapping[idx];
// GDI_ReleaseObj( hPal );
return ret;
}
color = *(COLORREF*)(palPtr->logpalette->palPalEntry + idx);
break;
default:
color &= 0xffffff;
/* fall through to RGB */
case 0: /* RGB */
if( dc && (dc->w.bitsPerPixel == 1) )
{
// GDI_ReleaseObj( hPal );
return (((color >> 16) & 0xff) +
((color >> 8) & 0xff) + (color & 0xff) > 255*3/2) ? 1 : 0;
}
}
red = GetRValue(color); green = GetGValue(color); blue = GetBValue(color);
if (PALETTE_Graymax)
{
/* grayscale only; return scaled value */
// GDI_ReleaseObj( hPal );
return ( (red * 30 + green * 59 + blue * 11) * PALETTE_Graymax) / 25500;
}
else
{
/* scale each individually and construct the TrueColor pixel value */
if (PALETTE_PRed.scale < 8)
red = red >> (8-PALETTE_PRed.scale);
else if (PALETTE_PRed.scale > 8)
red = red << (PALETTE_PRed.scale-8) |
red >> (16-PALETTE_PRed.scale);
if (PALETTE_PGreen.scale < 8)
green = green >> (8-PALETTE_PGreen.scale);
else if (PALETTE_PGreen.scale > 8)
green = green << (PALETTE_PGreen.scale-8) |
green >> (16-PALETTE_PGreen.scale);
if (PALETTE_PBlue.scale < 8)
blue = blue >> (8-PALETTE_PBlue.scale);
else if (PALETTE_PBlue.scale > 8)
blue = blue << (PALETTE_PBlue.scale-8) |
blue >> (16-PALETTE_PBlue.scale);
// GDI_ReleaseObj( hPal );
return (red << PALETTE_PRed.shift) | (green << PALETTE_PGreen.shift) | (blue << PALETTE_PBlue.shift);
}
}
else
{
if( !palPtr->mapping )
DPRINT("Palette %04x is not realized\n", dc->w.hPalette);
switch(spec_type) /* we have to peruse DC and system palette */
{
default:
color &= 0xffffff;
/* fall through to RGB */
case 0: /* RGB */
if( dc && (dc->w.bitsPerPixel == 1) )
{
// GDI_ReleaseObj( hPal );
return (((color >> 16) & 0xff) +
((color >> 8) & 0xff) + (color & 0xff) > 255*3/2) ? 1 : 0;
}
index = SysPaletteLookupPixel( color, FALSE);
/* if (PALETTE_PaletteToXPixel) index = PALETTE_PaletteToXPixel[index]; */
/* DPRINT(palette,"RGB(%lx) -> pixel %i\n", color, index);
*/
break;
case 1: /* PALETTEINDEX */
index = color & 0xffff;
if( index >= palPtr->logpalette->palNumEntries )
DbgPrint("RGB(%lx) : index %i is out of bounds\n", color, index);
else if( palPtr->mapping ) index = palPtr->mapping[index];
/* DPRINT(palette,"PALETTEINDEX(%04x) -> pixel %i\n", (WORD)color, index);
*/
break;
case 2: /* PALETTERGB */
index = GetNearestPaletteIndex( hPal, color );
if (palPtr->mapping) index = palPtr->mapping[index];
/* DPRINT(palette,"PALETTERGB(%lx) -> pixel %i\n", color, index);
*/
break;
}
}
// GDI_ReleaseObj( hPal );
return index;
}