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.

617 lines
11 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. efidisp.c
  5. Author:
  6. Create It. 21-Nov-2000 (andrewr)
  7. Abstract:
  8. This file contains utility routines for manipulating the EFI
  9. SIMPLE_CONSOLE_OUTPUT interface
  10. --*/
  11. #include "bldr.h"
  12. #include "bootefi.h"
  13. #include "efi.h"
  14. #include "efip.h"
  15. #include "flop.h"
  16. //
  17. // Externals
  18. //
  19. extern EFI_HANDLE EfiImageHandle;
  20. extern EFI_SYSTEM_TABLE *EfiST;
  21. extern EFI_BOOT_SERVICES *EfiBS;
  22. extern EFI_RUNTIME_SERVICES *EfiRS;
  23. extern BOOLEAN GoneVirtual;
  24. BOOLEAN gInverse = FALSE;
  25. ULONG
  26. BlEfiGetLinesPerRow(
  27. VOID
  28. )
  29. /*++
  30. Routine Description:
  31. Gets the number of lines per EFI console row.
  32. Arguments:
  33. None.
  34. Return Value:
  35. ULONG - number of lines.
  36. --*/
  37. {
  38. //
  39. // TODO: read the modes to determine lines/row.
  40. //
  41. // for now we just support 80x25
  42. //
  43. return 25;
  44. }
  45. ULONG
  46. BlEfiGetColumnsPerLine(
  47. VOID
  48. )
  49. /*++
  50. Routine Description:
  51. Gets the number of columns per EFI console line.
  52. Arguments:
  53. None.
  54. Return Value:
  55. ULONG - number of columns.
  56. --*/
  57. {
  58. //
  59. // TODO: read the modes to determine columns/line.
  60. //
  61. // for now we just support 80x25
  62. //
  63. return 80;
  64. }
  65. BOOLEAN
  66. BlEfiClearDisplay(
  67. VOID
  68. )
  69. /*++
  70. Routine Description:
  71. Clears the display.
  72. Arguments:
  73. None.
  74. Return Value:
  75. BOOLEAN - TRUE if the call succeeded.
  76. --*/
  77. {
  78. EFI_STATUS Status;
  79. //
  80. // you must be in physical mode to call EFI
  81. //
  82. FlipToPhysical();
  83. Status = EfiST->ConOut->ClearScreen(EfiST->ConOut);
  84. FlipToVirtual();
  85. return (Status == EFI_SUCCESS);
  86. }
  87. BOOLEAN
  88. BlEfiClearToEndOfDisplay(
  89. VOID
  90. )
  91. /*++
  92. Routine Description:
  93. Clears from the current cursor position to the end of the display.
  94. Arguments:
  95. None.
  96. Return Value:
  97. BOOLEAN - TRUE if the call succeeded.
  98. --*/
  99. {
  100. ULONG i,j, LinesPerRow,ColumnsPerLine;
  101. BOOLEAN FirstTime = TRUE;
  102. //
  103. // you must be in physical mode to call EFI
  104. //
  105. FlipToPhysical();
  106. LinesPerRow = BlEfiGetLinesPerRow();
  107. ColumnsPerLine = BlEfiGetColumnsPerLine();
  108. for (i = EfiST->ConOut->Mode->CursorRow; i<= LinesPerRow; i++) {
  109. j = FirstTime
  110. ? EfiST->ConOut->Mode->CursorColumn
  111. : 0 ;
  112. FirstTime = FALSE;
  113. for (; j <= ColumnsPerLine; j++) {
  114. EfiST->ConOut->SetCursorPosition(
  115. EfiST->ConOut,
  116. i,
  117. j);
  118. //
  119. // outputting a space should clear the current character
  120. //
  121. EfiST->ConOut->OutputString( EfiST->ConOut,
  122. L" " );
  123. }
  124. }
  125. //
  126. // flip back into virtual mode and return
  127. //
  128. FlipToVirtual();
  129. return(TRUE);
  130. }
  131. BOOLEAN
  132. BlEfiClearToEndOfLine(
  133. VOID
  134. )
  135. /*++
  136. Routine Description:
  137. Clears from the current cursor position to the end of the line.
  138. Arguments:
  139. None.
  140. Return Value:
  141. BOOLEAN - TRUE if the call succeeded.
  142. --*/
  143. {
  144. ULONG i, ColumnsPerLine;
  145. ULONG x, y;
  146. ColumnsPerLine = BlEfiGetColumnsPerLine();
  147. //
  148. // save current cursor position
  149. //
  150. BlEfiGetCursorPosition( &x, &y );
  151. FlipToPhysical();
  152. for (i = EfiST->ConOut->Mode->CursorColumn; i <= ColumnsPerLine; i++) {
  153. EfiST->ConOut->SetCursorPosition(
  154. EfiST->ConOut,
  155. i,
  156. EfiST->ConOut->Mode->CursorRow);
  157. //
  158. // outputting a space should clear the current character
  159. //
  160. EfiST->ConOut->OutputString( EfiST->ConOut,
  161. L" " );
  162. }
  163. //
  164. // restore the current cursor position
  165. //
  166. EfiST->ConOut->SetCursorPosition(
  167. EfiST->ConOut,
  168. x,
  169. y );
  170. FlipToVirtual();
  171. return(TRUE);
  172. }
  173. BOOLEAN
  174. BlEfiGetCursorPosition(
  175. OUT PULONG x, OPTIONAL
  176. OUT PULONG y OPTIONAL
  177. )
  178. /*++
  179. Routine Description:
  180. retrieves the current cursor position
  181. Arguments:
  182. x - if specified, receives the current cursor column.
  183. y - if specified, receives the current cursor row.
  184. Return Value:
  185. BOOLEAN - TRUE if the call succeeded.
  186. --*/
  187. {
  188. FlipToPhysical();
  189. if (x) {
  190. *x = EfiST->ConOut->Mode->CursorColumn;
  191. }
  192. if (y) {
  193. *y = EfiST->ConOut->Mode->CursorRow;
  194. }
  195. FlipToVirtual();
  196. return(TRUE);
  197. }
  198. BOOLEAN
  199. BlEfiPositionCursor(
  200. IN ULONG Column,
  201. IN ULONG Row
  202. )
  203. /*++
  204. Routine Description:
  205. Sets the current cursor position.
  206. Arguments:
  207. Column - column to set (x coordinate)
  208. Row - row to set (y coordinate)
  209. Return Value:
  210. BOOLEAN - TRUE if the call succeeded.
  211. --*/
  212. {
  213. EFI_STATUS Status;
  214. FlipToPhysical();
  215. Status = EfiST->ConOut->SetCursorPosition(EfiST->ConOut,Column,Row);
  216. FlipToVirtual();
  217. return (Status == EFI_SUCCESS);
  218. }
  219. BOOLEAN
  220. BlEfiEnableCursor(
  221. BOOLEAN bVisible
  222. )
  223. /*++
  224. Routine Description:
  225. Turns on or off the input cursor.
  226. Arguments:
  227. bVisible - TRUE indicates that the cursor should be made visible.
  228. Return Value:
  229. BOOLEAN - TRUE if the call succeeded.
  230. --*/
  231. {
  232. EFI_STATUS Status;
  233. FlipToPhysical();
  234. Status = EfiST->ConOut->EnableCursor( EfiST->ConOut, bVisible );
  235. FlipToVirtual();
  236. return (Status == EFI_SUCCESS);
  237. }
  238. BOOLEAN
  239. BlEfiSetAttribute(
  240. ULONG Attribute
  241. )
  242. /*++
  243. Routine Description:
  244. Sets the current attribute for the console.
  245. This routines switches between the ATT_* constants into the EFI_* display
  246. constants. Not all of the ATT_ flags can be supported under EFI, so we
  247. make a best guess.
  248. Arguments:
  249. None.
  250. Return Value:
  251. BOOLEAN - TRUE if the call succeeded.
  252. --*/
  253. {
  254. EFI_STATUS Status;
  255. UINTN foreground,background;
  256. UINTN EfiAttribute;
  257. switch (Attribute & 0xf) {
  258. case ATT_FG_BLACK:
  259. foreground = EFI_BLACK;
  260. break;
  261. case ATT_FG_RED:
  262. foreground = EFI_RED;
  263. break;
  264. case ATT_FG_GREEN:
  265. foreground = EFI_GREEN;
  266. break;
  267. case ATT_FG_YELLOW:
  268. foreground = EFI_YELLOW;
  269. break;
  270. case ATT_FG_BLUE:
  271. foreground = EFI_BLUE;
  272. break;
  273. case ATT_FG_MAGENTA:
  274. foreground = EFI_MAGENTA;
  275. break;
  276. case ATT_FG_CYAN:
  277. foreground = EFI_CYAN;
  278. break;
  279. case ATT_FG_WHITE:
  280. foreground = EFI_LIGHTGRAY; // this is a best guess
  281. break;
  282. case ATT_FG_INTENSE:
  283. foreground = EFI_WHITE; // this is a best guess
  284. break;
  285. default:
  286. // you may fall into this for blinking attribute, etc.
  287. foreground = EFI_WHITE;
  288. }
  289. switch ( Attribute & ( 0xf << 4)) {
  290. case ATT_BG_BLACK:
  291. background = EFI_BACKGROUND_BLACK;
  292. break;
  293. case ATT_BG_RED:
  294. background = EFI_BACKGROUND_RED;
  295. break;
  296. case ATT_BG_GREEN:
  297. background = EFI_BACKGROUND_GREEN;
  298. break;
  299. case ATT_BG_YELLOW:
  300. // there is no yellow background in EFI
  301. background = EFI_BACKGROUND_CYAN;
  302. break;
  303. case ATT_BG_BLUE:
  304. background = EFI_BACKGROUND_BLUE;
  305. break;
  306. case ATT_BG_MAGENTA:
  307. background = EFI_BACKGROUND_MAGENTA;
  308. break;
  309. case ATT_BG_CYAN:
  310. background = EFI_BACKGROUND_CYAN;
  311. break;
  312. case ATT_BG_WHITE:
  313. // there is no white background in EFI
  314. background = EFI_BACKGROUND_LIGHTGRAY;
  315. break;
  316. case ATT_BG_INTENSE:
  317. // there is no intense (or white) background in EFI
  318. background = EFI_BACKGROUND_LIGHTGRAY;
  319. break;
  320. default:
  321. background = EFI_BACKGROUND_LIGHTGRAY;
  322. break;
  323. }
  324. EfiAttribute = foreground | background ;
  325. FlipToPhysical();
  326. Status = EfiST->ConOut->SetAttribute(EfiST->ConOut,EfiAttribute);
  327. FlipToVirtual();
  328. return (Status == EFI_SUCCESS);
  329. }
  330. BOOLEAN
  331. BlEfiSetInverseMode(
  332. BOOLEAN fInverseOn
  333. )
  334. /*++
  335. Routine Description:
  336. Sets the console text to an inverse attribute.
  337. Since EFI doesn't support the concept of inverse, we have
  338. to make a best guess at this. Note that if you clear the
  339. display, etc., then the entire display will be set to this
  340. attribute.
  341. Arguments:
  342. None.
  343. Return Value:
  344. BOOLEAN - TRUE if the call succeeded.
  345. --*/
  346. {
  347. EFI_STATUS Status;
  348. UINTN EfiAttribute,foreground,background;
  349. //
  350. // if it's already on, then just return.
  351. //
  352. if (fInverseOn && gInverse) {
  353. return(TRUE);
  354. }
  355. //
  356. // if it's already off, then just return.
  357. //
  358. if (!fInverseOn && !gInverse) {
  359. return(TRUE);
  360. }
  361. FlipToPhysical();
  362. //
  363. // get the current attribute and switch it.
  364. //
  365. EfiAttribute = EfiST->ConOut->Mode->Attribute;
  366. foreground = EfiAttribute & 0xf;
  367. background = (EfiAttribute & 0xf0) >> 4 ;
  368. EfiAttribute = background | foreground;
  369. Status = EfiST->ConOut->SetAttribute(EfiST->ConOut,EfiAttribute);
  370. FlipToVirtual();
  371. gInverse = !gInverse;
  372. return (Status == EFI_SUCCESS);
  373. }
  374. //
  375. // Array of EFI drawing characters.
  376. //
  377. // This array MUST MATCH the GraphicsChar enumerated type in bldr.h.
  378. //
  379. USHORT EfiDrawingArray[GraphicsCharMax] = {
  380. BOXDRAW_DOUBLE_DOWN_RIGHT,
  381. BOXDRAW_DOUBLE_DOWN_LEFT,
  382. BOXDRAW_DOUBLE_UP_RIGHT,
  383. BOXDRAW_DOUBLE_UP_LEFT,
  384. BOXDRAW_DOUBLE_VERTICAL,
  385. BOXDRAW_DOUBLE_HORIZONTAL,
  386. BLOCKELEMENT_FULL_BLOCK,
  387. BLOCKELEMENT_LIGHT_SHADE
  388. };
  389. USHORT
  390. BlEfiGetGraphicsChar(
  391. IN GraphicsChar WhichOne
  392. )
  393. /*++
  394. Routine Description:
  395. Gets the appropriate mapping character.
  396. Arguments:
  397. GraphicsChar - enumerated type indicating character to be retrieved.
  398. Return Value:
  399. USHORT - EFI drawing character.
  400. --*/
  401. {
  402. //
  403. // just return a space if the input it out of range
  404. //
  405. if (WhichOne >= GraphicsCharMax) {
  406. return(L' ');
  407. }
  408. return(EfiDrawingArray[WhichOne]);
  409. }
  410. #if DBG
  411. VOID
  412. DBG_EFI_PAUSE(
  413. VOID
  414. )
  415. {
  416. EFI_EVENT EventArray[2];
  417. EFI_INPUT_KEY Key;
  418. UINTN num;
  419. if (GoneVirtual) {
  420. FlipToPhysical();
  421. }
  422. EventArray[0] = EfiST->ConIn->WaitForKey;
  423. EventArray[1] = NULL;
  424. EfiBS->WaitForEvent(1,EventArray,&num);
  425. //
  426. // reset the event
  427. //
  428. EfiST->ConIn->ReadKeyStroke( EfiST->ConIn, &Key );
  429. if (GoneVirtual) {
  430. FlipToVirtual();
  431. }
  432. }
  433. #else
  434. VOID
  435. DBG_EFI_PAUSE(
  436. VOID
  437. )
  438. {
  439. NOTHING;
  440. }
  441. #endif