Leaked source code of windows server 2003
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.

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