windows-nt/Source/XPSP1/NT/base/ntsetup/win95upg/w95upgnt/rulehlpr/scheme.c
2020-09-26 16:20:57 +08:00

366 lines
9.4 KiB
C

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
scheme.c
Abstract:
Control Panel scheme converters
The helper functions in this source file converts an ANSI-
based Win95 scheme into a UNICODE-based NT scheme. Also
supplied is a logical font converter, closely related
to the scheme converter.
Author:
Jim Schmidt (jimschm) 9-Aug-1996
Revision History:
--*/
#include "pch.h"
#define COLOR_MAX_V1 25
#define COLOR_MAX_V3 25
#define COLOR_MAX_V4 29
#define COLOR_MAX_NT 29 // this is a modified version 2 format, similar to 4
//
// Win95 uses a mix of LOGFONTA and a weird 16-bit LOGFONT
// structure that uses SHORTs instead of LONGs.
//
typedef struct {
SHORT lfHeight;
SHORT lfWidth;
SHORT lfEscapement;
SHORT lfOrientation;
SHORT lfWeight;
BYTE lfItalic;
BYTE lfUnderline;
BYTE lfStrikeOut;
BYTE lfCharSet;
BYTE lfOutPrecision;
BYTE lfClipPrecision;
BYTE lfQuality;
BYTE lfPitchAndFamily;
char lfFaceName[LF_FACESIZE];
} SHORT_LOGFONT, *PSHORT_LOGFONT;
//
// NT uses only UNICODE structures, and pads the members
// to 32-bit boundaries.
//
typedef struct {
SHORT version; // 2 for NT UNICODE
WORD wDummy; // for alignment
NONCLIENTMETRICSW ncm;
LOGFONTW lfIconTitle;
COLORREF rgb[COLOR_MAX_NT];
} SCHEMEDATA_NT, *PSCHEMEDATA_NT;
//
// Win95 uses NONCLIENTMETRICSA which has LOGFONTA members,
// but it uses a 16-bit LOGFONT as well.
//
#pragma pack(push)
#pragma pack(1)
typedef struct {
SHORT version; // 1 for Win95 ANSI
NONCLIENTMETRICSA ncm;
SHORT_LOGFONT lfIconTitle;
COLORREF rgb[COLOR_MAX_V1];
} SCHEMEDATA_V1, *PSCHEMEDATA_V1;
typedef struct {
SHORT version; // 1 for Win95 ANSI
NONCLIENTMETRICSA ncm;
SHORT_LOGFONT lfIconTitle;
COLORREF rgb[COLOR_MAX_V4];
} SCHEMEDATA_V1A, *PSCHEMEDATA_V1A;
typedef struct {
SHORT version; // 3 for Win98 ANSI, 4 for portable format
WORD Dummy;
NONCLIENTMETRICSA ncm;
LOGFONTA lfIconTitle;
COLORREF rgb[COLOR_MAX_V3];
} SCHEMEDATA_V3, *PSCHEMEDATA_V3;
typedef struct {
SHORT version; // 4 for Win32 format (whatever that means)
WORD Dummy;
NONCLIENTMETRICSA ncm;
LOGFONTA lfIconTitle;
COLORREF rgb[COLOR_MAX_V4];
} SCHEMEDATA_V4, *PSCHEMEDATA_V4;
#pragma pack(pop)
//
// Some utility functions
//
void
ConvertLF (LOGFONTW *plfDest, const LOGFONTA *plfSrc)
{
plfDest->lfHeight = plfSrc->lfHeight;
plfDest->lfWidth = plfSrc->lfWidth;
plfDest->lfEscapement = plfSrc->lfEscapement;
plfDest->lfOrientation = plfSrc->lfOrientation;
plfDest->lfWeight = plfSrc->lfWeight;
plfDest->lfItalic = plfSrc->lfItalic;
plfDest->lfUnderline = plfSrc->lfUnderline;
plfDest->lfStrikeOut = plfSrc->lfStrikeOut;
plfDest->lfCharSet = plfSrc->lfCharSet;
plfDest->lfOutPrecision = plfSrc->lfOutPrecision;
plfDest->lfClipPrecision = plfSrc->lfClipPrecision;
plfDest->lfQuality = plfSrc->lfQuality;
plfDest->lfPitchAndFamily = plfSrc->lfPitchAndFamily;
MultiByteToWideChar (OurGetACP(),
0,
plfSrc->lfFaceName,
-1,
plfDest->lfFaceName,
sizeof (plfDest->lfFaceName) / sizeof (WCHAR));
}
void
ConvertLFShort (LOGFONTW *plfDest, const SHORT_LOGFONT *plfSrc)
{
plfDest->lfHeight = plfSrc->lfHeight;
plfDest->lfWidth = plfSrc->lfWidth;
plfDest->lfEscapement = plfSrc->lfEscapement;
plfDest->lfOrientation = plfSrc->lfOrientation;
plfDest->lfWeight = plfSrc->lfWeight;
plfDest->lfItalic = plfSrc->lfItalic;
plfDest->lfUnderline = plfSrc->lfUnderline;
plfDest->lfStrikeOut = plfSrc->lfStrikeOut;
plfDest->lfCharSet = plfSrc->lfCharSet;
plfDest->lfOutPrecision = plfSrc->lfOutPrecision;
plfDest->lfClipPrecision = plfSrc->lfClipPrecision;
plfDest->lfQuality = plfSrc->lfQuality;
plfDest->lfPitchAndFamily = plfSrc->lfPitchAndFamily;
MultiByteToWideChar (OurGetACP(),
0,
plfSrc->lfFaceName,
-1,
plfDest->lfFaceName,
sizeof (plfDest->lfFaceName) / sizeof (WCHAR));
}
VOID
ConvertNonClientMetrics (
OUT NONCLIENTMETRICSW *Dest,
IN NONCLIENTMETRICSA *Src
)
{
Dest->cbSize = sizeof (NONCLIENTMETRICSW);
Dest->iBorderWidth = Src->iBorderWidth;
Dest->iScrollWidth = Src->iScrollWidth;
Dest->iScrollHeight = Src->iScrollHeight;
Dest->iCaptionWidth = Src->iCaptionWidth;
Dest->iCaptionHeight = Src->iCaptionHeight;
Dest->iSmCaptionWidth = Src->iSmCaptionWidth;
Dest->iSmCaptionHeight = Src->iSmCaptionHeight;
Dest->iMenuWidth = Src->iMenuWidth;
Dest->iMenuHeight = Src->iMenuHeight;
ConvertLF (&Dest->lfCaptionFont, &Src->lfCaptionFont);
ConvertLF (&Dest->lfSmCaptionFont, &Src->lfSmCaptionFont);
ConvertLF (&Dest->lfMenuFont, &Src->lfMenuFont);
ConvertLF (&Dest->lfStatusFont, &Src->lfStatusFont);
ConvertLF (&Dest->lfMessageFont, &Src->lfMessageFont);
}
//
// And now the scheme converter
//
BOOL
ValFn_ConvertAppearanceScheme (
IN PDATAOBJECT ObPtr
)
{
SCHEMEDATA_NT sd_nt;
PSCHEMEDATA_V1 psd_v1;
PSCHEMEDATA_V3 psd_v3;
PSCHEMEDATA_V4 psd_v4;
PSCHEMEDATA_V1A psd_v1a;
BOOL Copy3dValues = FALSE;
psd_v1 = (PSCHEMEDATA_V1) ObPtr->Value.Buffer;
//
// Validate the size (must be a known size)
//
if (ObPtr->Value.Size != sizeof (SCHEMEDATA_V1) &&
ObPtr->Value.Size != sizeof (SCHEMEDATA_V3) &&
ObPtr->Value.Size != sizeof (SCHEMEDATA_V4) &&
ObPtr->Value.Size != sizeof (SCHEMEDATA_V1A)
) {
DEBUGMSG ((
DBG_WARNING,
"ValFn_ConvertAppearanceScheme doesn't support scheme size of %u bytes. "
"The supported sizes are %u, %u, %u, and %u.",
ObPtr->Value.Size,
sizeof (SCHEMEDATA_V1),
sizeof (SCHEMEDATA_V1A),
sizeof (SCHEMEDATA_V3),
sizeof (SCHEMEDATA_V4)
));
return TRUE;
}
//
// Make sure the structure is a known version
//
if (psd_v1->version != 1 && psd_v1->version != 3 && psd_v1->version != 4) {
DEBUGMSG ((
DBG_WARNING,
"ValFn_ConvertAppearanceScheme doesn't support version %u",
psd_v1->version
));
return TRUE;
}
//
// Convert the structure
//
if (psd_v1->version == 1) {
sd_nt.version = 2;
ConvertNonClientMetrics (&sd_nt.ncm, &psd_v1->ncm);
ConvertLFShort (&sd_nt.lfIconTitle, &psd_v1->lfIconTitle);
ZeroMemory (sd_nt.rgb, sizeof (sd_nt.rgb));
CopyMemory (
&sd_nt.rgb,
&psd_v1->rgb,
min (sizeof (psd_v1->rgb), sizeof (sd_nt.rgb))
);
Copy3dValues = TRUE;
} else if (psd_v1->version == 3 && ObPtr->Value.Size == sizeof (SCHEMEDATA_V1A)) {
psd_v1a = (PSCHEMEDATA_V1A) psd_v1;
sd_nt.version = 2;
ConvertNonClientMetrics (&sd_nt.ncm, &psd_v1a->ncm);
ConvertLFShort (&sd_nt.lfIconTitle, &psd_v1a->lfIconTitle);
ZeroMemory (sd_nt.rgb, sizeof (sd_nt.rgb));
CopyMemory (
&sd_nt.rgb,
&psd_v1a->rgb,
min (sizeof (psd_v1a->rgb), sizeof (sd_nt.rgb))
);
Copy3dValues = TRUE;
} else if (psd_v1->version == 3 && ObPtr->Value.Size == sizeof (SCHEMEDATA_V3)) {
psd_v3 = (PSCHEMEDATA_V3) psd_v1;
sd_nt.version = 2;
ConvertNonClientMetrics (&sd_nt.ncm, &psd_v3->ncm);
ConvertLF (&sd_nt.lfIconTitle, &psd_v3->lfIconTitle);
ZeroMemory (sd_nt.rgb, sizeof (sd_nt.rgb));
CopyMemory (
&sd_nt.rgb,
&psd_v3->rgb,
min (sizeof (psd_v3->rgb), sizeof (sd_nt.rgb))
);
Copy3dValues = TRUE;
} else if (psd_v1->version == 4) {
psd_v4 = (PSCHEMEDATA_V4) psd_v1;
sd_nt.version = 2;
ConvertNonClientMetrics (&sd_nt.ncm, &psd_v4->ncm);
ConvertLF (&sd_nt.lfIconTitle, &psd_v4->lfIconTitle);
ZeroMemory (sd_nt.rgb, sizeof (sd_nt.rgb));
CopyMemory (
&sd_nt.rgb,
&psd_v4->rgb,
min (sizeof (psd_v4->rgb), sizeof (sd_nt.rgb))
);
} else {
// not a possible case
MYASSERT (FALSE);
}
if (Copy3dValues) {
//
// Make sure the NT structure has values for 3D colors
//
sd_nt.rgb[COLOR_HOTLIGHT] = sd_nt.rgb[COLOR_ACTIVECAPTION];
sd_nt.rgb[COLOR_GRADIENTACTIVECAPTION] = sd_nt.rgb[COLOR_ACTIVECAPTION];
sd_nt.rgb[COLOR_GRADIENTINACTIVECAPTION] = sd_nt.rgb[COLOR_INACTIVECAPTION];
}
return ReplaceValue (ObPtr, (LPBYTE) &sd_nt, sizeof (sd_nt));
}
//
// And logfont converter
//
BOOL
ValFn_ConvertLogFont (
IN PDATAOBJECT ObPtr
)
{
LOGFONTW lfNT;
PSHORT_LOGFONT plf95;
plf95 = (PSHORT_LOGFONT) ObPtr->Value.Buffer;
if (ObPtr->Value.Size != sizeof (SHORT_LOGFONT)) {
SetLastError (ERROR_SUCCESS);
DEBUGMSG ((
DBG_NAUSEA,
"ValFn_ConvertLogFont skipped because data wasn't the right size. "
"%u bytes, should be %u",
ObPtr->Value.Size,
sizeof (SHORT_LOGFONT)
));
return FALSE;
}
ConvertLFShort (&lfNT, plf95);
return ReplaceValue (ObPtr, (LPBYTE) &lfNT, sizeof (lfNT));
}