Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

365 lines
9.4 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. scheme.c
  5. Abstract:
  6. Control Panel scheme converters
  7. The helper functions in this source file converts an ANSI-
  8. based Win95 scheme into a UNICODE-based NT scheme. Also
  9. supplied is a logical font converter, closely related
  10. to the scheme converter.
  11. Author:
  12. Jim Schmidt (jimschm) 9-Aug-1996
  13. Revision History:
  14. --*/
  15. #include "pch.h"
  16. #define COLOR_MAX_V1 25
  17. #define COLOR_MAX_V3 25
  18. #define COLOR_MAX_V4 29
  19. #define COLOR_MAX_NT 29 // this is a modified version 2 format, similar to 4
  20. //
  21. // Win95 uses a mix of LOGFONTA and a weird 16-bit LOGFONT
  22. // structure that uses SHORTs instead of LONGs.
  23. //
  24. typedef struct {
  25. SHORT lfHeight;
  26. SHORT lfWidth;
  27. SHORT lfEscapement;
  28. SHORT lfOrientation;
  29. SHORT lfWeight;
  30. BYTE lfItalic;
  31. BYTE lfUnderline;
  32. BYTE lfStrikeOut;
  33. BYTE lfCharSet;
  34. BYTE lfOutPrecision;
  35. BYTE lfClipPrecision;
  36. BYTE lfQuality;
  37. BYTE lfPitchAndFamily;
  38. char lfFaceName[LF_FACESIZE];
  39. } SHORT_LOGFONT, *PSHORT_LOGFONT;
  40. //
  41. // NT uses only UNICODE structures, and pads the members
  42. // to 32-bit boundaries.
  43. //
  44. typedef struct {
  45. SHORT version; // 2 for NT UNICODE
  46. WORD wDummy; // for alignment
  47. NONCLIENTMETRICSW ncm;
  48. LOGFONTW lfIconTitle;
  49. COLORREF rgb[COLOR_MAX_NT];
  50. } SCHEMEDATA_NT, *PSCHEMEDATA_NT;
  51. //
  52. // Win95 uses NONCLIENTMETRICSA which has LOGFONTA members,
  53. // but it uses a 16-bit LOGFONT as well.
  54. //
  55. #pragma pack(push)
  56. #pragma pack(1)
  57. typedef struct {
  58. SHORT version; // 1 for Win95 ANSI
  59. NONCLIENTMETRICSA ncm;
  60. SHORT_LOGFONT lfIconTitle;
  61. COLORREF rgb[COLOR_MAX_V1];
  62. } SCHEMEDATA_V1, *PSCHEMEDATA_V1;
  63. typedef struct {
  64. SHORT version; // 1 for Win95 ANSI
  65. NONCLIENTMETRICSA ncm;
  66. SHORT_LOGFONT lfIconTitle;
  67. COLORREF rgb[COLOR_MAX_V4];
  68. } SCHEMEDATA_V1A, *PSCHEMEDATA_V1A;
  69. typedef struct {
  70. SHORT version; // 3 for Win98 ANSI, 4 for portable format
  71. WORD Dummy;
  72. NONCLIENTMETRICSA ncm;
  73. LOGFONTA lfIconTitle;
  74. COLORREF rgb[COLOR_MAX_V3];
  75. } SCHEMEDATA_V3, *PSCHEMEDATA_V3;
  76. typedef struct {
  77. SHORT version; // 4 for Win32 format (whatever that means)
  78. WORD Dummy;
  79. NONCLIENTMETRICSA ncm;
  80. LOGFONTA lfIconTitle;
  81. COLORREF rgb[COLOR_MAX_V4];
  82. } SCHEMEDATA_V4, *PSCHEMEDATA_V4;
  83. #pragma pack(pop)
  84. //
  85. // Some utility functions
  86. //
  87. void
  88. ConvertLF (LOGFONTW *plfDest, const LOGFONTA *plfSrc)
  89. {
  90. plfDest->lfHeight = plfSrc->lfHeight;
  91. plfDest->lfWidth = plfSrc->lfWidth;
  92. plfDest->lfEscapement = plfSrc->lfEscapement;
  93. plfDest->lfOrientation = plfSrc->lfOrientation;
  94. plfDest->lfWeight = plfSrc->lfWeight;
  95. plfDest->lfItalic = plfSrc->lfItalic;
  96. plfDest->lfUnderline = plfSrc->lfUnderline;
  97. plfDest->lfStrikeOut = plfSrc->lfStrikeOut;
  98. plfDest->lfCharSet = plfSrc->lfCharSet;
  99. plfDest->lfOutPrecision = plfSrc->lfOutPrecision;
  100. plfDest->lfClipPrecision = plfSrc->lfClipPrecision;
  101. plfDest->lfQuality = plfSrc->lfQuality;
  102. plfDest->lfPitchAndFamily = plfSrc->lfPitchAndFamily;
  103. MultiByteToWideChar (OurGetACP(),
  104. 0,
  105. plfSrc->lfFaceName,
  106. -1,
  107. plfDest->lfFaceName,
  108. sizeof (plfDest->lfFaceName) / sizeof (WCHAR));
  109. }
  110. void
  111. ConvertLFShort (LOGFONTW *plfDest, const SHORT_LOGFONT *plfSrc)
  112. {
  113. plfDest->lfHeight = plfSrc->lfHeight;
  114. plfDest->lfWidth = plfSrc->lfWidth;
  115. plfDest->lfEscapement = plfSrc->lfEscapement;
  116. plfDest->lfOrientation = plfSrc->lfOrientation;
  117. plfDest->lfWeight = plfSrc->lfWeight;
  118. plfDest->lfItalic = plfSrc->lfItalic;
  119. plfDest->lfUnderline = plfSrc->lfUnderline;
  120. plfDest->lfStrikeOut = plfSrc->lfStrikeOut;
  121. plfDest->lfCharSet = plfSrc->lfCharSet;
  122. plfDest->lfOutPrecision = plfSrc->lfOutPrecision;
  123. plfDest->lfClipPrecision = plfSrc->lfClipPrecision;
  124. plfDest->lfQuality = plfSrc->lfQuality;
  125. plfDest->lfPitchAndFamily = plfSrc->lfPitchAndFamily;
  126. MultiByteToWideChar (OurGetACP(),
  127. 0,
  128. plfSrc->lfFaceName,
  129. -1,
  130. plfDest->lfFaceName,
  131. sizeof (plfDest->lfFaceName) / sizeof (WCHAR));
  132. }
  133. VOID
  134. ConvertNonClientMetrics (
  135. OUT NONCLIENTMETRICSW *Dest,
  136. IN NONCLIENTMETRICSA *Src
  137. )
  138. {
  139. Dest->cbSize = sizeof (NONCLIENTMETRICSW);
  140. Dest->iBorderWidth = Src->iBorderWidth;
  141. Dest->iScrollWidth = Src->iScrollWidth;
  142. Dest->iScrollHeight = Src->iScrollHeight;
  143. Dest->iCaptionWidth = Src->iCaptionWidth;
  144. Dest->iCaptionHeight = Src->iCaptionHeight;
  145. Dest->iSmCaptionWidth = Src->iSmCaptionWidth;
  146. Dest->iSmCaptionHeight = Src->iSmCaptionHeight;
  147. Dest->iMenuWidth = Src->iMenuWidth;
  148. Dest->iMenuHeight = Src->iMenuHeight;
  149. ConvertLF (&Dest->lfCaptionFont, &Src->lfCaptionFont);
  150. ConvertLF (&Dest->lfSmCaptionFont, &Src->lfSmCaptionFont);
  151. ConvertLF (&Dest->lfMenuFont, &Src->lfMenuFont);
  152. ConvertLF (&Dest->lfStatusFont, &Src->lfStatusFont);
  153. ConvertLF (&Dest->lfMessageFont, &Src->lfMessageFont);
  154. }
  155. //
  156. // And now the scheme converter
  157. //
  158. BOOL
  159. ValFn_ConvertAppearanceScheme (
  160. IN PDATAOBJECT ObPtr
  161. )
  162. {
  163. SCHEMEDATA_NT sd_nt;
  164. PSCHEMEDATA_V1 psd_v1;
  165. PSCHEMEDATA_V3 psd_v3;
  166. PSCHEMEDATA_V4 psd_v4;
  167. PSCHEMEDATA_V1A psd_v1a;
  168. BOOL Copy3dValues = FALSE;
  169. psd_v1 = (PSCHEMEDATA_V1) ObPtr->Value.Buffer;
  170. //
  171. // Validate the size (must be a known size)
  172. //
  173. if (ObPtr->Value.Size != sizeof (SCHEMEDATA_V1) &&
  174. ObPtr->Value.Size != sizeof (SCHEMEDATA_V3) &&
  175. ObPtr->Value.Size != sizeof (SCHEMEDATA_V4) &&
  176. ObPtr->Value.Size != sizeof (SCHEMEDATA_V1A)
  177. ) {
  178. DEBUGMSG ((
  179. DBG_WARNING,
  180. "ValFn_ConvertAppearanceScheme doesn't support scheme size of %u bytes. "
  181. "The supported sizes are %u, %u, %u, and %u.",
  182. ObPtr->Value.Size,
  183. sizeof (SCHEMEDATA_V1),
  184. sizeof (SCHEMEDATA_V1A),
  185. sizeof (SCHEMEDATA_V3),
  186. sizeof (SCHEMEDATA_V4)
  187. ));
  188. return TRUE;
  189. }
  190. //
  191. // Make sure the structure is a known version
  192. //
  193. if (psd_v1->version != 1 && psd_v1->version != 3 && psd_v1->version != 4) {
  194. DEBUGMSG ((
  195. DBG_WARNING,
  196. "ValFn_ConvertAppearanceScheme doesn't support version %u",
  197. psd_v1->version
  198. ));
  199. return TRUE;
  200. }
  201. //
  202. // Convert the structure
  203. //
  204. if (psd_v1->version == 1) {
  205. sd_nt.version = 2;
  206. ConvertNonClientMetrics (&sd_nt.ncm, &psd_v1->ncm);
  207. ConvertLFShort (&sd_nt.lfIconTitle, &psd_v1->lfIconTitle);
  208. ZeroMemory (sd_nt.rgb, sizeof (sd_nt.rgb));
  209. CopyMemory (
  210. &sd_nt.rgb,
  211. &psd_v1->rgb,
  212. min (sizeof (psd_v1->rgb), sizeof (sd_nt.rgb))
  213. );
  214. Copy3dValues = TRUE;
  215. } else if (psd_v1->version == 3 && ObPtr->Value.Size == sizeof (SCHEMEDATA_V1A)) {
  216. psd_v1a = (PSCHEMEDATA_V1A) psd_v1;
  217. sd_nt.version = 2;
  218. ConvertNonClientMetrics (&sd_nt.ncm, &psd_v1a->ncm);
  219. ConvertLFShort (&sd_nt.lfIconTitle, &psd_v1a->lfIconTitle);
  220. ZeroMemory (sd_nt.rgb, sizeof (sd_nt.rgb));
  221. CopyMemory (
  222. &sd_nt.rgb,
  223. &psd_v1a->rgb,
  224. min (sizeof (psd_v1a->rgb), sizeof (sd_nt.rgb))
  225. );
  226. Copy3dValues = TRUE;
  227. } else if (psd_v1->version == 3 && ObPtr->Value.Size == sizeof (SCHEMEDATA_V3)) {
  228. psd_v3 = (PSCHEMEDATA_V3) psd_v1;
  229. sd_nt.version = 2;
  230. ConvertNonClientMetrics (&sd_nt.ncm, &psd_v3->ncm);
  231. ConvertLF (&sd_nt.lfIconTitle, &psd_v3->lfIconTitle);
  232. ZeroMemory (sd_nt.rgb, sizeof (sd_nt.rgb));
  233. CopyMemory (
  234. &sd_nt.rgb,
  235. &psd_v3->rgb,
  236. min (sizeof (psd_v3->rgb), sizeof (sd_nt.rgb))
  237. );
  238. Copy3dValues = TRUE;
  239. } else if (psd_v1->version == 4) {
  240. psd_v4 = (PSCHEMEDATA_V4) psd_v1;
  241. sd_nt.version = 2;
  242. ConvertNonClientMetrics (&sd_nt.ncm, &psd_v4->ncm);
  243. ConvertLF (&sd_nt.lfIconTitle, &psd_v4->lfIconTitle);
  244. ZeroMemory (sd_nt.rgb, sizeof (sd_nt.rgb));
  245. CopyMemory (
  246. &sd_nt.rgb,
  247. &psd_v4->rgb,
  248. min (sizeof (psd_v4->rgb), sizeof (sd_nt.rgb))
  249. );
  250. } else {
  251. // not a possible case
  252. MYASSERT (FALSE);
  253. }
  254. if (Copy3dValues) {
  255. //
  256. // Make sure the NT structure has values for 3D colors
  257. //
  258. sd_nt.rgb[COLOR_HOTLIGHT] = sd_nt.rgb[COLOR_ACTIVECAPTION];
  259. sd_nt.rgb[COLOR_GRADIENTACTIVECAPTION] = sd_nt.rgb[COLOR_ACTIVECAPTION];
  260. sd_nt.rgb[COLOR_GRADIENTINACTIVECAPTION] = sd_nt.rgb[COLOR_INACTIVECAPTION];
  261. }
  262. return ReplaceValue (ObPtr, (LPBYTE) &sd_nt, sizeof (sd_nt));
  263. }
  264. //
  265. // And logfont converter
  266. //
  267. BOOL
  268. ValFn_ConvertLogFont (
  269. IN PDATAOBJECT ObPtr
  270. )
  271. {
  272. LOGFONTW lfNT;
  273. PSHORT_LOGFONT plf95;
  274. plf95 = (PSHORT_LOGFONT) ObPtr->Value.Buffer;
  275. if (ObPtr->Value.Size != sizeof (SHORT_LOGFONT)) {
  276. SetLastError (ERROR_SUCCESS);
  277. DEBUGMSG ((
  278. DBG_NAUSEA,
  279. "ValFn_ConvertLogFont skipped because data wasn't the right size. "
  280. "%u bytes, should be %u",
  281. ObPtr->Value.Size,
  282. sizeof (SHORT_LOGFONT)
  283. ));
  284. return FALSE;
  285. }
  286. ConvertLFShort (&lfNT, plf95);
  287. return ReplaceValue (ObPtr, (LPBYTE) &lfNT, sizeof (lfNT));
  288. }