diff --git a/reactos/dll/win32/gdi32/gdi32.rbuild b/reactos/dll/win32/gdi32/gdi32.rbuild index fe27eb3ed5f..4418bac6d13 100644 --- a/reactos/dll/win32/gdi32/gdi32.rbuild +++ b/reactos/dll/win32/gdi32/gdi32.rbuild @@ -39,6 +39,7 @@ eng.c enhmfile.c font.c + icm.c linedda.c metafile.c painting.c diff --git a/reactos/dll/win32/gdi32/misc/stubs.c b/reactos/dll/win32/gdi32/misc/stubs.c index 29f32c51a84..297f8d569ca 100644 --- a/reactos/dll/win32/gdi32/misc/stubs.c +++ b/reactos/dll/win32/gdi32/misc/stubs.c @@ -637,34 +637,6 @@ CheckColorsInGamut( } -/* - * @unimplemented - */ -HCOLORSPACE -STDCALL -GetColorSpace(HDC hDc) -{ - UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - -/* - * @unimplemented - */ -HCOLORSPACE -STDCALL -SetColorSpace( - HDC a0, - HCOLORSPACE a1 - ) -{ - UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - /* * @implemented */ diff --git a/reactos/dll/win32/gdi32/misc/stubsa.c b/reactos/dll/win32/gdi32/misc/stubsa.c index ee280dc5a9d..ec2894c05d5 100644 --- a/reactos/dll/win32/gdi32/misc/stubsa.c +++ b/reactos/dll/win32/gdi32/misc/stubsa.c @@ -85,21 +85,6 @@ GetLogColorSpaceA( } -/* - * @unimplemented - */ -HCOLORSPACE -STDCALL -CreateColorSpaceA( - LPLOGCOLORSPACEA a0 - ) -{ - UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - /* * @unimplemented */ diff --git a/reactos/dll/win32/gdi32/misc/stubsw.c b/reactos/dll/win32/gdi32/misc/stubsw.c index 82460c63bc2..d00154b79ca 100644 --- a/reactos/dll/win32/gdi32/misc/stubsw.c +++ b/reactos/dll/win32/gdi32/misc/stubsw.c @@ -48,20 +48,6 @@ GetLogColorSpaceW( return FALSE; } -/* - * @unimplemented - */ -HCOLORSPACE -STDCALL -CreateColorSpaceW( - LPLOGCOLORSPACEW a0 - ) -{ - UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - /* * @unimplemented diff --git a/reactos/dll/win32/gdi32/objects/icm.c b/reactos/dll/win32/gdi32/objects/icm.c new file mode 100644 index 00000000000..b6c31c17efb --- /dev/null +++ b/reactos/dll/win32/gdi32/objects/icm.c @@ -0,0 +1,130 @@ +#include "precomp.h" + +#define NDEBUG +#include + + +HCOLORSPACE +FASTCALL +IntCreateColorSpaceW( + LPLOGCOLORSPACEW lplcpw, + BOOL Ascii + ) +{ + LOGCOLORSPACEEXW lcpeexw; + + if ((lplcpw->lcsSignature != LCS_SIGNATURE) || + (lplcpw->lcsVersion != 0x400) || + (lplcpw->lcsSize != sizeof(LOGCOLORSPACEW))) + { + SetLastError(ERROR_INVALID_COLORSPACE); + return NULL; + } + RtlCopyMemory(&lcpeexw.lcsColorSpace, lplcpw, sizeof(LOGCOLORSPACEW)); + + return NtGdiCreateColorSpace(&lcpeexw); +} + +/* + * @implemented + */ +HCOLORSPACE +STDCALL +CreateColorSpaceW( + LPLOGCOLORSPACEW lplcpw + ) +{ + return IntCreateColorSpaceW(lplcpw, FALSE); +} + + +/* + * @implemented + */ +HCOLORSPACE +STDCALL +CreateColorSpaceA( + LPLOGCOLORSPACEA lplcpa + ) +{ + LOGCOLORSPACEW lcpw; + + if ((lplcpa->lcsSignature != LCS_SIGNATURE) || + (lplcpa->lcsVersion != 0x400) || + (lplcpa->lcsSize != sizeof(LOGCOLORSPACEA))) + { + SetLastError(ERROR_INVALID_COLORSPACE); + return NULL; + } + + lcpw.lcsSignature = lplcpa->lcsSignature; + lcpw.lcsVersion = lplcpa->lcsVersion; + lcpw.lcsSize = sizeof(LOGCOLORSPACEW); + lcpw.lcsCSType = lplcpa->lcsCSType; + lcpw.lcsIntent = lplcpa->lcsIntent; + lcpw.lcsEndpoints = lplcpa->lcsEndpoints; + lcpw.lcsGammaRed = lplcpa->lcsGammaRed; + lcpw.lcsGammaGreen = lplcpa->lcsGammaGreen; + lcpw.lcsGammaBlue = lplcpa->lcsGammaBlue; + + RtlMultiByteToUnicodeN( lcpw.lcsFilename, + MAX_PATH, + NULL, + lplcpa->lcsFilename, + strlen(lplcpa->lcsFilename) + 1); + + return IntCreateColorSpaceW(&lcpw, FALSE); +} + +/* + * @implemented + */ +HCOLORSPACE +STDCALL +GetColorSpace(HDC hDC) +{ + PDC_ATTR pDc_Attr; + + if (!GdiGetHandleUserData(hDC, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr)) + { + SetLastError(ERROR_INVALID_HANDLE); + return NULL; + } + return pDc_Attr->hColorSpace; +} + + +/* + * @implemented + */ +HCOLORSPACE +STDCALL +SetColorSpace( + HDC hDC, + HCOLORSPACE hCS + ) +{ + HCOLORSPACE rhCS = GetColorSpace(hDC); + + if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_DC) + { + if (NtGdiSetColorSpace(hDC, hCS)) return rhCS; + } +#if 0 + if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_METADC) + { + PLDC pLDC = GdiGetLDC(hDC); + if ( !pLDC ) + { + SetLastError(ERROR_INVALID_HANDLE); + return NULL; + } + if (pLDC->iType == LDC_EMFLDC) + { + return NULL; + } + } +#endif + return NULL; +} + diff --git a/reactos/include/psdk/wingdi.h b/reactos/include/psdk/wingdi.h index 8113b5448db..02447336492 100644 --- a/reactos/include/psdk/wingdi.h +++ b/reactos/include/psdk/wingdi.h @@ -966,6 +966,10 @@ extern "C" { #define LCS_GM_BUSINESS 1 #define LCS_GM_GRAPHICS 2 #define LCS_GM_IMAGES 4 +#define LCS_GM_ABS_COLORIMETRIC 8 +#define LCS_SIGNATURE 0x50534F43 // 'PSOC' +#define LCS_sRGB 'sRGB' +#define LCS_WINDOWS_COLOR_SPACE 'Win ' #define RASTER_FONTTYPE 1 #define DEVICE_FONTTYPE 2 #define TRUETYPE_FONTTYPE 4 diff --git a/reactos/subsystems/win32/win32k/include/color.h b/reactos/subsystems/win32/win32k/include/color.h index f8b49122c31..0489217ea6b 100644 --- a/reactos/subsystems/win32/win32k/include/color.h +++ b/reactos/subsystems/win32/win32k/include/color.h @@ -10,10 +10,29 @@ #define NB_RESERVED_COLORS 20 /* number of fixed colors in system palette */ +typedef struct _COLORSPACE +{ + BASEOBJECT BaseObject; + LOGCOLORSPACEW lcsColorSpace; + DWORD dwFlags; +} COLORSPACE, *PCOLORSPACE; + + +#define COLORSPACEOBJ_AllocCS() ((PCOLORSPACE) GDIOBJ_AllocObj(GDIObjType_ICMLCS_TYPE)) +#define COLORSPACEOBJ_AllocCSWithHandle() ((PCOLORSPACE) GDIOBJ_AllocObjWithHandle (GDI_OBJECT_TYPE_COLORSPACE)) +#define COLORSPACEOBJ_FreeCS(pCS) GDIOBJ_FreeObj((POBJ)pCS, GDIObjType_ICMLCS_TYPE) +#define COLORSPACEOBJ_FreeCSByHandle(hCS) GDIOBJ_FreeObjByHandle((HGDIOBJ)hCS, GDI_OBJECT_TYPE_COLORSPACE) +#define COLORSPACEOBJ_LockCS(hCS) ((PCOLORSPACE)GDIOBJ_LockObj((HGDIOBJ)hCS, GDI_OBJECT_TYPE_COLORSPACE)) +#define COLORSPACEOBJ_UnlockCS(pCS) GDIOBJ_UnlockObjByPtr((POBJ)pCS) + +extern HCOLORSPACE hStockColorSpace; + const PALETTEENTRY* FASTCALL COLOR_GetSystemPaletteTemplate (VOID); COLORREF STDCALL COLOR_LookupNearestColor (PALETTEENTRY* palPalEntry, INT size, COLORREF color); INT STDCALL COLOR_PaletteLookupExactIndex (PALETTEENTRY* palPalEntry, INT size, COLORREF col); INT STDCALL COLOR_PaletteLookupPixel(PALETTEENTRY *palPalEntry, INT size, XLATEOBJ *XlateObj, COLORREF col, BOOL skipReserved); UINT FASTCALL IntGdiRealizePalette (HDC); +HCOLORSPACE FASTCALL IntGdiCreateColorSpace(PLOGCOLORSPACEEXW); +BOOL FASTCALL IntGdiDeleteColorSpace(HCOLORSPACE); #endif /* _WIN32K_COLOR_H */ diff --git a/reactos/subsystems/win32/win32k/objects/gdiobj.c b/reactos/subsystems/win32/win32k/objects/gdiobj.c index b386bf199c9..3aa4ff0a1f0 100644 --- a/reactos/subsystems/win32/win32k/objects/gdiobj.c +++ b/reactos/subsystems/win32/win32k/objects/gdiobj.c @@ -59,7 +59,7 @@ OBJ_TYPE_INFO ObjTypeInfo[] = {0, sizeof(DC), TAG_CLIENTOBJ, GDI_CleanupDummy}, /* 06 CLIENTOBJ: METADC,... FIXME: don't use DC struct */ {0, 0, TAG_PATH, NULL}, /* 07 PATH, unused */ {1, sizeof(PALGDI), TAG_PALETTE, PALETTE_Cleanup}, /* 08 PAL */ - {0, 0, TAG_ICMLCS, NULL}, /* 09 ICMLCS, unused */ + {1, sizeof(COLORSPACE), TAG_ICMLCS, GDI_CleanupDummy}, /* 09 ICMLCS, unused */ {1, sizeof(TEXTOBJ), TAG_LFONT, GDI_CleanupDummy}, /* 0a LFONT */ {0, 0, TAG_RFONT, NULL}, /* 0b RFONT, unused */ {0, 0, TAG_PFE, NULL}, /* 0c PFE, unused */ diff --git a/reactos/subsystems/win32/win32k/objects/icm.c b/reactos/subsystems/win32/win32k/objects/icm.c index e583380abdf..30fdeb21643 100644 --- a/reactos/subsystems/win32/win32k/objects/icm.c +++ b/reactos/subsystems/win32/win32k/objects/icm.c @@ -16,20 +16,75 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id$ */ #include #define NDEBUG #include +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 +FASTCALL +IntGdiDeleteColorSpace( + HCOLORSPACE hColorSpace) +{ + BOOL Ret = FALSE; + + if ( hColorSpace != hStockColorSpace ) + { + Ret = COLORSPACEOBJ_FreeCSByHandle(hColorSpace); + if ( !Ret ) SetLastWin32Error(ERROR_INVALID_PARAMETER); + } + return Ret; +} + HANDLE APIENTRY NtGdiCreateColorSpace( IN PLOGCOLORSPACEEXW pLogColorSpace) { - UNIMPLEMENTED; - return 0; + LOGCOLORSPACEEXW Safelcs; + NTSTATUS Status = STATUS_SUCCESS; + + _SEH_TRY + { + ProbeForRead( pLogColorSpace, + sizeof(LOGCOLORSPACEEXW), + 1); + RtlCopyMemory(&Safelcs, pLogColorSpace, sizeof(LOGCOLORSPACEEXW)); + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return NULL; + } + return IntGdiCreateColorSpace(&Safelcs); } BOOL @@ -37,8 +92,7 @@ APIENTRY NtGdiDeleteColorSpace( IN HANDLE hColorSpace) { - UNIMPLEMENTED; - return FALSE; + return IntGdiDeleteColorSpace(hColorSpace); } BOOL @@ -136,8 +190,43 @@ STDCALL NtGdiSetColorSpace(IN HDC hdc, IN HCOLORSPACE hColorSpace) { - UNIMPLEMENTED; - return 0; + PDC pDC; + PDC_ATTR pDc_Attr; + PCOLORSPACE pCS; + + pDC = DC_LockDc(hdc); + if (!pDC) + { + SetLastWin32Error(ERROR_INVALID_HANDLE); + return FALSE; + } + pDc_Attr = pDC->pDc_Attr; + if(!pDc_Attr) pDc_Attr = &pDC->Dc_Attr; + + if (pDc_Attr->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; + pDc_Attr->hColorSpace = hColorSpace; + + COLORSPACEOBJ_UnlockCS(pCS); + DC_UnlockDc(pDC); + return TRUE; } BOOL