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