/** @file\r
Language settings\r
\r
-Copyright (c) 2004 - 2008, Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
-#include "Language.h"\r
-#include "FrontPage.h"\r
-\r
-#define NARROW_GLYPH_NUMBER 8\r
-#define WIDE_GLYPH_NUMBER 75\r
+#include "Bds.h"\r
+#define ISO_639_2_ENTRY_SIZE 3\r
\r
-EFI_GUID mFontPackageGuid = {\r
- 0x78941450, 0x90ab, 0x4fb1, {0xb7, 0x5f, 0x58, 0x92, 0x14, 0xe2, 0x4a, 0xc}\r
-};\r
+/**\r
+ Check if lang is in supported language codes according to language string.\r
+\r
+ This code is used to check if lang is in in supported language codes. It can handle\r
+ RFC4646 and ISO639 language tags.\r
+ In ISO639 language tags, take 3-characters as a delimitation to find matched string.\r
+ In RFC4646 language tags, take semicolon as a delimitation to find matched string.\r
+\r
+ For example:\r
+ SupportedLang = "engfraengfra"\r
+ Iso639Language = TRUE\r
+ Lang = "eng", the return value is "TRUE", or\r
+ Lang = "chs", the return value is "FALSE".\r
+ Another example:\r
+ SupportedLang = "en;fr;en-US;fr-FR"\r
+ Iso639Language = FALSE\r
+ Lang = "en", the return value is "TRUE", or\r
+ Lang = "zh", the return value is "FALSE".\r
+\r
+ @param SupportedLang Platform supported language codes.\r
+ @param Lang Configured language.\r
+ @param Iso639Language A bool value to signify if the handler is operated on ISO639 or RFC4646.\r
+\r
+ @retval TRUE lang is in supported language codes.\r
+ @retval FALSE lang is not in supported language codes.\r
\r
-typedef struct {\r
- ///\r
- /// This 4-bytes total array length is required by HiiLibPreparePackageList()\r
- ///\r
- UINT32 Length;\r
+**/\r
+BOOLEAN\r
+IsLangInSupportedLangCodes (\r
+ IN CHAR8 *SupportedLang,\r
+ IN CHAR8 *Lang,\r
+ IN BOOLEAN Iso639Language\r
+ )\r
+{\r
+ UINTN Index;\r
+ UINTN CompareLength;\r
+ UINTN LanguageLength;\r
+\r
+ if (Iso639Language) {\r
+ CompareLength = ISO_639_2_ENTRY_SIZE;\r
+ for (Index = 0; Index < AsciiStrLen (SupportedLang); Index += CompareLength) {\r
+ if (AsciiStrnCmp (Lang, SupportedLang + Index, CompareLength) == 0) {\r
+ //\r
+ // Successfully find the Lang string in SupportedLang string.\r
+ //\r
+ return TRUE;\r
+ }\r
+ }\r
\r
- //\r
- // This is the Font package definition\r
- //\r
- EFI_HII_PACKAGE_HEADER Header;\r
- UINT16 NumberOfNarrowGlyphs;\r
- UINT16 NumberOfWideGlyphs;\r
- EFI_NARROW_GLYPH NarrowArray[NARROW_GLYPH_NUMBER];\r
- EFI_WIDE_GLYPH WideArray[WIDE_GLYPH_NUMBER];\r
-} FONT_PACK_BIN;\r
+ return FALSE;\r
+ } else {\r
+ //\r
+ // Compare RFC4646 language code\r
+ //\r
+ for (LanguageLength = 0; Lang[LanguageLength] != '\0'; LanguageLength++) {\r
+ }\r
\r
-FONT_PACK_BIN mFontBin = {\r
- sizeof (FONT_PACK_BIN),\r
- {\r
- sizeof (FONT_PACK_BIN) - sizeof (UINT32),\r
- EFI_HII_PACKAGE_SIMPLE_FONTS,\r
- },\r
- NARROW_GLYPH_NUMBER,\r
- 0,\r
- { // Narrow Glyphs\r
- {\r
- 0x05d0,\r
- 0x00,\r
- {\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x4E,\r
- 0x6E,\r
- 0x62,\r
- 0x32,\r
- 0x32,\r
- 0x3C,\r
- 0x68,\r
- 0x4C,\r
- 0x4C,\r
- 0x46,\r
- 0x76,\r
- 0x72,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00\r
- }\r
- },\r
- {\r
- 0x05d1,\r
- 0x00,\r
- {\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x78,\r
- 0x7C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x7E,\r
- 0x7E,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00\r
- }\r
- },\r
- {\r
- 0x05d2,\r
- 0x00,\r
- {\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x78,\r
- 0x7C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x1C,\r
- 0x3E,\r
- 0x66,\r
- 0x66,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00\r
- }\r
- },\r
- {\r
- 0x05d3,\r
- 0x00,\r
- {\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x7E,\r
- 0x7E,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00\r
- }\r
- },\r
- {\r
- 0x05d4,\r
- 0x00,\r
- {\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x7C,\r
- 0x7E,\r
- 0x06,\r
- 0x06,\r
- 0x06,\r
- 0x06,\r
- 0x66,\r
- 0x66,\r
- 0x66,\r
- 0x66,\r
- 0x66,\r
- 0x66,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00\r
- }\r
- },\r
- {\r
- 0x05d5,\r
- 0x00,\r
- {\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x3C,\r
- 0x3C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x0C,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00\r
+ for ( ; *SupportedLang != '\0'; SupportedLang += CompareLength) {\r
+ //\r
+ // Skip ';' characters in SupportedLang\r
+ //\r
+ for ( ; *SupportedLang != '\0' && *SupportedLang == ';'; SupportedLang++) {\r
}\r
- },\r
- {\r
- 0x05d6,\r
- 0x00,\r
- {\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x38,\r
- 0x38,\r
- 0x1E,\r
- 0x1E,\r
- 0x18,\r
- 0x18,\r
- 0x18,\r
- 0x18,\r
- 0x18,\r
- 0x18,\r
- 0x18,\r
- 0x18,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00\r
+\r
+ //\r
+ // Determine the length of the next language code in SupportedLang\r
+ //\r
+ for (CompareLength = 0; SupportedLang[CompareLength] != '\0' && SupportedLang[CompareLength] != ';'; CompareLength++) {\r
}\r
- },\r
- {\r
- 0x0000,\r
- 0x00,\r
+\r
+ if ((CompareLength == LanguageLength) &&\r
+ (AsciiStrnCmp (Lang, SupportedLang, CompareLength) == 0))\r
{\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00,\r
- 0x00\r
+ //\r
+ // Successfully find the Lang string in SupportedLang string.\r
+ //\r
+ return TRUE;\r
}\r
}\r
+\r
+ return FALSE;\r
}\r
-};\r
+}\r
\r
/**\r
- Routine to export glyphs to the HII database. This is in addition to whatever is defined in the Graphics Console driver.\r
+ Initialize Lang or PlatformLang variable, if Lang or PlatformLang variable is not found,\r
+ or it has been set to an unsupported value(not one of platform supported language codes),\r
+ set the default language code to it.\r
+\r
+ @param LangName Language name, L"Lang" or L"PlatformLang".\r
+ @param SupportedLang Platform supported language codes.\r
+ @param DefaultLang Default language code.\r
+ @param Iso639Language A bool value to signify if the handler is operated on ISO639 or RFC4646,\r
+ TRUE for L"Lang" LangName or FALSE for L"PlatformLang" LangName.\r
\r
**/\r
VOID\r
-ExportFonts (\r
- VOID\r
+InitializeLangVariable (\r
+ IN CHAR16 *LangName,\r
+ IN CHAR8 *SupportedLang,\r
+ IN CHAR8 *DefaultLang,\r
+ IN BOOLEAN Iso639Language\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_HANDLE DriverHandle;\r
- EFI_HII_HANDLE HiiHandle;\r
- EFI_HII_PACKAGE_LIST_HEADER *PackageList;\r
+ CHAR8 *Lang;\r
\r
//\r
- // Create driver handle used by HII database\r
+ // Find current Lang or PlatformLang from EFI Variable.\r
//\r
- Status = HiiLibCreateHiiDriverHandle (&DriverHandle);\r
- if (EFI_ERROR (Status)) {\r
- return ;\r
- }\r
+ GetEfiGlobalVariable2 (LangName, (VOID **)&Lang, NULL);\r
\r
- PackageList = HiiLibPreparePackageList (1, &mFontPackageGuid, &mFontBin);\r
- ASSERT (PackageList != NULL);\r
+ //\r
+ // If Lang or PlatformLang variable is not found,\r
+ // or it has been set to an unsupported value(not one of the supported language codes),\r
+ // set the default language code to it.\r
+ //\r
+ if ((Lang == NULL) || !IsLangInSupportedLangCodes (SupportedLang, Lang, Iso639Language)) {\r
+ //\r
+ // The default language code should be one of the supported language codes.\r
+ //\r
+ ASSERT (IsLangInSupportedLangCodes (SupportedLang, DefaultLang, Iso639Language));\r
+ BdsDxeSetVariableAndReportStatusCodeOnError (\r
+ LangName,\r
+ &gEfiGlobalVariableGuid,\r
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+ AsciiStrSize (DefaultLang),\r
+ DefaultLang\r
+ );\r
+ }\r
\r
- gHiiDatabase->NewPackageList (gHiiDatabase, PackageList, DriverHandle, &HiiHandle);\r
- FreePool (PackageList);\r
+ if (Lang != NULL) {\r
+ FreePool (Lang);\r
+ }\r
}\r
\r
/**\r
Determine the current language that will be used\r
based on language related EFI Variables.\r
\r
- @param LangCodesSettingRequired - If required to set LangCode variable\r
+ @param LangCodesSettingRequired - If required to set LangCodes variable\r
\r
**/\r
VOID\r
InitializeLanguage (\r
- BOOLEAN LangCodesSettingRequired\r
+ BOOLEAN LangCodesSettingRequired\r
)\r
{\r
EFI_STATUS Status;\r
- UINTN Size;\r
- CHAR8 *Lang;\r
- CHAR8 LangCode[ISO_639_2_ENTRY_SIZE];\r
CHAR8 *LangCodes;\r
- CHAR8 *PlatformLang;\r
CHAR8 *PlatformLangCodes;\r
- UINTN Index;\r
- BOOLEAN Invalid;\r
\r
- ExportFonts ();\r
-\r
- LangCodes = (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultLangCodes);\r
+ LangCodes = (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultLangCodes);\r
+ PlatformLangCodes = (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes);\r
if (LangCodesSettingRequired) {\r
- if (!FeaturePcdGet (PcdUefiVariableDefaultLangDepricate)) {\r
+ if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {\r
//\r
// UEFI 2.1 depricated this variable so we support turning it off\r
//\r
L"LangCodes",\r
&gEfiGlobalVariableGuid,\r
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
- AsciiStrLen (LangCodes),\r
+ AsciiStrSize (LangCodes),\r
LangCodes\r
);\r
+ //\r
+ // Platform needs to make sure setting volatile variable before calling 3rd party code shouldn't fail.\r
+ //\r
+ ASSERT_EFI_ERROR (Status);\r
}\r
\r
-\r
- PlatformLangCodes = (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes);\r
Status = gRT->SetVariable (\r
L"PlatformLangCodes",\r
&gEfiGlobalVariableGuid,\r
AsciiStrSize (PlatformLangCodes),\r
PlatformLangCodes\r
);\r
- }\r
-\r
- if (!FeaturePcdGet (PcdUefiVariableDefaultLangDepricate)) {\r
//\r
- // UEFI 2.1 depricated this variable so we support turning it off\r
+ // Platform needs to make sure setting volatile variable before calling 3rd party code shouldn't fail.\r
//\r
-\r
- //\r
- // Find current LangCode from Lang NV Variable\r
- //\r
- Size = ISO_639_2_ENTRY_SIZE;\r
- Status = gRT->GetVariable (\r
- L"Lang",\r
- &gEfiGlobalVariableGuid,\r
- NULL,\r
- &Size,\r
- &LangCode\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- Status = EFI_NOT_FOUND;\r
- for (Index = 0; LangCodes[Index] != 0; Index += ISO_639_2_ENTRY_SIZE) {\r
- if (CompareMem (&LangCodes[Index], LangCode, ISO_639_2_ENTRY_SIZE) == 0) {\r
- Status = EFI_SUCCESS;\r
- break;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // If we cannot get language code from Lang variable,\r
- // or LangCode cannot be found from language table,\r
- // set the mDefaultLangCode to Lang variable.\r
- //\r
- if (EFI_ERROR (Status)) {\r
- Lang = (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultLang);\r
- Status = gRT->SetVariable (\r
- L"Lang",\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
- ISO_639_2_ENTRY_SIZE,\r
- Lang\r
- );\r
- }\r
+ ASSERT_EFI_ERROR (Status);\r
}\r
\r
- Invalid = FALSE;\r
- PlatformLang = BdsLibGetVariableAndSize (L"PlatformLang", &gEfiGlobalVariableGuid, &Size);\r
- if (PlatformLang != NULL) {\r
+ if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {\r
//\r
- // Check Current PlatformLang value against PlatformLangCode. Need a library that is TBD\r
- // Set Invalid based on state of PlatformLang.\r
+ // UEFI 2.1 depricated this variable so we support turning it off\r
//\r
-\r
- FreePool (PlatformLang);\r
- } else {\r
- // No valid variable is set\r
- Invalid = TRUE;\r
+ InitializeLangVariable (L"Lang", LangCodes, (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultLang), TRUE);\r
}\r
\r
- if (Invalid) {\r
- PlatformLang = (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLang);\r
- Status = gRT->SetVariable (\r
- L"PlatformLang",\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
- AsciiStrSize (PlatformLang),\r
- PlatformLang\r
- );\r
- }\r
+ InitializeLangVariable (L"PlatformLang", PlatformLangCodes, (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLang), FALSE);\r
}\r