Imp Get/SetDeviceGammaRamp, not fully supported yet. Fix typos and updates.

svn path=/trunk/; revision=30976
This commit is contained in:
James Tabor 2007-12-03 07:32:10 +00:00
parent 93dd38b8e4
commit 4aee5c9e17
6 changed files with 276 additions and 18 deletions

View file

@ -366,7 +366,7 @@ typedef struct _DC
ULONG lucExcLock;
ULONG Tid;
DHPDEV PDev; // GDIDEVICE.Handle
DHPDEV PDev; // GDIDEVICE.PDev
INT DC_Type;
INT DC_Flags;
PVOID pPDev; // PGDIDEVICE

View file

@ -32,6 +32,30 @@
#define NDEBUG
#include <debug.h>
//
//
//
VOID FASTCALL
ColorCorrection(PPALGDI PalGDI, PPALETTEENTRY PaletteEntry, ULONG Colors)
{
PGDIDEVICE pGDev = (PGDIDEVICE)PalGDI->hPDev;
if (!pGDev) return;
if (pGDev->flFlags & PDEV_GAMMARAMP_TABLE)
{
INT i;
PGAMMARAMP GammaRamp = (PGAMMARAMP)pGDev->pvGammaRamp;
for ( i = 0; i < Colors; i++)
{
PaletteEntry[i].peRed += GammaRamp->Red[i];
PaletteEntry[i].peGreen += GammaRamp->Green[i];
PaletteEntry[i].peBlue += GammaRamp->Blue[i];
}
}
return;
}
/*
* @implemented
*/
@ -80,6 +104,9 @@ PALOBJ_cGetColors(PALOBJ *PalObj, ULONG Start, ULONG Colors, ULONG *PaletteEntry
/* NOTE: PaletteEntry ULONGs are in the same order as PALETTEENTRY. */
RtlCopyMemory(PaletteEntry, PalGDI->IndexedColors + Start, sizeof(ULONG) * Colors);
if (PalGDI->Mode & PAL_GAMMACORRECTION)
ColorCorrection(PalGDI, (PPALETTEENTRY)PaletteEntry, Colors);
return Colors;
}

View file

@ -10,26 +10,26 @@
#define PALETTE_WHITESET 0x2000
// Palette mode flags
#if 0 // Defined in ddk/winddi.h
#define PAL_INDEXED 0x00000001
#define PAL_BITFIELDS 0x00000002
#define PAL_RGB 0x00000004
#define PAL_BGR 0x00000008
#define PAL_CMYK 0x00000010
#ifndef __WINDDI_H // Defined in ddk/winddi.h
#define PAL_INDEXED 0x00000001 // Indexed palette
#define PAL_BITFIELDS 0x00000002 // Bit fields used for DIB, DIB section
#define PAL_RGB 0x00000004 // Red, green, blue
#define PAL_BGR 0x00000008 // Blue, green, red
#define PAL_CMYK 0x00000010 // Cyan, magenta, yellow, black
#endif
#define PAL_DC 0x00000100
#define PAL_FIXED 0x00000200
#define PAL_FIXED 0x00000200 // Can't be changed
#define PAL_FREE 0x00000400
#define PAL_MANAGED 0x00000800
#define PAL_NOSTATIC 0x00001000
#define PAL_MONOCHROME 0x00002000
#define PAL_MONOCHROME 0x00002000 // Two colors only
#define PAL_BRUSHHACK 0x00004000
#define PAL_DIBSECTION 0x00008000
#define PAL_DIBSECTION 0x00008000 // Used for a DIB section
#define PAL_NOSTATIC256 0x00010000
#define PAL_HT 0x00100000
#define PAL_RGB16_555 0x00200000
#define PAL_RGB16_565 0x00400000
#define PAL_GAMMACORRECTION 0x00800000
#define PAL_HT 0x00100000 // Halftone palette
#define PAL_RGB16_555 0x00200000 // 16-bit RGB in 555 format
#define PAL_RGB16_565 0x00400000 // 16-bit RGB in 565 format
#define PAL_GAMMACORRECTION 0x00800000 // Correct colors
typedef struct {
int shift;
@ -52,6 +52,7 @@ typedef struct _PALGDI {
ULONG RedMask;
ULONG GreenMask;
ULONG BlueMask;
HDEV hPDev;
} PALGDI, *PPALGDI;
HPALETTE FASTCALL PALETTE_AllocPalette(ULONG Mode,

View file

@ -35,6 +35,7 @@
#define TAG_DC TAG('D', 'C', 'D', 'C') /* dc */
#define TAG_GDIOBJ TAG('G', 'D', 'I', 'O') /* gdi obj */
#define TAG_GDIHNDTBLE TAG('G', 'D', 'I', 'H') /* gdi handle table */
#define TAG_GDIICM TAG('G', 'i', 'c', 'm') /* gdi Icm */
#define TAG_DIB TAG('D', 'I', 'B', ' ') /* dib */
#define TAG_COLORMAP TAG('C', 'O', 'L', 'M') /* color map */
#define TAG_SHAPE TAG('S', 'H', 'A', 'P') /* shape */

View file

@ -284,6 +284,7 @@ TRACEDRV_ROUTINE(GetDirectDrawInfo)
TRACEDRV_ROUTINE(EnableDirectDraw)
TRACEDRV_ROUTINE(DisableDirectDraw)
TRACEDRV_ROUTINE(QuerySpoolType)
TRACEDRV_ROUTINE(IcmSetDeviceGammaRamp)
TRACEDRV_ROUTINE(GradientFill)
TRACEDRV_ROUTINE(SynchronizeSurface)
TRACEDRV_ROUTINE(AlphaBlend)
@ -352,6 +353,7 @@ static TRACEDRVINFO TraceDrvInfo[] =
TRACEDRVINFO_ENTRY(EnableDirectDraw),
TRACEDRVINFO_ENTRY(DisableDirectDraw),
TRACEDRVINFO_ENTRY(QuerySpoolType),
TRACEDRVINFO_ENTRY(IcmSetDeviceGammaRamp),
TRACEDRVINFO_ENTRY(GradientFill),
TRACEDRVINFO_ENTRY(SynchronizeSurface),
TRACEDRVINFO_ENTRY(AlphaBlend)
@ -450,6 +452,7 @@ BOOL DRIVER_BuildDDIFunctions(PDRVENABLEDATA DED,
DRIVER_FUNCTION(EnableDirectDraw);
DRIVER_FUNCTION(DisableDirectDraw);
DRIVER_FUNCTION(QuerySpoolType);
DRIVER_FUNCTION(IcmSetDeviceGammaRamp);
DRIVER_FUNCTION(GradientFill);
DRIVER_FUNCTION(SynchronizeSurface);
DRIVER_FUNCTION(AlphaBlend);

View file

@ -74,13 +74,94 @@ NtGdiGetColorSpace(HDC hDC)
return 0;
}
BOOL
FASTCALL
IntGetDeviceGammaRamp(HDEV hPDev, PGAMMARAMP Ramp)
{
PGDIDEVICE pGDev = (PGDIDEVICE) hPDev;
int i;
if (!(pGDev->flFlags & PDEV_DISPLAY )) return FALSE;
if ((pGDev->DevInfo.iDitherFormat == BMF_8BPP) ||
(pGDev->DevInfo.iDitherFormat == BMF_16BPP) ||
(pGDev->DevInfo.iDitherFormat == BMF_24BPP) ||
(pGDev->DevInfo.iDitherFormat == BMF_32BPP))
{
if (pGDev->flFlags & PDEV_GAMMARAMP_TABLE)
RtlCopyMemory( Ramp,
pGDev->pvGammaRamp,
sizeof(GAMMARAMP));
else
// Generate the 256-colors array
for(i=0; i<256; i++ )
{
int NewValue = i * 256;
if (NewValue > 65535) NewValue = 65535;
Ramp->Red[i] = Ramp->Green[i] = Ramp->Blue[i] = ((WORD)NewValue);
}
return TRUE;
}
else
return FALSE;
}
BOOL
STDCALL
NtGdiGetDeviceGammaRamp(HDC hDC,
LPVOID Ramp)
{
UNIMPLEMENTED;
return FALSE;
BOOL Ret;
PDC dc;
NTSTATUS Status = STATUS_SUCCESS;
PGAMMARAMP SafeRamp;
if (!Ramp) return FALSE;
dc = DC_LockDc(hDC);
if (!dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
SafeRamp = ExAllocatePool(PagedPool, sizeof(GAMMARAMP));
if (!SafeRamp)
{
DC_UnlockDc(dc);
SetLastWin32Error(STATUS_NO_MEMORY);
return FALSE;
}
Ret = IntGetDeviceGammaRamp((HDEV)dc->pPDev, SafeRamp);
if (!Ret) return Ret;
_SEH_TRY
{
ProbeForWrite( Ramp,
sizeof(PVOID),
1);
RtlCopyMemory( Ramp,
SafeRamp,
sizeof(GAMMARAMP));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
DC_UnlockDc(dc);
ExFreePool(SafeRamp);
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
}
return Ret;
}
BOOL
@ -112,13 +193,158 @@ NtGdiSetColorSpace(IN HDC hdc,
return 0;
}
BOOL
FASTCALL
UpdateDeviceGammaRamp( HDEV hPDev )
{
BOOL Ret = FALSE;
PPALGDI palGDI;
PALOBJ *palPtr;
PGDIDEVICE pGDev = (PGDIDEVICE) hPDev;
if ((pGDev->DevInfo.iDitherFormat == BMF_8BPP) ||
(pGDev->DevInfo.iDitherFormat == BMF_16BPP) ||
(pGDev->DevInfo.iDitherFormat == BMF_24BPP) ||
(pGDev->DevInfo.iDitherFormat == BMF_32BPP))
{
if (pGDev->DriverFunctions.IcmSetDeviceGammaRamp)
return pGDev->DriverFunctions.IcmSetDeviceGammaRamp( pGDev->PDev,
IGRF_RGB_256WORDS,
pGDev->pvGammaRamp);
if ( (pGDev->DevInfo.iDitherFormat != BMF_8BPP) ||
!(pGDev->GDIInfo.flRaster & RC_PALETTE)) return FALSE;
if (!(pGDev->flFlags & PDEV_GAMMARAMP_TABLE)) return FALSE;
palGDI = PALETTE_LockPalette(pGDev->DevInfo.hpalDefault);
if(!palGDI) return FALSE;
palPtr = (PALOBJ*) palGDI;
if (pGDev->flFlags & PDEV_GAMMARAMP_TABLE)
palGDI->Mode |= PAL_GAMMACORRECTION;
else
palGDI->Mode &= ~PAL_GAMMACORRECTION;
if (!(pGDev->flFlags & PDEV_DRIVER_PUNTED_CALL)) // No punting, we hook
{
// BMF_8BPP only!
// PALOBJ_cGetColors check mode flags and update Gamma Correction.
// Set the HDEV to pal and go.
palGDI->hPDev = hPDev;
Ret = pGDev->DriverFunctions.SetPalette(pGDev->PDev,
palPtr,
0,
0,
palGDI->NumColors);
}
PALETTE_UnlockPalette(palGDI);
return Ret;
}
else
return FALSE;
}
BOOL
FASTCALL
IntSetDeviceGammaRamp(HDEV hPDev, PGAMMARAMP Ramp)
{
BOOL Ret = FALSE;
PGDIDEVICE pGDev = (PGDIDEVICE) hPDev;
if (!hPDev) return FALSE;
if (!(pGDev->flFlags & PDEV_DISPLAY )) return FALSE;
if ((pGDev->DevInfo.iDitherFormat == BMF_8BPP) ||
(pGDev->DevInfo.iDitherFormat == BMF_16BPP) ||
(pGDev->DevInfo.iDitherFormat == BMF_24BPP) ||
(pGDev->DevInfo.iDitherFormat == BMF_32BPP))
{
if (!pGDev->DriverFunctions.IcmSetDeviceGammaRamp)
{ // No driver support
if (!(pGDev->DevInfo.flGraphicsCaps2 & GCAPS2_CHANGEGAMMARAMP))
{ // Driver does not support Gamma Ramp, so test to see we
// have BMF_8BPP only and palette operation support.
if ((pGDev->DevInfo.iDitherFormat != BMF_8BPP) ||
!(pGDev->GDIInfo.flRaster & RC_PALETTE)) return FALSE;
}
}
if (pGDev->flFlags & PDEV_GAMMARAMP_TABLE)
if (RtlCompareMemory( pGDev->pvGammaRamp, Ramp, sizeof(GAMMARAMP)) ==
sizeof(GAMMARAMP)) return TRUE;
if (!pGDev->pvGammaRamp && !(pGDev->flFlags & PDEV_GAMMARAMP_TABLE))
{ // If the above is true and we have nothing allocated, create it.
pGDev->pvGammaRamp = ExAllocatePoolWithTag(PagedPool, sizeof(GAMMARAMP), TAG_GDIICM);
pGDev->flFlags |= PDEV_GAMMARAMP_TABLE;
}
//
// Need to adjust the input Ramp with internal brightness before copy.
// ICM subkey sets internal brightness, gamma range 128 or 256 during icm init.
RtlCopyMemory( pGDev->pvGammaRamp, Ramp, sizeof(GAMMARAMP));
Ret = UpdateDeviceGammaRamp(hPDev);
return Ret;
}
else
return FALSE;
}
BOOL
STDCALL
NtGdiSetDeviceGammaRamp(HDC hDC,
LPVOID Ramp)
{
UNIMPLEMENTED;
return FALSE;
BOOL Ret;
PDC dc;
NTSTATUS Status = STATUS_SUCCESS;
PGAMMARAMP SafeRamp;
if (!Ramp) return FALSE;
dc = DC_LockDc(hDC);
if (!dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
SafeRamp = ExAllocatePool(PagedPool, sizeof(GAMMARAMP));
if (!SafeRamp)
{
DC_UnlockDc(dc);
SetLastWin32Error(STATUS_NO_MEMORY);
return FALSE;
}
_SEH_TRY
{
ProbeForRead( Ramp,
sizeof(PVOID),
1);
RtlCopyMemory( SafeRamp,
Ramp,
sizeof(GAMMARAMP));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if (!NT_SUCCESS(Status))
{
DC_UnlockDc(dc);
ExFreePool(SafeRamp);
SetLastNtError(Status);
return FALSE;
}
Ret = IntSetDeviceGammaRamp((HDEV)dc->pPDev, SafeRamp);
DC_UnlockDc(dc);
ExFreePool(SafeRamp);
return Ret;
}
INT