1 /* 2 * ReactOS kernel 3 * Copyright (C) 2008 ReactOS Team 4 * 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. 9 * 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. 14 * 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. 18 */ 19 /* 20 * COPYRIGHT: See COPYING in the top level directory 21 * PROJECT: ReactOS text-mode setup 22 * FILE: base/setup/usetup/mui.c 23 * PURPOSE: Text-mode setup 24 * PROGRAMMER: 25 */ 26 27 #include "usetup.h" 28 #include "muilanguages.h" 29 30 #define NDEBUG 31 #include <debug.h> 32 33 static 34 ULONG 35 FindLanguageIndex(VOID) 36 { 37 ULONG lngIndex = 0; 38 39 if (SelectedLanguageId == NULL) 40 { 41 /* Default to en-US */ 42 return 0; // FIXME!! 43 // SelectedLanguageId = L"00000409"; 44 } 45 46 while (ResourceList[lngIndex].MuiPages != NULL) 47 { 48 if (_wcsicmp(ResourceList[lngIndex].LanguageID, SelectedLanguageId) == 0) 49 { 50 return lngIndex; 51 } 52 53 lngIndex++; 54 } 55 56 return 0; 57 } 58 59 60 #if 0 61 BOOLEAN 62 IsLanguageAvailable( 63 PWCHAR LanguageId) 64 { 65 ULONG lngIndex = 0; 66 67 while (ResourceList[lngIndex].MuiPages != NULL) 68 { 69 if (_wcsicmp(ResourceList[lngIndex].LanguageID, LanguageId) == 0) 70 return TRUE; 71 72 lngIndex++; 73 } 74 75 return FALSE; 76 } 77 #endif 78 79 80 static 81 const MUI_ENTRY * 82 FindMUIEntriesOfPage( 83 IN ULONG PageNumber) 84 { 85 ULONG muiIndex = 0; 86 ULONG lngIndex; 87 const MUI_PAGE * Pages = NULL; 88 89 lngIndex = max(FindLanguageIndex(), 0); 90 Pages = ResourceList[lngIndex].MuiPages; 91 92 while (Pages[muiIndex].MuiEntry != NULL) 93 { 94 if (Pages[muiIndex].Number == PageNumber) 95 return Pages[muiIndex].MuiEntry; 96 97 muiIndex++; 98 } 99 100 return NULL; 101 } 102 103 static 104 const MUI_ERROR * 105 FindMUIErrorEntries(VOID) 106 { 107 ULONG lngIndex = max(FindLanguageIndex(), 0); 108 return ResourceList[lngIndex].MuiErrors; 109 } 110 111 static 112 const MUI_STRING * 113 FindMUIStringEntries(VOID) 114 { 115 ULONG lngIndex = max(FindLanguageIndex(), 0); 116 return ResourceList[lngIndex].MuiStrings; 117 } 118 119 120 VOID 121 MUIClearPage( 122 IN ULONG page) 123 { 124 const MUI_ENTRY * entry; 125 ULONG index; 126 127 entry = FindMUIEntriesOfPage(page); 128 if (!entry) 129 { 130 PopupError("Error: Failed to find translated page", 131 NULL, 132 NULL, 133 POPUP_WAIT_NONE); 134 return; 135 } 136 137 index = 0; 138 while (entry[index].Buffer != NULL) 139 { 140 CONSOLE_ClearStyledText(entry[index].X, 141 entry[index].Y, 142 entry[index].Flags, 143 (USHORT)strlen(entry[index].Buffer)); 144 index++; 145 } 146 } 147 148 VOID 149 MUIDisplayPage( 150 IN ULONG page) 151 { 152 const MUI_ENTRY * entry; 153 ULONG index; 154 155 entry = FindMUIEntriesOfPage(page); 156 if (!entry) 157 { 158 PopupError("Error: Failed to find translated page", 159 NULL, 160 NULL, 161 POPUP_WAIT_NONE); 162 return; 163 } 164 165 index = 0; 166 while (entry[index].Buffer != NULL) 167 { 168 CONSOLE_SetStyledText(entry[index].X, 169 entry[index].Y, 170 entry[index].Flags, 171 entry[index].Buffer); 172 173 index++; 174 } 175 } 176 177 VOID 178 MUIDisplayErrorV( 179 IN ULONG ErrorNum, 180 OUT PINPUT_RECORD Ir, 181 IN ULONG WaitEvent, 182 IN va_list args) 183 { 184 const MUI_ERROR* entry; 185 CHAR Buffer[2048]; 186 187 if (ErrorNum >= ERROR_LAST_ERROR_CODE) 188 { 189 PopupError("Invalid error number provided", 190 "Press ENTER to continue", 191 Ir, 192 POPUP_WAIT_ENTER); 193 return; 194 } 195 196 entry = FindMUIErrorEntries(); 197 if (!entry) 198 { 199 PopupError("Error: Failed to find translated error message", 200 NULL, 201 NULL, 202 POPUP_WAIT_NONE); 203 return; 204 } 205 206 vsprintf(Buffer, entry[ErrorNum].ErrorText, args); 207 208 PopupError(Buffer, 209 entry[ErrorNum].ErrorStatus, 210 Ir, 211 WaitEvent); 212 } 213 214 VOID 215 __cdecl 216 MUIDisplayError( 217 IN ULONG ErrorNum, 218 OUT PINPUT_RECORD Ir, 219 IN ULONG WaitEvent, 220 ...) 221 { 222 va_list arg_ptr; 223 224 va_start(arg_ptr, WaitEvent); 225 MUIDisplayErrorV(ErrorNum, Ir, WaitEvent, arg_ptr); 226 va_end(arg_ptr); 227 } 228 229 PCSTR 230 MUIGetString( 231 ULONG Number) 232 { 233 ULONG i; 234 const MUI_STRING * entry; 235 CHAR szErr[128]; 236 237 entry = FindMUIStringEntries(); 238 if (entry) 239 { 240 for (i = 0; entry[i].Number != 0; i++) 241 { 242 if (entry[i].Number == Number) 243 { 244 return entry[i].String; 245 } 246 } 247 } 248 249 sprintf(szErr, "Error: failed find string id %lu for language index %lu\n", Number, FindLanguageIndex()); 250 251 PopupError(szErr, 252 NULL, 253 NULL, 254 POPUP_WAIT_NONE); 255 256 return "<nostring>"; 257 } 258 259 /** 260 * @MUIGetEntry 261 * 262 * Retrieves a MUI entry of a page, given the page number and the text ID. 263 * 264 * @param[in] Page 265 * The MUI (Multilingual User Interface) entry page number, as a unsigned long integer. 266 * 267 * @param[in] TextID 268 * The text identification number (ID), as a unsigned integer. The parameter is used to identify 269 * its MUI properties like the coordinates, text style flag and its buffer content. 270 * 271 * @return 272 * Returns a constant MUI entry. 273 * 274 */ 275 const MUI_ENTRY * 276 MUIGetEntry( 277 IN ULONG Page, 278 IN INT TextID) 279 { 280 const MUI_ENTRY * entry; 281 ULONG index; 282 283 /* Retrieve the entries of a MUI page */ 284 entry = FindMUIEntriesOfPage(Page); 285 if (!entry) 286 { 287 DPRINT("MUIGetEntryData(): Failed to get the translated entry page!\n"); 288 return NULL; 289 } 290 291 /* Loop over the ID entries and check if it matches with one of them */ 292 for (index = 0; entry[index].Buffer != NULL; index++) 293 { 294 if (entry[index].TextID == TextID) 295 { 296 /* They match so return the MUI entry */ 297 return &entry[index]; 298 } 299 } 300 301 /* Page number or ID are incorrect so in this case bail out */ 302 DPRINT("Couldn't get the MUI entry field from the page!\n"); 303 return NULL; 304 } 305 306 /** 307 * @MUIClearText 308 * 309 * Clears a portion of text from the console output. 310 * 311 * @param[in] Page 312 * The MUI (Multilingual User Interface) entry page number, as a unsigned long integer. 313 * 314 * @param[in] TextID 315 * The text identification number (ID), as an integer. The parameter is used to identify 316 * its MUI properties like the coordinates, text style flag and its buffer content. 317 * 318 * @return 319 * Nothing. 320 * 321 */ 322 VOID 323 MUIClearText( 324 IN ULONG Page, 325 IN INT TextID) 326 { 327 const MUI_ENTRY * entry; 328 ULONG Index = 0; 329 330 /* Get the MUI entry */ 331 entry = MUIGetEntry(Page, TextID); 332 333 if (!entry) 334 return; 335 336 /* Ensure that the text string given by the text ID and page is not NULL */ 337 while (entry[Index].Buffer != NULL) 338 { 339 /* If text ID is not correct, skip the entry */ 340 if (entry[Index].TextID != TextID) 341 { 342 Index++; 343 continue; 344 } 345 346 /* Remove the text by using CONSOLE_ClearTextXY() */ 347 CONSOLE_ClearTextXY( 348 entry[Index].X, 349 entry[Index].Y, 350 (USHORT)strlen(entry[Index].Buffer)); 351 352 /* Increment the index and loop over next entires with the same ID */ 353 Index++; 354 } 355 } 356 357 /** 358 * @MUIClearStyledText 359 * 360 * Clears a portion of text from the console output, given the actual state style flag of the text. 361 * 362 * @param[in] Page 363 * The MUI (Multilingual User Interface) entry page number, as a unsigned long integer. 364 * 365 * @param[in] TextID 366 * The text identification number (ID), as an integer. The parameter is used to identify 367 * its MUI properties like the coordinates, text style flag and its buffer content. 368 * 369 * @param[in] Flags 370 * The text style flag, as an integer. The flag determines the style of the text, such 371 * as being highlighted, underlined, high padding and so on. 372 * 373 * @return 374 * Nothing. 375 * 376 */ 377 VOID 378 MUIClearStyledText( 379 IN ULONG Page, 380 IN INT TextID, 381 IN INT Flags) 382 { 383 const MUI_ENTRY * entry; 384 ULONG Index = 0; 385 386 /* Get the MUI entry */ 387 entry = MUIGetEntry(Page, TextID); 388 389 if (!entry) 390 return; 391 392 /* Ensure that the text string given by the text ID and page is not NULL */ 393 while (entry[Index].Buffer != NULL) 394 { 395 /* If text ID is not correct, skip the entry */ 396 if (entry[Index].TextID != TextID) 397 { 398 Index++; 399 continue; 400 } 401 402 /* Now, begin removing the text by calling CONSOLE_ClearStyledText() */ 403 CONSOLE_ClearStyledText( 404 entry[Index].X, 405 entry[Index].Y, 406 Flags, 407 (USHORT)strlen(entry[Index].Buffer)); 408 409 /* Increment the index and loop over next entires with the same ID */ 410 Index++; 411 } 412 } 413 414 /** 415 * @MUISetText 416 * 417 * Prints a text to the console output. 418 * 419 * @param[in] Page 420 * The MUI (Multilingual User Interface) entry page number, as a unsigned long integer. 421 * 422 * @param[in] TextID 423 * The text identification number (ID), as an integer. The parameter is used to identify 424 * its MUI properties like the coordinates, text style flag and its buffer content. 425 * 426 * @return 427 * Nothing. 428 * 429 */ 430 VOID 431 MUISetText( 432 IN ULONG Page, 433 IN INT TextID) 434 { 435 const MUI_ENTRY * entry; 436 ULONG Index = 0; 437 438 /* Get the MUI entry */ 439 entry = MUIGetEntry(Page, TextID); 440 441 if (!entry) 442 return; 443 444 /* Ensure that the text string given by the text ID and page is not NULL */ 445 while (entry[Index].Buffer != NULL) 446 { 447 /* If text ID is not correct, skip the entry */ 448 if (entry[Index].TextID != TextID) 449 { 450 Index++; 451 continue; 452 } 453 454 /* Print the text to the console output by calling CONSOLE_SetTextXY() */ 455 CONSOLE_SetTextXY(entry[Index].X, entry[Index].Y, entry[Index].Buffer); 456 457 /* Increment the index and loop over next entires with the same ID */ 458 Index++; 459 } 460 } 461 462 /** 463 * @MUISetStyledText 464 * 465 * Prints a text to the console output, with a style for it. 466 * 467 * @param[in] Page 468 * The MUI (Multilingual User Interface) entry page number, as a unsigned long integer. 469 * 470 * @param[in] TextID 471 * The text identification number (ID), as an integer. The parameter is used to identify 472 * its MUI properties like the coordinates, text style flag and its buffer content. 473 * 474 * @param[in] Flags 475 * The text style flag, as an integer. The flag determines the style of the text, such 476 * as being highlighted, underlined, high padding and so on. 477 * 478 * @return 479 * Nothing. 480 * 481 */ 482 VOID 483 MUISetStyledText( 484 IN ULONG Page, 485 IN INT TextID, 486 IN INT Flags) 487 { 488 const MUI_ENTRY * entry; 489 ULONG Index = 0; 490 491 /* Get the MUI entry */ 492 entry = MUIGetEntry(Page, TextID); 493 494 if (!entry) 495 return; 496 497 /* Ensure that the text string given by the text ID and page is not NULL */ 498 while (entry[Index].Buffer != NULL) 499 { 500 /* If text ID is not correct, skip the entry */ 501 if (entry[Index].TextID != TextID) 502 { 503 Index++; 504 continue; 505 } 506 507 /* Print the text to the console output by calling CONSOLE_SetStyledText() */ 508 CONSOLE_SetStyledText(entry[Index].X, entry[Index].Y, Flags, entry[Index].Buffer); 509 510 /* Increment the index and loop over next entires with the same ID */ 511 Index++; 512 } 513 } 514 515 VOID 516 SetConsoleCodePage(VOID) 517 { 518 UINT wCodePage; 519 520 #if 0 521 ULONG lngIndex = 0; 522 523 while (ResourceList[lngIndex].MuiPages != NULL) 524 { 525 if (_wcsicmp(ResourceList[lngIndex].LanguageID, SelectedLanguageId) == 0) 526 { 527 wCodePage = (UINT) wcstoul(ResourceList[lngIndex].OEMCPage, NULL, 10); 528 SetConsoleOutputCP(wCodePage); 529 return; 530 } 531 532 lngIndex++; 533 } 534 #else 535 wCodePage = (UINT)wcstoul(MUIGetOEMCodePage(SelectedLanguageId), NULL, 10); 536 SetConsoleOutputCP(wCodePage); 537 #endif 538 } 539 540 /* EOF */ 541