• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   Language settings
3 
4 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution.  The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9 
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 **/
14 
15 #include "Language.h"
16 #include "FrontPage.h"
17 
18 EFI_GUID  mFontPackageGuid = {
19   0x78941450, 0x90ab, 0x4fb1, {0xb7, 0x5f, 0x58, 0x92, 0x14, 0xe2, 0x4a, 0xc}
20 };
21 
22 #define NARROW_GLYPH_NUMBER 8
23 #define WIDE_GLYPH_NUMBER   75
24 
25 typedef struct {
26   ///
27   /// This 4-bytes total array length is required by HiiAddPackages()
28   ///
29   UINT32                 Length;
30 
31   //
32   // This is the Font package definition
33   //
34   EFI_HII_PACKAGE_HEADER Header;
35   UINT16                 NumberOfNarrowGlyphs;
36   UINT16                 NumberOfWideGlyphs;
37   EFI_NARROW_GLYPH       NarrowArray[NARROW_GLYPH_NUMBER];
38   EFI_WIDE_GLYPH         WideArray[WIDE_GLYPH_NUMBER];
39 } FONT_PACK_BIN;
40 
41 FONT_PACK_BIN mFontBin = {
42   sizeof (FONT_PACK_BIN),
43   {
44     sizeof (FONT_PACK_BIN) - sizeof (UINT32),
45     EFI_HII_PACKAGE_SIMPLE_FONTS,
46   },
47   NARROW_GLYPH_NUMBER,
48   0,
49   {     // Narrow Glyphs
50     {
51       0x05d0,
52       0x00,
53       {
54         0x00,
55         0x00,
56         0x00,
57         0x4E,
58         0x6E,
59         0x62,
60         0x32,
61         0x32,
62         0x3C,
63         0x68,
64         0x4C,
65         0x4C,
66         0x46,
67         0x76,
68         0x72,
69         0x00,
70         0x00,
71         0x00,
72         0x00
73       }
74     },
75     {
76       0x05d1,
77       0x00,
78       {
79         0x00,
80         0x00,
81         0x00,
82         0x78,
83         0x7C,
84         0x0C,
85         0x0C,
86         0x0C,
87         0x0C,
88         0x0C,
89         0x0C,
90         0x0C,
91         0x0C,
92         0x7E,
93         0x7E,
94         0x00,
95         0x00,
96         0x00,
97         0x00
98       }
99     },
100     {
101       0x05d2,
102       0x00,
103       {
104         0x00,
105         0x00,
106         0x00,
107         0x78,
108         0x7C,
109         0x0C,
110         0x0C,
111         0x0C,
112         0x0C,
113         0x0C,
114         0x0C,
115         0x1C,
116         0x3E,
117         0x66,
118         0x66,
119         0x00,
120         0x00,
121         0x00,
122         0x00
123       }
124     },
125     {
126       0x05d3,
127       0x00,
128       {
129         0x00,
130         0x00,
131         0x00,
132         0x7E,
133         0x7E,
134         0x0C,
135         0x0C,
136         0x0C,
137         0x0C,
138         0x0C,
139         0x0C,
140         0x0C,
141         0x0C,
142         0x0C,
143         0x0C,
144         0x00,
145         0x00,
146         0x00,
147         0x00
148       }
149     },
150     {
151       0x05d4,
152       0x00,
153       {
154         0x00,
155         0x00,
156         0x00,
157         0x7C,
158         0x7E,
159         0x06,
160         0x06,
161         0x06,
162         0x06,
163         0x66,
164         0x66,
165         0x66,
166         0x66,
167         0x66,
168         0x66,
169         0x00,
170         0x00,
171         0x00,
172         0x00
173       }
174     },
175     {
176       0x05d5,
177       0x00,
178       {
179         0x00,
180         0x00,
181         0x00,
182         0x3C,
183         0x3C,
184         0x0C,
185         0x0C,
186         0x0C,
187         0x0C,
188         0x0C,
189         0x0C,
190         0x0C,
191         0x0C,
192         0x0C,
193         0x0C,
194         0x00,
195         0x00,
196         0x00,
197         0x00
198       }
199     },
200     {
201       0x05d6,
202       0x00,
203       {
204         0x00,
205         0x00,
206         0x00,
207         0x38,
208         0x38,
209         0x1E,
210         0x1E,
211         0x18,
212         0x18,
213         0x18,
214         0x18,
215         0x18,
216         0x18,
217         0x18,
218         0x18,
219         0x00,
220         0x00,
221         0x00,
222         0x00
223       }
224     },
225     {
226       0x0000,
227       0x00,
228       {
229         0x00,
230         0x00,
231         0x00,
232         0x00,
233         0x00,
234         0x00,
235         0x00,
236         0x00,
237         0x00,
238         0x00,
239         0x00,
240         0x00,
241         0x00,
242         0x00,
243         0x00,
244         0x00,
245         0x00,
246         0x00,
247         0x00
248       }
249     }
250   }
251 };
252 
253 /**
254   Routine to export glyphs to the HII database.  This is in addition to whatever is defined in the Graphics Console driver.
255 
256 **/
257 VOID
ExportFonts(VOID)258 ExportFonts (
259   VOID
260   )
261 {
262   EFI_HII_HANDLE               HiiHandle;
263 
264   HiiHandle = HiiAddPackages (
265                 &mFontPackageGuid,
266                 gImageHandle,
267                 &mFontBin,
268                 NULL
269                 );
270   ASSERT (HiiHandle != NULL);
271 }
272 
273 /**
274   Get next language from language code list (with separator ';').
275 
276   If LangCode is NULL, then ASSERT.
277   If Lang is NULL, then ASSERT.
278 
279   @param  LangCode    On input: point to first language in the list. On
280                                  output: point to next language in the list, or
281                                  NULL if no more language in the list.
282   @param  Lang           The first language in the list.
283 
284 **/
285 VOID
286 EFIAPI
GetNextLanguage(IN OUT CHAR8 ** LangCode,OUT CHAR8 * Lang)287 GetNextLanguage (
288   IN OUT CHAR8      **LangCode,
289   OUT CHAR8         *Lang
290   )
291 {
292   UINTN  Index;
293   CHAR8  *StringPtr;
294 
295   ASSERT (LangCode != NULL);
296   ASSERT (*LangCode != NULL);
297   ASSERT (Lang != NULL);
298 
299   Index = 0;
300   StringPtr = *LangCode;
301   while (StringPtr[Index] != 0 && StringPtr[Index] != ';') {
302     Index++;
303   }
304 
305   CopyMem (Lang, StringPtr, Index);
306   Lang[Index] = 0;
307 
308   if (StringPtr[Index] == ';') {
309     Index++;
310   }
311   *LangCode = StringPtr + Index;
312 }
313 
314 /**
315   Check if lang is in supported language codes according to language string.
316 
317   This code is used to check if lang is in in supported language codes. It can handle
318   RFC4646 and ISO639 language tags.
319   In ISO639 language tags, take 3-characters as a delimitation to find matched string.
320   In RFC4646 language tags, take semicolon as a delimitation to find matched string.
321 
322   For example:
323     SupportedLang  = "engfraengfra"
324     Iso639Language = TRUE
325     Lang           = "eng", the return value is "TRUE", or
326     Lang           = "chs", the return value is "FALSE".
327   Another example:
328     SupportedLang  = "en;fr;en-US;fr-FR"
329     Iso639Language = FALSE
330     Lang           = "en", the return value is "TRUE", or
331     Lang           = "zh", the return value is "FALSE".
332 
333   @param  SupportedLang               Platform supported language codes.
334   @param  Lang                        Configured language.
335   @param  Iso639Language              A bool value to signify if the handler is operated on ISO639 or RFC4646.
336 
337   @retval TRUE  lang is in supported language codes.
338   @retval FALSE lang is not in supported language codes.
339 
340 **/
341 BOOLEAN
IsLangInSupportedLangCodes(IN CHAR8 * SupportedLang,IN CHAR8 * Lang,IN BOOLEAN Iso639Language)342 IsLangInSupportedLangCodes(
343   IN  CHAR8            *SupportedLang,
344   IN  CHAR8            *Lang,
345   IN  BOOLEAN          Iso639Language
346   )
347 {
348   UINTN    Index;
349   UINTN    CompareLength;
350   UINTN    LanguageLength;
351 
352   if (Iso639Language) {
353     CompareLength = ISO_639_2_ENTRY_SIZE;
354     for (Index = 0; Index < AsciiStrLen (SupportedLang); Index += CompareLength) {
355       if (AsciiStrnCmp (Lang, SupportedLang + Index, CompareLength) == 0) {
356         //
357         // Successfully find the Lang string in SupportedLang string.
358         //
359         return TRUE;
360       }
361     }
362     return FALSE;
363   } else {
364     //
365     // Compare RFC4646 language code
366     //
367     for (LanguageLength = 0; Lang[LanguageLength] != '\0'; LanguageLength++);
368 
369     for (; *SupportedLang != '\0'; SupportedLang += CompareLength) {
370       //
371       // Skip ';' characters in SupportedLang
372       //
373       for (; *SupportedLang != '\0' && *SupportedLang == ';'; SupportedLang++);
374       //
375       // Determine the length of the next language code in SupportedLang
376       //
377       for (CompareLength = 0; SupportedLang[CompareLength] != '\0' && SupportedLang[CompareLength] != ';'; CompareLength++);
378 
379       if ((CompareLength == LanguageLength) &&
380           (AsciiStrnCmp (Lang, SupportedLang, CompareLength) == 0)) {
381         //
382         // Successfully find the Lang string in SupportedLang string.
383         //
384         return TRUE;
385       }
386     }
387     return FALSE;
388   }
389 }
390 
391 /**
392   Initialize Lang or PlatformLang variable, if Lang or PlatformLang variable is not found,
393   or it has been set to an unsupported value(not one of platform supported language codes),
394   set the default language code to it.
395 
396   @param  LangName                    Language name, L"Lang" or L"PlatformLang".
397   @param  SupportedLang               Platform supported language codes.
398   @param  DefaultLang                 Default language code.
399   @param  Iso639Language              A bool value to signify if the handler is operated on ISO639 or RFC4646,
400                                       TRUE for L"Lang" LangName or FALSE for L"PlatformLang" LangName.
401 
402 **/
403 VOID
InitializeLangVariable(IN CHAR16 * LangName,IN CHAR8 * SupportedLang,IN CHAR8 * DefaultLang,IN BOOLEAN Iso639Language)404 InitializeLangVariable (
405   IN CHAR16     *LangName,
406   IN CHAR8      *SupportedLang,
407   IN CHAR8      *DefaultLang,
408   IN BOOLEAN    Iso639Language
409   )
410 {
411   CHAR8       *Lang;
412 
413   //
414   // Find current Lang or PlatformLang from EFI Variable.
415   //
416   GetEfiGlobalVariable2 (LangName, (VOID **) &Lang, NULL);
417   //
418   // If Lang or PlatformLang variable is not found,
419   // or it has been set to an unsupported value(not one of the supported language codes),
420   // set the default language code to it.
421   //
422   if ((Lang == NULL) || !IsLangInSupportedLangCodes (SupportedLang, Lang, Iso639Language)) {
423     //
424     // The default language code should be one of the supported language codes.
425     //
426     ASSERT (IsLangInSupportedLangCodes (SupportedLang, DefaultLang, Iso639Language));
427     BdsDxeSetVariableAndReportStatusCodeOnError (
428                     LangName,
429                     &gEfiGlobalVariableGuid,
430                     EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
431                     AsciiStrSize (DefaultLang),
432                     DefaultLang
433                     );
434   }
435 
436   if (Lang != NULL) {
437     FreePool (Lang);
438   }
439 }
440 
441 /**
442   Determine the current language that will be used
443   based on language related EFI Variables.
444 
445   @param LangCodesSettingRequired - If required to set LangCodes variable
446 
447 **/
448 VOID
InitializeLanguage(BOOLEAN LangCodesSettingRequired)449 InitializeLanguage (
450   BOOLEAN LangCodesSettingRequired
451   )
452 {
453   EFI_STATUS  Status;
454   CHAR8       *LangCodes;
455   CHAR8       *PlatformLangCodes;
456 
457   ExportFonts ();
458 
459   LangCodes = (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultLangCodes);
460   PlatformLangCodes = (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes);
461   if (LangCodesSettingRequired) {
462     if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
463       //
464       // UEFI 2.0 depricated this variable so we support turning it off
465       //
466       Status = gRT->SetVariable (
467                       L"LangCodes",
468                       &gEfiGlobalVariableGuid,
469                       EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
470                       AsciiStrSize (LangCodes),
471                       LangCodes
472                       );
473       //
474       // Platform needs to make sure setting volatile variable before calling 3rd party code shouldn't fail.
475       //
476       ASSERT_EFI_ERROR (Status);
477     }
478 
479     Status = gRT->SetVariable (
480                     L"PlatformLangCodes",
481                     &gEfiGlobalVariableGuid,
482                     EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
483                     AsciiStrSize (PlatformLangCodes),
484                     PlatformLangCodes
485                     );
486     //
487     // Platform needs to make sure setting volatile variable before calling 3rd party code shouldn't fail.
488     //
489     ASSERT_EFI_ERROR (Status);
490   }
491 
492   if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
493     //
494     // UEFI 2.0 depricated this variable so we support turning it off
495     //
496     InitializeLangVariable (L"Lang", LangCodes, (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultLang), TRUE);
497   }
498   InitializeLangVariable (L"PlatformLang", PlatformLangCodes, (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang), FALSE);
499 }
500