3 * Copyright (C) 2008 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: subsys/system/usetup/mui.c
23 * PURPOSE: Text-mode setup
29 #include "muilanguages.h"
36 PopupError(IN PCCH Text
,
43 FindLanguageIndex(VOID
)
47 if (SelectedLanguageId
== NULL
)
49 /* default to english */
55 if (_wcsicmp(LanguageList
[lngIndex
].LanguageID
, SelectedLanguageId
) == 0)
61 }while (LanguageList
[lngIndex
].MuiPages
!= NULL
);
67 IsLanguageAvailable(PWCHAR LanguageId
)
73 if (_wcsicmp(LanguageList
[lngIndex
].LanguageID
, LanguageId
) == 0)
77 }while (LanguageList
[lngIndex
].MuiPages
!= NULL
);
85 FindMUIEntriesOfPage(IN ULONG PageNumber
)
89 const MUI_PAGE
* Pages
= NULL
;
91 lngIndex
= max(FindLanguageIndex(), 0);
92 Pages
= LanguageList
[lngIndex
].MuiPages
;
96 if (Pages
[muiIndex
].Number
== PageNumber
)
97 return Pages
[muiIndex
].MuiEntry
;
100 }while (Pages
[muiIndex
].MuiEntry
!= NULL
);
107 FindMUIErrorEntries(VOID
)
109 ULONG lngIndex
= max(FindLanguageIndex(), 0);
110 return LanguageList
[lngIndex
].MuiErrors
;
115 FindMUIStringEntries(VOID
)
117 ULONG lngIndex
= max(FindLanguageIndex(), 0);
118 return LanguageList
[lngIndex
].MuiStrings
;
122 MUIDefaultKeyboardLayout(VOID
)
124 ULONG lngIndex
= max(FindLanguageIndex(), 0);
125 return LanguageList
[lngIndex
].MuiLayouts
[0].LayoutID
;
131 ULONG lngIndex
= max(FindLanguageIndex(), 0);
132 return LanguageList
[lngIndex
].GeoID
;
136 MUIGetLayoutsList(VOID
)
138 ULONG lngIndex
= max(FindLanguageIndex(), 0);
139 return LanguageList
[lngIndex
].MuiLayouts
;
143 MUIClearPage(IN ULONG page
)
145 const MUI_ENTRY
* entry
;
148 entry
= FindMUIEntriesOfPage(page
);
151 PopupError("Error: Failed to find translated page",
161 CONSOLE_ClearStyledText(entry
[index
].X
,
164 strlen(entry
[index
].Buffer
));
167 while (entry
[index
].Buffer
!= NULL
);
171 MUIDisplayPage(IN ULONG page
)
173 const MUI_ENTRY
* entry
;
176 entry
= FindMUIEntriesOfPage(page
);
179 PopupError("Error: Failed to find translated page",
189 CONSOLE_SetStyledText(entry
[index
].X
,
192 entry
[index
].Buffer
);
196 while (entry
[index
].Buffer
!= NULL
);
200 MUIDisplayError(IN ULONG ErrorNum
, OUT PINPUT_RECORD Ir
, IN ULONG WaitEvent
)
202 const MUI_ERROR
* entry
;
204 if (ErrorNum
>= ERROR_LAST_ERROR_CODE
)
206 PopupError("Invalid error number provided",
207 "Press ENTER to continue",
214 entry
= FindMUIErrorEntries();
217 PopupError("Error: Failed to find translated error message",
224 PopupError(entry
[ErrorNum
].ErrorText
,
225 entry
[ErrorNum
].ErrorStatus
,
231 MUIGetString(ULONG Number
)
234 const MUI_STRING
* entry
;
237 entry
= FindMUIStringEntries();
240 for (i
= 0; entry
[i
].Number
!= 0; i
++)
242 if (entry
[i
].Number
== Number
)
244 return entry
[i
].String
;
249 sprintf(szErr
, "Error: failed find string id %lu for language index %lu\n", Number
, FindLanguageIndex());
260 AddHotkeySettings(IN LPCWSTR Hotkey
, IN LPCWSTR LangHotkey
, IN LPCWSTR LayoutHotkey
)
262 OBJECT_ATTRIBUTES ObjectAttributes
;
263 UNICODE_STRING KeyName
;
264 UNICODE_STRING ValueName
;
269 RtlInitUnicodeString(&KeyName
,
270 L
"\\Registry\\User\\.DEFAULT\\Keyboard Layout\\Toggle");
271 InitializeObjectAttributes(&ObjectAttributes
,
273 OBJ_CASE_INSENSITIVE
,
277 Status
= NtCreateKey(&KeyHandle
,
285 if(!NT_SUCCESS(Status
))
287 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status
);
291 RtlInitUnicodeString(&ValueName
,
294 Status
= NtSetValueKey(KeyHandle
,
299 (1 + 1) * sizeof(WCHAR
));
300 if (!NT_SUCCESS(Status
))
302 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
307 RtlInitUnicodeString(&ValueName
,
310 Status
= NtSetValueKey(KeyHandle
,
315 (1 + 1) * sizeof(WCHAR
));
316 if (!NT_SUCCESS(Status
))
318 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
323 RtlInitUnicodeString(&ValueName
,
326 Status
= NtSetValueKey(KeyHandle
,
331 (1 + 1) * sizeof(WCHAR
));
332 if (!NT_SUCCESS(Status
))
334 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
344 AddKbLayoutsToRegistry(IN
const MUI_LAYOUTS
* MuiLayouts
)
346 OBJECT_ATTRIBUTES ObjectAttributes
;
347 UNICODE_STRING KeyName
;
348 UNICODE_STRING ValueName
;
355 WCHAR szKeyName
[48] = L
"\\Registry\\User\\.DEFAULT\\Keyboard Layout";
356 WCHAR szValueName
[3 + 1];
357 WCHAR szLangID
[8 + 1];
359 // Open the keyboard layout key
360 RtlInitUnicodeString(&KeyName
,
362 InitializeObjectAttributes(&ObjectAttributes
,
364 OBJ_CASE_INSENSITIVE
,
368 Status
= NtCreateKey(&KeyHandle
,
376 if(NT_SUCCESS(Status
))
380 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status
);
384 KeyName
.MaximumLength
= sizeof(szKeyName
);
385 Status
= RtlAppendUnicodeToString(&KeyName
, L
"\\Preload");
387 if(!NT_SUCCESS(Status
))
389 DPRINT1("RtlAppend failed! (%lx)\n", Status
);
390 DPRINT1("String is %wZ\n", &KeyName
);
394 InitializeObjectAttributes(&ObjectAttributes
,
396 OBJ_CASE_INSENSITIVE
,
400 Status
= NtCreateKey(&KeyHandle
,
408 if (!NT_SUCCESS(Status
))
410 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status
);
414 RtlInitUnicodeString(&KeyName
, L
"\\Registry\\User\\.DEFAULT\\Keyboard Layout\\Substitutes");
415 InitializeObjectAttributes(&ObjectAttributes
,
417 OBJ_CASE_INSENSITIVE
,
421 Status
= NtCreateKey(&SubKeyHandle
,
429 if(!NT_SUCCESS(Status
))
431 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status
);
432 NtClose(SubKeyHandle
);
439 if (uIndex
> 19) break;
441 swprintf(szValueName
, L
"%u", uIndex
+ 1);
442 RtlInitUnicodeString(&ValueName
, szValueName
);
444 swprintf(szLangID
, L
"0000%s", MuiLayouts
[uIndex
].LangID
);
446 if (_wcsicmp(szLangID
, MuiLayouts
[uIndex
].LayoutID
) == 0)
448 Status
= NtSetValueKey(KeyHandle
,
452 (PVOID
)MuiLayouts
[uIndex
].LayoutID
,
453 (wcslen(MuiLayouts
[uIndex
].LayoutID
)+1) * sizeof(WCHAR
));
454 if (!NT_SUCCESS(Status
))
456 DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %d)\n", Status
, uIndex
);
457 NtClose(SubKeyHandle
);
464 swprintf(szLangID
, L
"d%03u%s", uCount
, MuiLayouts
[uIndex
].LangID
);
465 Status
= NtSetValueKey(KeyHandle
,
470 (wcslen(szLangID
)+1) * sizeof(WCHAR
));
471 if (!NT_SUCCESS(Status
))
473 DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %d)\n", Status
, uIndex
);
474 NtClose(SubKeyHandle
);
479 RtlInitUnicodeString(&ValueName
, szLangID
);
481 Status
= NtSetValueKey(SubKeyHandle
,
485 (PVOID
)MuiLayouts
[uIndex
].LayoutID
,
486 (wcslen(MuiLayouts
[uIndex
].LayoutID
)+1) * sizeof(WCHAR
));
487 if (!NT_SUCCESS(Status
))
489 DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %u)\n", Status
, uIndex
);
490 NtClose(SubKeyHandle
);
500 while (MuiLayouts
[uIndex
].LangID
!= NULL
);
503 AddHotkeySettings(L
"2", L
"2", L
"1");
505 AddHotkeySettings(L
"3", L
"3", L
"3");
507 NtClose(SubKeyHandle
);
513 AddKeyboardLayouts(VOID
)
518 if (_wcsicmp(LanguageList
[lngIndex
].LanguageID
, SelectedLanguageId
) == 0)
520 return AddKbLayoutsToRegistry(LanguageList
[lngIndex
].MuiLayouts
);
525 while (LanguageList
[lngIndex
].MuiPages
!= NULL
);
531 AddCodepageToRegistry(IN LPCWSTR ACPage
, IN LPCWSTR OEMCPage
, IN LPCWSTR MACCPage
)
533 OBJECT_ATTRIBUTES ObjectAttributes
;
534 UNICODE_STRING KeyName
;
535 UNICODE_STRING ValueName
;
539 // Open the nls codepage key
540 RtlInitUnicodeString(&KeyName
,
541 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage");
542 InitializeObjectAttributes(&ObjectAttributes
,
544 OBJ_CASE_INSENSITIVE
,
547 Status
= NtOpenKey(&KeyHandle
,
550 if (!NT_SUCCESS(Status
))
552 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
557 RtlInitUnicodeString(&ValueName
, L
"ACP");
558 Status
= NtSetValueKey(KeyHandle
,
563 (wcslen(ACPage
)+1) * sizeof(WCHAR
));
564 if (!NT_SUCCESS(Status
))
566 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
572 RtlInitUnicodeString(&ValueName
, L
"OEMCP");
573 Status
= NtSetValueKey(KeyHandle
,
578 (wcslen(OEMCPage
)+1) * sizeof(WCHAR
));
579 if (!NT_SUCCESS(Status
))
581 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
587 RtlInitUnicodeString(&ValueName
, L
"MACCP");
588 Status
= NtSetValueKey(KeyHandle
,
593 (wcslen(MACCPage
)+1) * sizeof(WCHAR
));
594 if (!NT_SUCCESS(Status
))
596 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
607 AddFontsSettingsToRegistry(IN
const MUI_SUBFONT
* MuiSubFonts
)
609 OBJECT_ATTRIBUTES ObjectAttributes
;
610 UNICODE_STRING KeyName
;
611 UNICODE_STRING ValueName
;
616 RtlInitUnicodeString(&KeyName
,
617 L
"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes");
618 InitializeObjectAttributes(&ObjectAttributes
,
620 OBJ_CASE_INSENSITIVE
,
623 Status
= NtOpenKey(&KeyHandle
,
626 if (!NT_SUCCESS(Status
))
628 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
634 RtlInitUnicodeString(&ValueName
, MuiSubFonts
[uIndex
].FontName
);
635 Status
= NtSetValueKey(KeyHandle
,
639 (PVOID
)MuiSubFonts
[uIndex
].SubFontName
,
640 (wcslen(MuiSubFonts
[uIndex
].SubFontName
)+1) * sizeof(WCHAR
));
641 if (!NT_SUCCESS(Status
))
643 DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %d)\n", Status
, uIndex
);
650 while (MuiSubFonts
[uIndex
].FontName
!= NULL
);
663 if (_wcsicmp(LanguageList
[lngIndex
].LanguageID
, SelectedLanguageId
) == 0)
665 if (AddCodepageToRegistry(LanguageList
[lngIndex
].ACPage
,
666 LanguageList
[lngIndex
].OEMCPage
,
667 LanguageList
[lngIndex
].MACCPage
)&&
668 AddFontsSettingsToRegistry(LanguageList
[lngIndex
].MuiSubFonts
))
680 while (LanguageList
[lngIndex
].MuiPages
!= NULL
);
686 SetConsoleCodePage(VOID
)
693 if (_wcsicmp(LanguageList
[lngIndex
].LanguageID
, SelectedLanguageId
) == 0)
695 wCodePage
= (UINT
) wcstoul(LanguageList
[lngIndex
].OEMCPage
, NULL
, 10);
696 SetConsoleOutputCP(wCodePage
);
702 while (LanguageList
[lngIndex
].MuiPages
!= NULL
);