]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/BdsDxe/Language.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / BdsDxe / Language.c
index 907bb61e8b8b965b0901493ba425deb8ca0a9271..03aa055bd08835310712fc0fc19ff1753b98fb04 100644 (file)
-/*++\r
-\r
-Copyright (c) 2004 - 2008, Intel Corporation\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
-\r
-Module Name:\r
-\r
-  Language.c\r
-\r
-Abstract:\r
-\r
+/** @file\r
   Language settings\r
 \r
-Revision History\r
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "Bds.h"\r
+#define ISO_639_2_ENTRY_SIZE 3\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
+**/\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
+    return FALSE;\r
+  } else {\r
+    //\r
+    // Compare RFC4646 language code\r
+    //\r
+    for (LanguageLength = 0; Lang[LanguageLength] != '\0'; LanguageLength++);\r
 \r
---*/\r
+    for (; *SupportedLang != '\0'; SupportedLang += CompareLength) {\r
+      //\r
+      // Skip ';' characters in SupportedLang\r
+      //\r
+      for (; *SupportedLang != '\0' && *SupportedLang == ';'; SupportedLang++);\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
+      if ((CompareLength == LanguageLength) &&\r
+          (AsciiStrnCmp (Lang, SupportedLang, CompareLength) == 0)) {\r
+        //\r
+        // Successfully find the Lang string in SupportedLang string.\r
+        //\r
+        return TRUE;\r
+      }\r
+    }\r
+    return FALSE;\r
+  }\r
+}\r
 \r
-#include "Language.h"\r
-#include "FrontPage.h"\r
+/**\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
-#define NARROW_GLYPH_NUMBER 8\r
-#define WIDE_GLYPH_NUMBER   75\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
-EFI_GUID  mFontPackageGuid = {\r
-  0x78941450, 0x90ab, 0x4fb1, {0xb7, 0x5f, 0x58, 0x92, 0x14, 0xe2, 0x4a, 0xc}\r
-};\r
+**/\r
+VOID\r
+InitializeLangVariable (\r
+  IN CHAR16     *LangName,\r
+  IN CHAR8      *SupportedLang,\r
+  IN CHAR8      *DefaultLang,\r
+  IN BOOLEAN    Iso639Language\r
+  )\r
+{\r
+  CHAR8       *Lang;\r
 \r
-typedef struct {\r
   //\r
-  // This 4-bytes total array length is required by HiiLibPreparePackageList()\r
+  // Find current Lang or PlatformLang from EFI Variable.\r
   //\r
-  UINT32                 Length;\r
+  GetEfiGlobalVariable2 (LangName, (VOID **) &Lang, NULL);\r
 \r
   //\r
-  // This is the Font package definition\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
-  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
-\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
-      }\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
-    {\r
-      0x0000,\r
-      0x00,\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
-    }\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
-\r
-VOID\r
-ExportFonts (\r
-  VOID\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-  Routine to export glyphs to the HII database.  This is in addition to whatever is defined in the Graphics Console driver.\r
-\r
-Arguments:\r
-  None\r
-\r
-Returns:\r
 \r
---*/\r
-{\r
-  EFI_STATUS                   Status;\r
-  EFI_HANDLE                   DriverHandle;\r
-  EFI_HII_HANDLE               HiiHandle;\r
-  EFI_HII_PACKAGE_LIST_HEADER  *PackageList;\r
-\r
-  //\r
-  // Create driver handle used by HII database\r
-  //\r
-  Status = HiiLibCreateHiiDriverHandle (&DriverHandle);\r
-  if (EFI_ERROR (Status)) {\r
-    return ;\r
+  if (Lang != NULL) {\r
+    FreePool (Lang);\r
   }\r
+}\r
 \r
-  PackageList = HiiLibPreparePackageList (1, &mFontPackageGuid, &mFontBin);\r
-  ASSERT (PackageList != NULL);\r
+/**\r
+  Determine the current language that will be used\r
+  based on language related EFI Variables.\r
 \r
-  gHiiDatabase->NewPackageList (gHiiDatabase, PackageList, DriverHandle, &HiiHandle);\r
-  FreePool (PackageList);\r
-}\r
+  @param LangCodesSettingRequired - If required to set LangCodes variable\r
 \r
+**/\r
 VOID\r
 InitializeLanguage (\r
   BOOLEAN LangCodesSettingRequired\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-  Determine the current language that will be used\r
-  based on language related EFI Variables\r
-\r
-Arguments:\r
-  LangCodesSettingRequired - If required to set LangCode variable\r
-\r
-Returns:\r
-\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
+  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
@@ -334,13 +164,15 @@ Returns:
                       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
@@ -348,73 +180,17 @@ Returns:
                     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
-    //\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
+    // Platform needs to make sure setting volatile variable before calling 3rd party code shouldn't fail.\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
-  }\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
+    InitializeLangVariable (L"Lang", LangCodes, (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultLang), TRUE);\r
   }\r
+  InitializeLangVariable (L"PlatformLang", PlatformLangCodes, (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang), FALSE);\r
 }\r