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
28 #include "interface/consup.h"
29 #include "errorcode.h"
32 #include "muilanguages.h"
39 PopupError(IN PCCH Text
,
50 if (SelectedLanguageId
== NULL
)
52 /* default to english */
58 if (_wcsicmp(LanguageList
[lngIndex
].LanguageID
, SelectedLanguageId
) == 0)
64 }while (LanguageList
[lngIndex
].MuiPages
!= NULL
);
72 FindMUIEntriesOfPage(IN ULONG PageNumber
)
76 const MUI_PAGE
* Pages
= NULL
;
78 lngIndex
= max(FindLanguageIndex(), 0);
79 Pages
= LanguageList
[lngIndex
].MuiPages
;
83 if (Pages
[muiIndex
].Number
== PageNumber
)
84 return Pages
[muiIndex
].MuiEntry
;
87 }while (Pages
[muiIndex
].MuiEntry
!= NULL
);
94 FindMUIErrorEntries(VOID
)
96 ULONG lngIndex
= max(FindLanguageIndex(), 0);
97 return LanguageList
[lngIndex
].MuiErrors
;
102 FindMUIStringEntries(VOID
)
104 ULONG lngIndex
= max(FindLanguageIndex(), 0);
105 return LanguageList
[lngIndex
].MuiStrings
;
109 MUIDefaultKeyboardLayout(VOID
)
111 ULONG lngIndex
= max(FindLanguageIndex(), 0);
112 return LanguageList
[lngIndex
].MuiLayouts
[0].LayoutID
;
118 ULONG lngIndex
= max(FindLanguageIndex(), 0);
119 return LanguageList
[lngIndex
].GeoID
;
123 MUIGetLayoutsList(VOID
)
125 ULONG lngIndex
= max(FindLanguageIndex(), 0);
126 return LanguageList
[lngIndex
].MuiLayouts
;
130 MUIDisplayPage(IN ULONG page
)
132 const MUI_ENTRY
* entry
;
135 entry
= FindMUIEntriesOfPage(page
);
138 PopupError("Error: Failed to find translated page",
148 CONSOLE_SetStyledText (
152 entry
[index
].Buffer
);
156 while (entry
[index
].Buffer
!= NULL
);
160 MUIDisplayError(IN ULONG ErrorNum
, OUT PINPUT_RECORD Ir
, IN ULONG WaitEvent
)
162 const MUI_ERROR
* entry
;
164 if (ErrorNum
>= ERROR_LAST_ERROR_CODE
)
166 PopupError("Invalid error number provided",
167 "Press ENTER to continue",
174 entry
= FindMUIErrorEntries();
177 PopupError("Error: Failed to find translated error message",
184 PopupError(entry
[ErrorNum
].ErrorText
,
185 entry
[ErrorNum
].ErrorStatus
,
191 MUIGetString(ULONG Number
)
194 const MUI_STRING
* entry
;
197 entry
= FindMUIStringEntries();
200 for (i
= 0; entry
[i
].Number
!= 0; i
++)
202 if (entry
[i
].Number
== Number
)
204 return entry
[i
].String
;
209 sprintf(szErr
, "Error: failed find string id %lu for language index %lu\n", Number
, FindLanguageIndex());
220 AddHotkeySettings(IN LPCWSTR Hotkey
, IN LPCWSTR LangHotkey
, IN LPCWSTR LayoutHotkey
)
222 OBJECT_ATTRIBUTES ObjectAttributes
;
223 UNICODE_STRING KeyName
;
224 UNICODE_STRING ValueName
;
229 RtlInitUnicodeString(&KeyName
,
230 L
"\\Registry\\User\\.DEFAULT\\Keyboard Layout\\Toggle");
231 InitializeObjectAttributes(&ObjectAttributes
,
233 OBJ_CASE_INSENSITIVE
,
237 Status
= NtCreateKey(&KeyHandle
,
245 if(!NT_SUCCESS(Status
))
247 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status
);
251 RtlInitUnicodeString(&ValueName
,
254 Status
= NtSetValueKey(KeyHandle
,
259 (1 + 1) * sizeof(WCHAR
));
260 if (!NT_SUCCESS(Status
))
262 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
267 RtlInitUnicodeString(&ValueName
,
270 Status
= NtSetValueKey(KeyHandle
,
275 (1 + 1) * sizeof(WCHAR
));
276 if (!NT_SUCCESS(Status
))
278 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
283 RtlInitUnicodeString(&ValueName
,
286 Status
= NtSetValueKey(KeyHandle
,
291 (1 + 1) * sizeof(WCHAR
));
292 if (!NT_SUCCESS(Status
))
294 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
304 AddKbLayoutsToRegistry(IN
const MUI_LAYOUTS
* MuiLayouts
)
306 OBJECT_ATTRIBUTES ObjectAttributes
;
307 UNICODE_STRING KeyName
;
308 UNICODE_STRING ValueName
;
315 WCHAR szKeyName
[48] = L
"\\Registry\\User\\.DEFAULT\\Keyboard Layout";
316 WCHAR szValueName
[3 + 1];
317 WCHAR szLangID
[8 + 1];
319 // Open the keyboard layout key
320 RtlInitUnicodeString(&KeyName
,
322 InitializeObjectAttributes(&ObjectAttributes
,
324 OBJ_CASE_INSENSITIVE
,
328 Status
= NtCreateKey(&KeyHandle
,
336 if(NT_SUCCESS(Status
))
340 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status
);
344 KeyName
.MaximumLength
= sizeof(szKeyName
);
345 Status
= RtlAppendUnicodeToString(&KeyName
, L
"\\Preload");
347 if(!NT_SUCCESS(Status
))
349 DPRINT1("RtlAppend failed! (%lx)\n", Status
);
350 DPRINT1("String is %wZ\n", &KeyName
);
354 InitializeObjectAttributes(&ObjectAttributes
,
356 OBJ_CASE_INSENSITIVE
,
360 Status
= NtCreateKey(&KeyHandle
,
368 if (!NT_SUCCESS(Status
))
370 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status
);
374 RtlInitUnicodeString(&KeyName
, L
"\\Registry\\User\\.DEFAULT\\Keyboard Layout\\Substitutes");
375 InitializeObjectAttributes(&ObjectAttributes
,
377 OBJ_CASE_INSENSITIVE
,
381 Status
= NtCreateKey(&SubKeyHandle
,
389 if(!NT_SUCCESS(Status
))
391 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status
);
392 NtClose(SubKeyHandle
);
399 if (uIndex
> 19) break;
401 swprintf(szValueName
, L
"%u", uIndex
+ 1);
402 RtlInitUnicodeString(&ValueName
, szValueName
);
404 swprintf(szLangID
, L
"0000%s", MuiLayouts
[uIndex
].LangID
);
406 if (_wcsicmp(szLangID
, MuiLayouts
[uIndex
].LayoutID
) == 0)
408 Status
= NtSetValueKey(KeyHandle
,
412 (PVOID
)MuiLayouts
[uIndex
].LayoutID
,
413 (wcslen(MuiLayouts
[uIndex
].LayoutID
)+1) * sizeof(WCHAR
));
414 if (!NT_SUCCESS(Status
))
416 DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %d)\n", Status
, uIndex
);
417 NtClose(SubKeyHandle
);
424 swprintf(szLangID
, L
"d%03u%s", uCount
, MuiLayouts
[uIndex
].LangID
);
425 Status
= NtSetValueKey(KeyHandle
,
430 (wcslen(szLangID
)+1) * sizeof(WCHAR
));
431 if (!NT_SUCCESS(Status
))
433 DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %d)\n", Status
, uIndex
);
434 NtClose(SubKeyHandle
);
439 RtlInitUnicodeString(&ValueName
, szLangID
);
441 Status
= NtSetValueKey(SubKeyHandle
,
445 (PVOID
)MuiLayouts
[uIndex
].LayoutID
,
446 (wcslen(MuiLayouts
[uIndex
].LayoutID
)+1) * sizeof(WCHAR
));
447 if (!NT_SUCCESS(Status
))
449 DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %u)\n", Status
, uIndex
);
450 NtClose(SubKeyHandle
);
460 while (MuiLayouts
[uIndex
].LangID
!= NULL
);
463 AddHotkeySettings(L
"2", L
"2", L
"1");
465 AddHotkeySettings(L
"3", L
"3", L
"3");
467 NtClose(SubKeyHandle
);
473 AddKeyboardLayouts(VOID
)
478 if (_wcsicmp(LanguageList
[lngIndex
].LanguageID
, SelectedLanguageId
) == 0)
480 return AddKbLayoutsToRegistry(LanguageList
[lngIndex
].MuiLayouts
);
485 while (LanguageList
[lngIndex
].MuiPages
!= NULL
);
491 AddCodepageToRegistry(IN LPCWSTR ACPage
, IN LPCWSTR OEMCPage
, IN LPCWSTR MACCPage
)
493 OBJECT_ATTRIBUTES ObjectAttributes
;
494 UNICODE_STRING KeyName
;
495 UNICODE_STRING ValueName
;
499 // Open the nls codepage key
500 RtlInitUnicodeString(&KeyName
,
501 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage");
502 InitializeObjectAttributes(&ObjectAttributes
,
504 OBJ_CASE_INSENSITIVE
,
507 Status
= NtOpenKey(&KeyHandle
,
510 if (!NT_SUCCESS(Status
))
512 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
517 RtlInitUnicodeString(&ValueName
, L
"ACP");
518 Status
= NtSetValueKey(KeyHandle
,
523 (wcslen(ACPage
)+1) * sizeof(PWCHAR
));
524 if (!NT_SUCCESS(Status
))
526 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
532 RtlInitUnicodeString(&ValueName
, L
"OEMCP");
533 Status
= NtSetValueKey(KeyHandle
,
538 (wcslen(OEMCPage
)+1) * sizeof(PWCHAR
));
539 if (!NT_SUCCESS(Status
))
541 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
547 RtlInitUnicodeString(&ValueName
, L
"MACCP");
548 Status
= NtSetValueKey(KeyHandle
,
553 (wcslen(MACCPage
)+1) * sizeof(PWCHAR
));
554 if (!NT_SUCCESS(Status
))
556 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status
);
567 AddFontsSettingsToRegistry(IN
const MUI_SUBFONT
* MuiSubFonts
)
569 OBJECT_ATTRIBUTES ObjectAttributes
;
570 UNICODE_STRING KeyName
;
571 UNICODE_STRING ValueName
;
576 RtlInitUnicodeString(&KeyName
,
577 L
"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SysFontSubstitutes");
578 InitializeObjectAttributes(&ObjectAttributes
,
580 OBJ_CASE_INSENSITIVE
,
583 Status
= NtOpenKey(&KeyHandle
,
586 if (!NT_SUCCESS(Status
))
588 DPRINT1("NtOpenKey() failed (Status %lx)\n", Status
);
594 RtlInitUnicodeString(&ValueName
, MuiSubFonts
[uIndex
].FontName
);
595 Status
= NtSetValueKey(KeyHandle
,
599 (PVOID
)MuiSubFonts
[uIndex
].SubFontName
,
600 (wcslen(MuiSubFonts
[uIndex
].SubFontName
)+1) * sizeof(WCHAR
));
601 if (!NT_SUCCESS(Status
))
603 DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %d)\n", Status
, uIndex
);
610 while (MuiSubFonts
[uIndex
].FontName
!= NULL
);
623 if (_wcsicmp(LanguageList
[lngIndex
].LanguageID
, SelectedLanguageId
) == 0)
625 if (AddCodepageToRegistry(LanguageList
[lngIndex
].ACPage
,
626 LanguageList
[lngIndex
].OEMCPage
,
627 LanguageList
[lngIndex
].MACCPage
)&&
628 AddFontsSettingsToRegistry(LanguageList
[lngIndex
].MuiSubFonts
))
640 while (LanguageList
[lngIndex
].MuiPages
!= NULL
);
646 SetConsoleCodePage(VOID
)
653 if (_wcsicmp(LanguageList
[lngIndex
].LanguageID
, SelectedLanguageId
) == 0)
655 wCodePage
= (UINT
) wcstoul(LanguageList
[lngIndex
].OEMCPage
, NULL
, 10);
656 SetConsoleOutputCP(wCodePage
);
662 while (LanguageList
[lngIndex
].MuiPages
!= NULL
);