Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

657 lines
11 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. display.c
  5. Author:
  6. Thomas Parslow [TomP] Feb-13-1991
  7. Reworked substantially in Tokyo 7-July-95 (tedm)
  8. Port from ARC-BIOS to EFI 22-Nov-2000 (andrewr)
  9. Abstract:
  10. This file contains an interface to the screen that is independent
  11. of the screen type actually being written to. The module serves
  12. as a layer between OS loader applications and the EFI services
  13. that do the actual legwork of writing to the default console
  14. handlers.
  15. --*/
  16. #include "bldr.h"
  17. #include "bootefi.h"
  18. #include "efi.h"
  19. #include "efip.h"
  20. #include "flop.h"
  21. //
  22. // Externals
  23. //
  24. extern EFI_HANDLE EfiImageHandle;
  25. extern EFI_SYSTEM_TABLE *EfiST;
  26. extern EFI_BOOT_SERVICES *EfiBS;
  27. extern EFI_RUNTIME_SERVICES *EfiRS;
  28. extern EFI_GUID EfiDevicePathProtocol;
  29. extern EFI_GUID EfiBlockIoProtocol;
  30. extern BOOLEAN GoneVirtual;
  31. #define ZLEN_SHORT(x) ((x < 0x10) + (x < 0x100) + (x < 0x1000))
  32. #define ZLEN_LONG(x) ((x < 0x10) + (x < 0x100) + (x < 0x1000) + \
  33. (x < 0x10000) + (x < 0x100000)+(x < 0x1000000)+(x < 0x10000000))
  34. //
  35. // Current screen position.
  36. //
  37. USHORT TextColumn = 0;
  38. USHORT TextRow = 0;
  39. //
  40. // Current text attribute
  41. //
  42. UCHAR TextCurrentAttribute = 0x07; // start with white on black.
  43. //
  44. // Internal routines
  45. //
  46. VOID
  47. puti(
  48. LONG
  49. );
  50. VOID
  51. putx(
  52. ULONG
  53. );
  54. VOID
  55. putu(
  56. ULONG
  57. );
  58. VOID
  59. putwS(
  60. PUNICODE_STRING String
  61. );
  62. VOID
  63. putS(
  64. PCWSTR String
  65. );
  66. VOID
  67. puts(
  68. PCSTR String
  69. );
  70. VOID
  71. BlPrint(
  72. PTCHAR cp,
  73. ...
  74. )
  75. /*++
  76. Routine Description:
  77. Standard printf function with a subset of formating features supported.
  78. Currently handles
  79. %d, %ld - signed short, signed long
  80. %u, %lu - unsigned short, unsigned long
  81. %c, %s - character, string
  82. %x, %lx - unsigned print in hex, unsigned long print in hex
  83. %C, %S - ansi character, string
  84. %wS - counted UNICODE_STRING
  85. Does not do:
  86. - field width specification
  87. - floating point.
  88. Arguments:
  89. cp - pointer to the format string, text string.
  90. Returns:
  91. Nothing
  92. --*/
  93. {
  94. ULONG l;
  95. ULONG Count;
  96. TCHAR ch;
  97. ULONG DeviceId;
  98. TCHAR b,c;
  99. PTSTR FormatString;
  100. va_list args;
  101. FormatString = cp;
  102. DeviceId = BlConsoleOutDeviceId;
  103. va_start(args, cp);
  104. //
  105. // Process the arguments using the descriptor string
  106. //
  107. while(*FormatString != TEXT('\0')) {
  108. b = *FormatString;
  109. FormatString += 1;
  110. if(b == TEXT('%')) {
  111. c = *FormatString;
  112. FormatString += 1;
  113. switch (c) {
  114. case TEXT('d'):
  115. puti((LONG)va_arg(args, LONG));
  116. break;
  117. case TEXT('s'):
  118. putS((PCWSTR)va_arg(args, PWSTR));
  119. break;
  120. case TEXT('S'):
  121. puts((PCSTR)va_arg(args, PSTR));
  122. break;
  123. case TEXT('c'):
  124. ch = (WCHAR)va_arg( args, WCHAR );
  125. ArcWrite(DeviceId, &ch, 1*sizeof(WCHAR), &Count);
  126. break;
  127. case TEXT('C'):
  128. ch = (CHAR)va_arg( args, CHAR );
  129. ArcWrite(DeviceId, &ch, 1*sizeof(CHAR), &Count);
  130. break;
  131. case TEXT('x'):
  132. //note that this doesn't currently support zero padding.
  133. putx((ULONG)va_arg( args, ULONG));
  134. break;
  135. case TEXT('u'):
  136. putu( (ULONG)va_arg( args, ULONG ));
  137. break;
  138. case TEXT('w'):
  139. c = *FormatString;
  140. FormatString += 1;
  141. switch (c) {
  142. case TEXT('S'):
  143. case TEXT('Z'):
  144. putwS((PUNICODE_STRING)va_arg( args, PUNICODE_STRING));
  145. break;
  146. }
  147. break;
  148. case TEXT('l'):
  149. c = *FormatString;
  150. FormatString += 1;
  151. switch(c) {
  152. case TEXT('0'):
  153. break;
  154. case TEXT('u'):
  155. putu(va_arg( args, ULONG));
  156. break;
  157. case TEXT('x'):
  158. //note that this doesn't currently support zero padding
  159. putx(va_arg( args, ULONG));
  160. break;
  161. case TEXT('d'):
  162. puti(va_arg( args, ULONG));
  163. break;
  164. }
  165. break;
  166. default :
  167. ch = (TCHAR)b;
  168. ArcWrite(DeviceId, &ch, 1*sizeof(TCHAR), &Count);
  169. ch = (TCHAR)c;
  170. ArcWrite(DeviceId, &ch, 1*sizeof(TCHAR), &Count);
  171. }
  172. } else {
  173. ArcWrite(DeviceId, FormatString - 1, 1*sizeof(TCHAR), &Count);
  174. }
  175. }
  176. va_end(args);
  177. #if 0
  178. //
  179. // This code pauses the system after each BlPrint. You must enter
  180. // a character to continue. This is used for debugging
  181. //
  182. ArcRead(BlConsoleInDeviceId, &l, 1, &Count);
  183. #endif
  184. }
  185. VOID
  186. putwS(
  187. PUNICODE_STRING String
  188. )
  189. /*++
  190. Routine Description:
  191. Writes counted unicode string to the display at the current
  192. cursor position.
  193. Arguments:
  194. String - pointer to unicode string to display
  195. Returns:
  196. Nothing
  197. --*/
  198. {
  199. ULONG i;
  200. ULONG Count;
  201. for(i=0; i < String->Length; i++) {
  202. ArcWrite(BlConsoleOutDeviceId, &String->Buffer[i], 1*sizeof(WCHAR), &Count);
  203. }
  204. }
  205. VOID
  206. puts(
  207. PCSTR AnsiString
  208. )
  209. /*++
  210. Routine Description:
  211. Writes an ANSI string to the display at the current cursor position.
  212. Arguments:
  213. String - pointer to ANSI string to display
  214. Returns:
  215. Nothing
  216. --*/
  217. {
  218. ULONG i;
  219. ULONG Count;
  220. WCHAR Char;
  221. PCSTR p;
  222. p = AnsiString;
  223. while (*p != '\0') {
  224. Char = (WCHAR)*p;
  225. ArcWrite(BlConsoleOutDeviceId, &Char, sizeof(WCHAR), &Count);
  226. p += 1;
  227. }
  228. }
  229. VOID
  230. putS(
  231. PCWSTR UnicodeString
  232. )
  233. /*++
  234. Routine Description:
  235. Writes an ANSI string to the display at the current cursor position.
  236. Arguments:
  237. String - pointer to ANSI string to display
  238. Returns:
  239. Nothing
  240. --*/
  241. {
  242. ULONG i;
  243. ULONG Count;
  244. WCHAR Char;
  245. PCWSTR p;
  246. p = UnicodeString;
  247. while (*p != L'\0') {
  248. Char = *p;
  249. ArcWrite(BlConsoleOutDeviceId, &Char, sizeof(WCHAR), &Count);
  250. p += 1;
  251. }
  252. }
  253. VOID
  254. putx(
  255. ULONG x
  256. )
  257. /*++
  258. Routine Description:
  259. Writes hex long to the display at the current cursor position.
  260. Arguments:
  261. x - ulong to write
  262. Returns:
  263. Nothing
  264. --*/
  265. {
  266. ULONG j;
  267. ULONG Count;
  268. _TUCHAR ch;
  269. if(x/16) {
  270. putx(x/16);
  271. }
  272. if((j=x%16) > 9) {
  273. ch = (_TUCHAR)(j+TEXT('A')-10);
  274. ArcWrite(BlConsoleOutDeviceId, &ch, 1*sizeof(_TUCHAR), &Count);
  275. } else {
  276. ch = (_TUCHAR)(j+TEXT('0'));
  277. ArcWrite(BlConsoleOutDeviceId, &ch, 1*sizeof(_TUCHAR), &Count);
  278. }
  279. }
  280. VOID
  281. puti(
  282. LONG i
  283. )
  284. /*++
  285. Routine Description:
  286. Writes a long integer on the display at the current cursor position.
  287. Arguments:
  288. i - the integer to write to the display.
  289. Returns:
  290. Nothing
  291. --*/
  292. {
  293. ULONG Count;
  294. _TUCHAR ch;
  295. if(i<0) {
  296. i = -i;
  297. ch = TEXT('-');
  298. ArcWrite(BlConsoleOutDeviceId, &ch, 1*sizeof(_TUCHAR), &Count);
  299. }
  300. if(i/10) {
  301. puti(i/10);
  302. }
  303. ch = (_TUCHAR)((i%10)+TEXT('0'));
  304. ArcWrite(BlConsoleOutDeviceId, &ch, 1*sizeof(_TUCHAR), &Count);
  305. }
  306. VOID
  307. putu(
  308. ULONG u
  309. )
  310. /*++
  311. Routine Description:
  312. Write an unsigned long to display
  313. Arguments:
  314. u - unsigned
  315. Returns:
  316. Nothing
  317. --*/
  318. {
  319. ULONG Count;
  320. _TUCHAR ch;
  321. if(u/10) {
  322. putu(u/10);
  323. }
  324. ch = (_TUCHAR)((u%10)+TEXT('0'));
  325. ArcWrite(BlConsoleOutDeviceId, &ch, 1*sizeof(_TUCHAR), &Count);
  326. }
  327. #if 0
  328. VOID
  329. pTextCharOut(
  330. IN UCHAR c
  331. )
  332. {
  333. if(DbcsLangId) {
  334. //
  335. // Single-byte only
  336. //
  337. TextGrCharOut(&c);
  338. } else {
  339. TextTmCharOut(&c);
  340. }
  341. }
  342. #endif
  343. VOID
  344. TextCharOut(
  345. IN PWCHAR pc
  346. )
  347. {
  348. WCHAR Text[2];
  349. Text[0] = *pc;
  350. Text[1] = L'\0';
  351. if (GoneVirtual) {
  352. FlipToPhysical();
  353. }
  354. EfiST->ConOut->OutputString(EfiST->ConOut,Text);
  355. if (GoneVirtual) {
  356. FlipToVirtual();
  357. }
  358. #if 0
  359. if(DbcsLangId) {
  360. return(TextGrCharOut(pc));
  361. } else {
  362. return(TextTmCharOut(pc));
  363. }
  364. #endif
  365. }
  366. VOID
  367. TextStringOut(
  368. IN PWCHAR String
  369. )
  370. {
  371. PWCHAR p = String;
  372. while (*p) {
  373. TextCharOut(p);
  374. p += 1;
  375. }
  376. #if 0
  377. if(DbcsLangId) {
  378. TextGrStringOut(String);
  379. } else {
  380. TextTmStringOut(String);
  381. }
  382. #endif
  383. }
  384. VOID
  385. TextSetCurrentAttribute(
  386. IN UCHAR Attribute
  387. )
  388. /*++
  389. Routine Description:
  390. Sets the character attribute to be used for subsequent text display.
  391. Arguments:
  392. Returns:
  393. Nothing.
  394. --*/
  395. {
  396. TextCurrentAttribute = Attribute;
  397. #ifdef EFI
  398. BlEfiSetAttribute( Attribute );
  399. #else
  400. if(DbcsLangId) {
  401. TextGrSetCurrentAttribute(Attribute);
  402. } else {
  403. TextTmSetCurrentAttribute(Attribute);
  404. }
  405. #endif
  406. }
  407. UCHAR
  408. TextGetCurrentAttribute(
  409. VOID
  410. )
  411. {
  412. return(TextCurrentAttribute);
  413. }
  414. VOID
  415. TextFillAttribute(
  416. IN UCHAR Attribute,
  417. IN ULONG Length
  418. )
  419. /*++
  420. Routine Description:
  421. Changes the screen attribute starting at the current cursor position.
  422. The cursor is not moved.
  423. Arguments:
  424. Attribute - Supplies the new attribute
  425. Length - Supplies the length of the area to change (in bytes)
  426. Return Value:
  427. None.
  428. --*/
  429. {
  430. #ifdef EFI
  431. ULONG x,y, OrigX, OrigY;
  432. BOOLEAN FirstTime = TRUE;
  433. BlEfiGetCursorPosition( &OrigX, &OrigY );
  434. x = OrigX;
  435. y = OrigY;
  436. for (y = OrigY; y < BlEfiGetLinesPerRow() ; y++) {
  437. x = FirstTime
  438. ? OrigX
  439. : 0 ;
  440. FirstTime = FALSE;
  441. for (; x <= BlEfiGetColumnsPerLine(); x++) {
  442. BlEfiPositionCursor( y, x );
  443. BlEfiSetAttribute( Attribute );
  444. }
  445. }
  446. BlEfiPositionCursor( OrigY, OrigX );
  447. #else
  448. if(DbcsLangId) {
  449. TextGrFillAttribute(Attribute,Length);
  450. } else {
  451. TextTmFillAttribute(Attribute,Length);
  452. }
  453. #endif
  454. }
  455. _TUCHAR
  456. TextGetGraphicsCharacter(
  457. IN GraphicsChar WhichOne
  458. )
  459. {
  460. #ifdef EFI
  461. return(BlEfiGetGraphicsChar( WhichOne ));
  462. #else
  463. return((WhichOne < GraphicsCharMax)
  464. ? (DbcsLangId
  465. ? TextGrGetGraphicsChar(WhichOne)
  466. : TextTmGetGraphicsChar(WhichOne))
  467. : TEXT(' '));
  468. #endif
  469. }