* 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.
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-/* $Id$ */
-#include <w32k.h>
+#include <win32k.h>
#define NDEBUG
#include <debug.h>
+HCOLORSPACE hStockColorSpace = NULL;
+
+
+HCOLORSPACE
+FASTCALL
+IntGdiCreateColorSpace(
+ PLOGCOLORSPACEEXW pLogColorSpace)
+{
+ PCOLORSPACE pCS;
+ HCOLORSPACE hCS;
+
+ pCS = COLORSPACEOBJ_AllocCSWithHandle();
+ hCS = pCS->BaseObject.hHmgr;
+
+ pCS->lcsColorSpace = pLogColorSpace->lcsColorSpace;
+ pCS->dwFlags = pLogColorSpace->dwFlags;
+
+ COLORSPACEOBJ_UnlockCS(pCS);
+ return hCS;
+}
+
BOOL
-STDCALL
-NtGdiColorMatchToTarget(HDC hDC,
- HDC hDCTarget,
- DWORD Action)
+FASTCALL
+IntGdiDeleteColorSpace(
+ HCOLORSPACE hColorSpace)
{
- UNIMPLEMENTED;
- return FALSE;
+ BOOL Ret = FALSE;
+
+ if ( hColorSpace != hStockColorSpace )
+ {
+ Ret = COLORSPACEOBJ_FreeCSByHandle(hColorSpace);
+ if ( !Ret ) SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ }
+ return Ret;
}
HANDLE
NtGdiCreateColorSpace(
IN PLOGCOLORSPACEEXW pLogColorSpace)
{
- UNIMPLEMENTED;
- return 0;
+ LOGCOLORSPACEEXW Safelcs;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ _SEH2_TRY
+ {
+ ProbeForRead( pLogColorSpace,
+ sizeof(LOGCOLORSPACEEXW),
+ 1);
+ RtlCopyMemory(&Safelcs, pLogColorSpace, sizeof(LOGCOLORSPACEEXW));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return NULL;
+ }
+ return IntGdiCreateColorSpace(&Safelcs);
}
BOOL
NtGdiDeleteColorSpace(
IN HANDLE hColorSpace)
{
- UNIMPLEMENTED;
- return FALSE;
+ return IntGdiDeleteColorSpace(hColorSpace);
}
-INT
-STDCALL
-NtGdiEnumICMProfiles(HDC hDC,
- LPWSTR lpstrBuffer,
- UINT cch )
+BOOL
+FASTCALL
+IntGetDeviceGammaRamp(HDEV hPDev, PGAMMARAMP Ramp)
{
- /*
- * FIXME - build list of file names into lpstrBuffer.
- * (MULTI-SZ would probably be best format)
- * return (needed) length of buffer in bytes
- */
- UNIMPLEMENTED;
- return 0;
-}
+ PPDEVOBJ pGDev = (PPDEVOBJ) hPDev;
+ int i;
-HCOLORSPACE
-STDCALL
-NtGdiGetColorSpace(HDC hDC)
-{
- /* FIXME: Need to to whatever GetColorSpace actually does */
- return 0;
+ 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;
+
+ Ramp->Red[i] = Ramp->Green[i] = Ramp->Blue[i] = ((WORD)NewValue);
+ }
+ return TRUE;
+ }
+ else
+ return FALSE;
}
BOOL
-STDCALL
+APIENTRY
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 = ExAllocatePoolWithTag(PagedPool, sizeof(GAMMARAMP), TAG_GDIICM);
+ if (!SafeRamp)
+ {
+ DC_UnlockDc(dc);
+ SetLastWin32Error(STATUS_NO_MEMORY);
+ return FALSE;
+ }
+
+ Ret = IntGetDeviceGammaRamp((HDEV)dc->ppdev, SafeRamp);
+
+ if (!Ret) return Ret;
+
+ _SEH2_TRY
+ {
+ ProbeForWrite( Ramp,
+ sizeof(PVOID),
+ 1);
+ RtlCopyMemory( Ramp,
+ SafeRamp,
+ sizeof(GAMMARAMP));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ DC_UnlockDc(dc);
+ ExFreePoolWithTag(SafeRamp, TAG_GDIICM);
+
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return FALSE;
+ }
+ return Ret;
}
BOOL
-STDCALL
-NtGdiGetICMProfile(HDC hDC,
- LPDWORD NameSize,
- LPWSTR Filename)
+APIENTRY
+NtGdiSetColorSpace(IN HDC hdc,
+ IN HCOLORSPACE hColorSpace)
{
- UNIMPLEMENTED;
- return FALSE;
+ PDC pDC;
+ PDC_ATTR pdcattr;
+ PCOLORSPACE pCS;
+
+ pDC = DC_LockDc(hdc);
+ if (!pDC)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+ pdcattr = pDC->pdcattr;
+
+ if (pdcattr->hColorSpace == hColorSpace)
+ {
+ DC_UnlockDc(pDC);
+ return TRUE;
+ }
+
+ pCS = COLORSPACEOBJ_LockCS(hColorSpace);
+ if (!pCS)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ if (pDC->dclevel.pColorSpace)
+ {
+ GDIOBJ_ShareUnlockObjByPtr((POBJ) pDC->dclevel.pColorSpace);
+ }
+
+ pDC->dclevel.pColorSpace = pCS;
+ pdcattr->hColorSpace = hColorSpace;
+
+ COLORSPACEOBJ_UnlockCS(pCS);
+ DC_UnlockDc(pDC);
+ return TRUE;
}
BOOL
-STDCALL
-NtGdiGetLogColorSpace(HCOLORSPACE hColorSpace,
- LPLOGCOLORSPACEW Buffer,
- DWORD Size)
+FASTCALL
+UpdateDeviceGammaRamp( HDEV hPDev )
{
- UNIMPLEMENTED;
- return FALSE;
+ BOOL Ret = FALSE;
+ PPALETTE palGDI;
+ PALOBJ *palPtr;
+ PPDEVOBJ pGDev = (PPDEVOBJ) 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->dhpdev,
+ 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->dhpdev,
+ palPtr,
+ 0,
+ 0,
+ palGDI->NumColors);
+ }
+ PALETTE_UnlockPalette(palGDI);
+ return Ret;
+ }
+ else
+ return FALSE;
}
+//
+// ICM registry subkey sets internal brightness range, gamma range is 128 or
+// 256 when icm is init.
+INT IcmGammaRangeSet = 128; // <- make it global
+
BOOL
-STDCALL
-NtGdiSetColorSpace(IN HDC hdc,
- IN HCOLORSPACE hColorSpace)
+FASTCALL
+IntSetDeviceGammaRamp(HDEV hPDev, PGAMMARAMP Ramp, BOOL Test)
{
- UNIMPLEMENTED;
- return 0;
+ WORD IcmGR, i, R, G, B;
+ BOOL Ret = FALSE, TstPeak;
+ PPDEVOBJ pGDev = (PPDEVOBJ) 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;
+ // Verify Ramp is inside range.
+ IcmGR = -IcmGammaRangeSet;
+ TstPeak = (Test == FALSE);
+ for (i = 0; i < 256; i++)
+ {
+ R = Ramp->Red[i] / 256;
+ G = Ramp->Green[i] / 256;
+ B = Ramp->Blue[i] / 256;
+ if ( R >= IcmGR)
+ {
+ if ( R <= IcmGammaRangeSet + i)
+ {
+ if ( G >= IcmGR &&
+ (G <= IcmGammaRangeSet + i) &&
+ B >= IcmGR &&
+ (B <= IcmGammaRangeSet + i) ) continue;
+ }
+ }
+ if (Test) return Ret; // Don't set and return.
+ // No test override, check max range
+ if (TstPeak)
+ {
+ if ( R != (IcmGR * 256) ||
+ G != (IcmGR * 256) ||
+ B != (IcmGR * 256) ) TstPeak = FALSE; // W/i range.
+ }
+ }
+ // ReactOS allocates a ramp even if it is 8BPP and Palette only.
+ // This way we have a record of the change in memory.
+ 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;
+ }
+ if (pGDev->pvGammaRamp)
+ RtlCopyMemory( pGDev->pvGammaRamp, Ramp, sizeof(GAMMARAMP));
+
+ Ret = UpdateDeviceGammaRamp(hPDev);
+
+ return Ret;
+ }
+ else
+ return Ret;
}
BOOL
-STDCALL
+APIENTRY
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 = ExAllocatePoolWithTag(PagedPool, sizeof(GAMMARAMP), TAG_GDIICM);
+ if (!SafeRamp)
+ {
+ DC_UnlockDc(dc);
+ SetLastWin32Error(STATUS_NO_MEMORY);
+ return FALSE;
+ }
+ _SEH2_TRY
+ {
+ ProbeForRead( Ramp,
+ sizeof(PVOID),
+ 1);
+ RtlCopyMemory( SafeRamp,
+ Ramp,
+ sizeof(GAMMARAMP));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ DC_UnlockDc(dc);
+ ExFreePoolWithTag(SafeRamp, TAG_GDIICM);
+ SetLastNtError(Status);
+ return FALSE;
+ }
+
+ Ret = IntSetDeviceGammaRamp((HDEV)dc->ppdev, SafeRamp, TRUE);
+ DC_UnlockDc(dc);
+ ExFreePoolWithTag(SafeRamp, TAG_GDIICM);
+ return Ret;
}
INT
-STDCALL
+APIENTRY
NtGdiSetIcmMode(HDC hDC,
ULONG nCommand,
ULONG EnableICM) // ulMode
return 0;
}
-BOOL
-STDCALL
-NtGdiSetICMProfile(HDC hDC,
- LPWSTR Filename)
-{
- UNIMPLEMENTED;
- return FALSE;
-}
-
-BOOL
-STDCALL
-NtGdiUpdateICMRegKey(DWORD Reserved,
- LPWSTR CMID,
- LPWSTR Filename,
- UINT Command)
-{
- UNIMPLEMENTED;
- return FALSE;
-}
-
/* EOF */