vidcon.c 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085
  1. /*++
  2. Copyright (c) 2014 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. vidcon.c
  5. Abstract:
  6. This module
  7. Author:
  8. Evan Green
  9. Environment:
  10. Kernel
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. //
  16. // Define away the API decorator.
  17. //
  18. #define KERNEL_API
  19. #include "ueficore.h"
  20. #include <minoca/kernel/sysres.h>
  21. #include <minoca/lib/basevid.h>
  22. #include <minoca/uefi/protocol/graphout.h>
  23. //
  24. // --------------------------------------------------------------------- Macros
  25. //
  26. //
  27. // This macro returns a pointer to the disk I/O data given a pointer to the
  28. // block I/O protocol instance.
  29. //
  30. #define EFI_GRAPHICS_CONSOLE_FROM_THIS(_TextOutput) \
  31. PARENT_STRUCTURE(_TextOutput, EFI_GRAPHICS_CONSOLE, TextOutput)
  32. //
  33. // ---------------------------------------------------------------- Definitions
  34. //
  35. #define EFI_GRAPHICS_CONSOLE_MAGIC 0x43646956 // 'CdiV'
  36. //
  37. // ------------------------------------------------------ Data Type Definitions
  38. //
  39. /*++
  40. Structure Description:
  41. This structure describes the internal data structure of a graphical
  42. console.
  43. Members:
  44. Magic - Stores the magic constant EFI_GRAPHICS_CONSOLE_MAGIC.
  45. Graphics - Stores a pointer to the graphics output protocol.
  46. Handle - Stores the console handle.
  47. TextOutput - Stores the simple text output protocol.
  48. Mode - Stores the mode information.
  49. HorizontalResolution - Stores the horizontal resolution of the graphics
  50. device, in pixels.
  51. VerticalResolution - Stores the vertical resolution of the graphics device,
  52. in pixels.
  53. PixelsPerScanLine - Stores the number of pixels per scan line in the
  54. frame buffer.
  55. BitsPerPixel - Stores the width of a pixel in the frame buffer.
  56. GraphicsMode - Stores the graphics mode number the console was initialized
  57. on.
  58. --*/
  59. typedef struct _EFI_GRAPHICS_CONSOLE {
  60. UINTN Magic;
  61. EFI_GRAPHICS_OUTPUT_PROTOCOL *Graphics;
  62. EFI_HANDLE Handle;
  63. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL TextOutput;
  64. EFI_SIMPLE_TEXT_OUTPUT_MODE Mode;
  65. UINT32 HorizontalResolution;
  66. UINT32 VerticalResolution;
  67. UINT32 PixelsPerScanLine;
  68. UINT32 BitsPerPixel;
  69. UINT32 GraphicsMode;
  70. } EFI_GRAPHICS_CONSOLE, *PEFI_GRAPHICS_CONSOLE;
  71. //
  72. // ----------------------------------------------- Internal Function Prototypes
  73. //
  74. EFIAPI
  75. VOID
  76. EfipGraphicsOutputNotify (
  77. EFI_EVENT Event,
  78. VOID *Context
  79. );
  80. EFIAPI
  81. EFI_STATUS
  82. EfipGraphicsTextReset (
  83. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
  84. BOOLEAN ExtendedVerification
  85. );
  86. EFI_STATUS
  87. EfipGraphicsTextStringOut (
  88. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
  89. CHAR16 *String
  90. );
  91. EFIAPI
  92. EFI_STATUS
  93. EfipGraphicsTextTestString (
  94. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
  95. CHAR16 *String
  96. );
  97. EFIAPI
  98. EFI_STATUS
  99. EfipGraphicsTextQueryMode (
  100. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
  101. UINTN ModeNumber,
  102. UINTN *Columns,
  103. UINTN *Rows
  104. );
  105. EFIAPI
  106. EFI_STATUS
  107. EfipGraphicsTextSetMode (
  108. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
  109. UINTN ModeNumber
  110. );
  111. EFIAPI
  112. EFI_STATUS
  113. EfipGraphicsTextSetAttribute (
  114. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
  115. UINTN Attribute
  116. );
  117. EFIAPI
  118. EFI_STATUS
  119. EfipGraphicsTextClearScreen (
  120. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
  121. );
  122. EFIAPI
  123. EFI_STATUS
  124. EfipGraphicsTextSetCursorPosition (
  125. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
  126. UINTN Column,
  127. UINTN Row
  128. );
  129. EFIAPI
  130. EFI_STATUS
  131. EfipGraphicsTextEnableCursor (
  132. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
  133. BOOLEAN Visible
  134. );
  135. //
  136. // -------------------------------------------------------------------- Globals
  137. //
  138. EFI_GUID EfiGraphicsOutputProtocolGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
  139. EFI_GUID EfiSimpleTextOutputProtocolGuid = EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID;
  140. EFI_EVENT EfiGraphicsOutputNotifyEvent;
  141. VOID *EfiGraphicsOutputNotifyRegistration;
  142. //
  143. // For now, only install onto one graphics device.
  144. //
  145. BOOLEAN EfiGraphicsConsoleInstalled;
  146. EFI_GRAPHICS_CONSOLE EfiGraphicsConsoleTemplate = {
  147. EFI_GRAPHICS_CONSOLE_MAGIC,
  148. NULL,
  149. NULL,
  150. {
  151. EfipGraphicsTextReset,
  152. EfipGraphicsTextStringOut,
  153. EfipGraphicsTextTestString,
  154. EfipGraphicsTextQueryMode,
  155. EfipGraphicsTextSetMode,
  156. EfipGraphicsTextSetAttribute,
  157. EfipGraphicsTextClearScreen,
  158. EfipGraphicsTextSetCursorPosition,
  159. EfipGraphicsTextEnableCursor,
  160. NULL
  161. }
  162. };
  163. BASE_VIDEO_CONTEXT EfiVideoContext;
  164. BASE_VIDEO_PALETTE EfiVideoPalette = {
  165. {
  166. BASE_VIDEO_COLOR_RGB(250, 250, 250),
  167. BASE_VIDEO_COLOR_RGB(0, 0, 0),
  168. BASE_VIDEO_COLOR_RGB(194, 54, 33),
  169. BASE_VIDEO_COLOR_RGB(37, 188, 36),
  170. BASE_VIDEO_COLOR_RGB(173, 173, 39),
  171. BASE_VIDEO_COLOR_RGB(73, 46, 225),
  172. BASE_VIDEO_COLOR_RGB(211, 56, 211),
  173. BASE_VIDEO_COLOR_RGB(51, 187, 200),
  174. BASE_VIDEO_COLOR_RGB(203, 204, 206),
  175. },
  176. {
  177. BASE_VIDEO_COLOR_RGB(255, 255, 170),
  178. BASE_VIDEO_COLOR_RGB(131, 131, 131),
  179. BASE_VIDEO_COLOR_RGB(252, 57, 31),
  180. BASE_VIDEO_COLOR_RGB(49, 231, 34),
  181. BASE_VIDEO_COLOR_RGB(234, 236, 35),
  182. BASE_VIDEO_COLOR_RGB(88, 51, 255),
  183. BASE_VIDEO_COLOR_RGB(249, 53, 248),
  184. BASE_VIDEO_COLOR_RGB(20, 240, 240),
  185. BASE_VIDEO_COLOR_RGB(233, 235, 237),
  186. },
  187. BASE_VIDEO_COLOR_RGB(35, 0, 35),
  188. BASE_VIDEO_COLOR_RGB(35, 0, 35),
  189. BASE_VIDEO_COLOR_RGB(250, 250, 250),
  190. BASE_VIDEO_COLOR_RGB(142, 40, 0),
  191. };
  192. //
  193. // ------------------------------------------------------------------ Functions
  194. //
  195. EFIAPI
  196. EFI_STATUS
  197. EfiGraphicsTextDriverEntry (
  198. EFI_HANDLE ImageHandle,
  199. EFI_SYSTEM_TABLE *SystemTable
  200. )
  201. /*++
  202. Routine Description:
  203. This routine initializes support for UEFI video consoles.
  204. Arguments:
  205. ImageHandle - Supplies the image handle for this driver. This is probably
  206. the firmware core image handle.
  207. SystemTable - Supplies a pointer to the system table.
  208. Return Value:
  209. EFI status code.
  210. --*/
  211. {
  212. //
  213. // Sign up to be notified whenever a new firmware volume block device
  214. // protocol crops up.
  215. //
  216. EfiGraphicsOutputNotifyEvent = EfiCoreCreateProtocolNotifyEvent(
  217. &EfiGraphicsOutputProtocolGuid,
  218. TPL_CALLBACK,
  219. EfipGraphicsOutputNotify,
  220. NULL,
  221. &EfiGraphicsOutputNotifyRegistration);
  222. ASSERT(EfiGraphicsOutputNotifyEvent != NULL);
  223. return EFI_SUCCESS;
  224. }
  225. //
  226. // --------------------------------------------------------- Internal Functions
  227. //
  228. EFIAPI
  229. VOID
  230. EfipGraphicsOutputNotify (
  231. EFI_EVENT Event,
  232. VOID *Context
  233. )
  234. /*++
  235. Routine Description:
  236. This routine is called when a new graphics output protocol appears in the
  237. system.
  238. Arguments:
  239. Event - Supplies a pointer to the event that fired.
  240. Context - Supplies an unused context pointer.
  241. Return Value:
  242. None.
  243. --*/
  244. {
  245. UINT32 BitsPerPixel;
  246. UINTN BufferSize;
  247. UINT32 CombinedMask;
  248. PEFI_GRAPHICS_CONSOLE Device;
  249. SYSTEM_RESOURCE_FRAME_BUFFER FrameBuffer;
  250. EFI_GRAPHICS_OUTPUT_PROTOCOL *Graphics;
  251. EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *GraphicsMode;
  252. EFI_HANDLE Handle;
  253. EFI_STATUS Status;
  254. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut;
  255. KSTATUS VideoStatus;
  256. //
  257. // Examine all new handles.
  258. //
  259. while (TRUE) {
  260. Status = EfiCoreLocateHandle(ByRegisterNotify,
  261. NULL,
  262. EfiGraphicsOutputNotifyRegistration,
  263. &BufferSize,
  264. &Handle);
  265. if (Status == EFI_NOT_FOUND) {
  266. break;
  267. }
  268. if (EFI_ERROR(Status)) {
  269. continue;
  270. }
  271. //
  272. // Get the graphics output protocol on the handle.
  273. //
  274. Status = EfiCoreHandleProtocol(Handle,
  275. &EfiGraphicsOutputProtocolGuid,
  276. (VOID **)&Graphics);
  277. if (EFI_ERROR(Status)) {
  278. ASSERT(FALSE);
  279. continue;
  280. }
  281. //
  282. // Skip any graphics protocols that aren't in graphical mode.
  283. //
  284. if ((Graphics->Mode == NULL) || (Graphics->Mode->Info == NULL) ||
  285. (Graphics->Mode->SizeOfInfo <
  286. sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION))) {
  287. continue;
  288. }
  289. GraphicsMode = Graphics->Mode->Info;
  290. if (GraphicsMode->PixelFormat >= PixelBltOnly) {
  291. continue;
  292. }
  293. //
  294. // For now, only install once.
  295. //
  296. if (EfiGraphicsConsoleInstalled != FALSE) {
  297. return;
  298. }
  299. //
  300. // Check to see if there is a simple text output protocol already
  301. // installed on this handle.
  302. //
  303. Status = EfiCoreHandleProtocol(Handle,
  304. &EfiSimpleTextOutputProtocolGuid,
  305. (VOID **)&TextOut);
  306. //
  307. // If there's a previously existing text output protocol, then
  308. // update the block device if it was created by this driver.
  309. //
  310. if (!EFI_ERROR(Status)) {
  311. Device = PARENT_STRUCTURE(TextOut,
  312. EFI_GRAPHICS_CONSOLE,
  313. TextOutput);
  314. if (Device->Magic == EFI_GRAPHICS_CONSOLE_MAGIC) {
  315. Device->Graphics = Graphics;
  316. }
  317. continue;
  318. }
  319. //
  320. // No text output protocol is present, create a new one.
  321. //
  322. Device = EfiCoreAllocateBootPool(sizeof(EFI_GRAPHICS_CONSOLE));
  323. if (Device == NULL) {
  324. return;
  325. }
  326. EfiCoreCopyMemory(Device,
  327. &EfiGraphicsConsoleTemplate,
  328. sizeof(EFI_GRAPHICS_CONSOLE));
  329. Device->Graphics = Graphics;
  330. Device->Handle = Handle;
  331. Device->TextOutput.Mode = &(Device->Mode);
  332. Device->VerticalResolution = GraphicsMode->VerticalResolution;
  333. Device->HorizontalResolution = GraphicsMode->HorizontalResolution;
  334. Device->PixelsPerScanLine = GraphicsMode->PixelsPerScanLine;
  335. Device->GraphicsMode = Graphics->Mode->Mode;
  336. Device->Mode.CursorVisible = TRUE;
  337. Device->Mode.Attribute = EFI_BACKGROUND_BLACK | EFI_LIGHTGRAY;
  338. EfiSetMem(&FrameBuffer, sizeof(SYSTEM_RESOURCE_FRAME_BUFFER), 0);
  339. FrameBuffer.Mode = BaseVideoModeFrameBuffer;
  340. FrameBuffer.Width = GraphicsMode->HorizontalResolution;
  341. FrameBuffer.Height = GraphicsMode->VerticalResolution;
  342. FrameBuffer.PixelsPerScanLine = GraphicsMode->PixelsPerScanLine;
  343. FrameBuffer.Header.PhysicalAddress = Graphics->Mode->FrameBufferBase;
  344. FrameBuffer.Header.VirtualAddress =
  345. (VOID *)(UINTN)(FrameBuffer.Header.PhysicalAddress);
  346. switch (GraphicsMode->PixelFormat) {
  347. case PixelRedGreenBlueReserved8BitPerColor:
  348. FrameBuffer.BitsPerPixel = 32;
  349. FrameBuffer.RedMask = 0x000000FF;
  350. FrameBuffer.GreenMask = 0x0000FF00;
  351. FrameBuffer.BlueMask = 0x00FF0000;
  352. break;
  353. case PixelBlueGreenRedReserved8BitPerColor:
  354. FrameBuffer.BitsPerPixel = 32;
  355. FrameBuffer.RedMask = 0x00FF0000;
  356. FrameBuffer.GreenMask = 0x0000FF00;
  357. FrameBuffer.BlueMask = 0x000000FF;
  358. break;
  359. case PixelBitMask:
  360. FrameBuffer.RedMask = GraphicsMode->PixelInformation.RedMask;
  361. FrameBuffer.GreenMask = GraphicsMode->PixelInformation.GreenMask;
  362. FrameBuffer.BlueMask = GraphicsMode->PixelInformation.BlueMask;
  363. CombinedMask = GraphicsMode->PixelInformation.RedMask |
  364. GraphicsMode->PixelInformation.GreenMask |
  365. GraphicsMode->PixelInformation.BlueMask |
  366. GraphicsMode->PixelInformation.ReservedMask;
  367. ASSERT(CombinedMask != 0);
  368. BitsPerPixel = 32;
  369. while ((BitsPerPixel != 0) &&
  370. ((CombinedMask & (1 << (BitsPerPixel - 1))) == 0)) {
  371. BitsPerPixel -= 1;
  372. }
  373. FrameBuffer.BitsPerPixel = BitsPerPixel;
  374. break;
  375. default:
  376. EfiCoreFreePool(Device);
  377. continue;
  378. }
  379. Device->BitsPerPixel = FrameBuffer.BitsPerPixel;
  380. FrameBuffer.Header.Size = FrameBuffer.PixelsPerScanLine *
  381. (FrameBuffer.BitsPerPixel / 8) *
  382. FrameBuffer.Height;
  383. FrameBuffer.Header.Type = SystemResourceFrameBuffer;
  384. VideoStatus = VidInitialize(&EfiVideoContext, &FrameBuffer);
  385. if (KSUCCESS(VideoStatus)) {
  386. VidSetPalette(&EfiVideoContext, &EfiVideoPalette, NULL);
  387. VidClearScreen(&EfiVideoContext, 0, 0, -1, -1);
  388. Status = EFI_SUCCESS;
  389. } else {
  390. Status = EFI_DEVICE_ERROR;
  391. }
  392. if (!EFI_ERROR(Status)) {
  393. Status = EfiCoreInstallProtocolInterface(
  394. &Handle,
  395. &EfiSimpleTextOutputProtocolGuid,
  396. EFI_NATIVE_INTERFACE,
  397. &(Device->TextOutput));
  398. ASSERT(!EFI_ERROR(Status));
  399. }
  400. if (EFI_ERROR(Status)) {
  401. EfiCoreFreePool(Device);
  402. } else {
  403. EfiGraphicsConsoleInstalled = TRUE;
  404. }
  405. }
  406. return;
  407. }
  408. EFIAPI
  409. EFI_STATUS
  410. EfipGraphicsTextReset (
  411. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
  412. BOOLEAN ExtendedVerification
  413. )
  414. /*++
  415. Routine Description:
  416. This routine resets the output device hardware and optionally runs
  417. diagnostics.
  418. Arguments:
  419. This - Supplies a pointer to the protocol instance.
  420. ExtendedVerification - Supplies a boolean indicating if the driver should
  421. perform diagnostics on reset.
  422. Return Value:
  423. EFI_SUCCESS on success.
  424. EFI_DEVICE_ERROR if the device is not functioning properly and could not be
  425. reset.
  426. --*/
  427. {
  428. PEFI_GRAPHICS_CONSOLE Console;
  429. Console = EFI_GRAPHICS_CONSOLE_FROM_THIS(This);
  430. ASSERT(Console->Magic == EFI_GRAPHICS_CONSOLE_MAGIC);
  431. This->SetAttribute(
  432. This,
  433. EFI_TEXT_ATTR(This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));
  434. return This->SetMode(This, Console->GraphicsMode);
  435. }
  436. EFI_STATUS
  437. EfipGraphicsTextStringOut (
  438. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
  439. CHAR16 *String
  440. )
  441. /*++
  442. Routine Description:
  443. This routine writes a (wide) string to the output device.
  444. Arguments:
  445. This - Supplies a pointer to the protocol instance.
  446. String - Supplies the null-terminated string to be displayed on the output
  447. device(s). All output devices must also support the Unicode drawing
  448. character codes defined in this file.
  449. Return Value:
  450. EFI_SUCCESS on success.
  451. EFI_DEVICE_ERROR if the device is not functioning properly and could not be
  452. written to.
  453. EFI_UNSUPPORTED if the output device's mode indicates some of the
  454. characters in the string could not be rendered and were skipped.
  455. --*/
  456. {
  457. CHAR8 Ascii[2];
  458. UINT32 CellHeight;
  459. UINT32 CellWidth;
  460. UINTN ColumnCount;
  461. PEFI_GRAPHICS_CONSOLE Console;
  462. UINTN CopySize;
  463. VOID *FrameBuffer;
  464. UINTN LastLineY;
  465. VOID *LineOne;
  466. EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;
  467. UINTN RowCount;
  468. EFI_STATUS Status;
  469. Console = EFI_GRAPHICS_CONSOLE_FROM_THIS(This);
  470. ASSERT(Console->Magic == EFI_GRAPHICS_CONSOLE_MAGIC);
  471. Mode = This->Mode;
  472. Status = This->QueryMode(This, Mode->Mode, &ColumnCount, &RowCount);
  473. if (EFI_ERROR(Status)) {
  474. return Status;
  475. }
  476. //
  477. // Skip it if the graphics output has been configured for a different mode
  478. // than the one initialized in.
  479. //
  480. if (Console->Graphics->Mode->Mode != Console->GraphicsMode) {
  481. return EFI_DEVICE_ERROR;
  482. }
  483. FrameBuffer = (VOID *)(UINTN)(Console->Graphics->Mode->FrameBufferBase);
  484. if (FrameBuffer == NULL) {
  485. return EFI_DEVICE_ERROR;
  486. }
  487. //
  488. // Calculate the number of bytes to copy when scrolling, which is the
  489. // number of console lines minus one.
  490. //
  491. CellWidth = EfiVideoContext.Font->CellWidth;
  492. CellHeight = EfiVideoContext.Font->CellHeight;
  493. CopySize = Console->PixelsPerScanLine * (Console->BitsPerPixel / 8) *
  494. ((RowCount - 1) * CellHeight);
  495. LineOne = FrameBuffer + (Console->PixelsPerScanLine *
  496. (Console->BitsPerPixel / 8) *
  497. CellHeight);
  498. //
  499. // Loop printing each character.
  500. //
  501. Ascii[1] = '\0';
  502. Status = EFI_SUCCESS;
  503. while (*String != L'\0') {
  504. if (*String == CHAR_BACKSPACE) {
  505. if (Mode->CursorColumn == 0) {
  506. if (Mode->CursorRow != 0) {
  507. Mode->CursorRow -= 1;
  508. }
  509. Mode->CursorColumn = ColumnCount - 1;
  510. } else {
  511. Mode->CursorColumn -= 1;
  512. }
  513. } else if (*String == CHAR_LINEFEED) {
  514. if (Mode->CursorRow < RowCount - 1) {
  515. Mode->CursorRow += 1;
  516. //
  517. // If already at the last line, scroll.
  518. //
  519. } else {
  520. EfiCopyMem(FrameBuffer, LineOne, CopySize);
  521. LastLineY = (RowCount - 1) * CellHeight;
  522. VidClearScreen(&EfiVideoContext,
  523. 0,
  524. LastLineY,
  525. ColumnCount * CellWidth,
  526. LastLineY + CellHeight);
  527. }
  528. } else if (*String == CHAR_CARRIAGE_RETURN) {
  529. Mode->CursorColumn = 0;
  530. } else if ((*String >= L' ') && (*String <= L'~')) {
  531. Ascii[0] = *String;
  532. //
  533. // If the cursor is in the last position, scroll.
  534. //
  535. if (Mode->CursorColumn >= ColumnCount - 1) {
  536. Mode->CursorColumn = 0;
  537. if (Mode->CursorRow == RowCount - 1) {
  538. EfiCopyMem(FrameBuffer, LineOne, CopySize);
  539. LastLineY = (RowCount - 1) * CellHeight;
  540. VidClearScreen(&EfiVideoContext,
  541. 0,
  542. LastLineY,
  543. ColumnCount * CellWidth,
  544. LastLineY + CellHeight);
  545. } else {
  546. Mode->CursorRow += 1;
  547. }
  548. }
  549. VidPrintString(&EfiVideoContext,
  550. Mode->CursorColumn,
  551. Mode->CursorRow,
  552. Ascii);
  553. Mode->CursorColumn += 1;
  554. //
  555. // Some of the characters could not be rendered.
  556. //
  557. } else {
  558. Status = EFI_UNSUPPORTED;
  559. }
  560. String += 1;
  561. }
  562. return EFI_SUCCESS;
  563. }
  564. EFIAPI
  565. EFI_STATUS
  566. EfipGraphicsTextTestString (
  567. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
  568. CHAR16 *String
  569. )
  570. /*++
  571. Routine Description:
  572. This routine verifies that all characters in a string can be output to the
  573. target device.
  574. Arguments:
  575. This - Supplies a pointer to the protocol instance.
  576. String - Supplies the null-terminated string to be examined for the output
  577. device(s).
  578. Return Value:
  579. EFI_SUCCESS on success.
  580. EFI_UNSUPPORTED if the output device's mode indicates some of the
  581. characters in the string could not be rendered and were skipped.
  582. --*/
  583. {
  584. EFI_STATUS Status;
  585. Status = EFI_SUCCESS;
  586. while (*String != L'\0') {
  587. if ((*String != CHAR_BACKSPACE) &&
  588. (*String != CHAR_LINEFEED) &&
  589. (*String != CHAR_CARRIAGE_RETURN) &&
  590. ((*String < L' ') || (*String > L'~'))) {
  591. Status = EFI_UNSUPPORTED;
  592. break;
  593. }
  594. String += 1;
  595. }
  596. return Status;
  597. }
  598. EFIAPI
  599. EFI_STATUS
  600. EfipGraphicsTextQueryMode (
  601. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
  602. UINTN ModeNumber,
  603. UINTN *Columns,
  604. UINTN *Rows
  605. )
  606. /*++
  607. Routine Description:
  608. This routine requests information for an available text mode that the
  609. output device(s) can support.
  610. Arguments:
  611. This - Supplies a pointer to the protocol instance.
  612. ModeNumber - Supplies the mode number to return information on.
  613. Columns - Supplies a pointer where the number of columns on the output
  614. device will be returned.
  615. Rows - Supplies a pointer where the number of rows on the output device
  616. will be returned.
  617. Return Value:
  618. EFI_SUCCESS on success.
  619. EFI_DEVICE_ERROR if the device had an error and could not complete the
  620. request.
  621. EFI_UNSUPPORTED if the mode number was not valid.
  622. --*/
  623. {
  624. PEFI_GRAPHICS_CONSOLE Console;
  625. Console = EFI_GRAPHICS_CONSOLE_FROM_THIS(This);
  626. ASSERT(Console->Magic == EFI_GRAPHICS_CONSOLE_MAGIC);
  627. if (ModeNumber == 0) {
  628. if (EfiVideoContext.Font == NULL) {
  629. return EFI_NOT_READY;
  630. }
  631. *Columns = Console->HorizontalResolution /
  632. EfiVideoContext.Font->CellWidth;
  633. *Rows = Console->VerticalResolution / EfiVideoContext.Font->CellHeight;
  634. return EFI_SUCCESS;
  635. }
  636. return EFI_UNSUPPORTED;
  637. }
  638. EFIAPI
  639. EFI_STATUS
  640. EfipGraphicsTextSetMode (
  641. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
  642. UINTN ModeNumber
  643. )
  644. /*++
  645. Routine Description:
  646. This routine sets the output device to a specified mode.
  647. Arguments:
  648. This - Supplies a pointer to the protocol instance.
  649. ModeNumber - Supplies the mode number to set.
  650. Return Value:
  651. EFI_SUCCESS on success.
  652. EFI_DEVICE_ERROR if the device had an error and could not complete the
  653. request.
  654. EFI_UNSUPPORTED if the mode number was not valid.
  655. --*/
  656. {
  657. if (ModeNumber != 0) {
  658. return EFI_UNSUPPORTED;
  659. }
  660. This->Mode->Mode = 0;
  661. This->ClearScreen(This);
  662. return EFI_SUCCESS;
  663. }
  664. EFIAPI
  665. EFI_STATUS
  666. EfipGraphicsTextSetAttribute (
  667. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
  668. UINTN Attribute
  669. )
  670. /*++
  671. Routine Description:
  672. This routine sets the background and foreground colors for the output
  673. string and clear screen functions.
  674. Arguments:
  675. This - Supplies a pointer to the protocol instance.
  676. Attribute - Supplies the attributes to set. Bits 0 to 3 are the foreground
  677. color, and bits 4 to 6 are the background color. All other bits must
  678. be zero. See the EFI_TEXT_ATTR macro.
  679. Return Value:
  680. EFI_SUCCESS on success.
  681. EFI_DEVICE_ERROR if the device had an error and could not complete the
  682. request.
  683. EFI_UNSUPPORTED if the attribute requested is not defined.
  684. --*/
  685. {
  686. This->Mode->Attribute = Attribute;
  687. return EFI_SUCCESS;
  688. }
  689. EFIAPI
  690. EFI_STATUS
  691. EfipGraphicsTextClearScreen (
  692. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
  693. )
  694. /*++
  695. Routine Description:
  696. This routine clears the output device(s) display to the currently selected
  697. background color.
  698. Arguments:
  699. This - Supplies a pointer to the protocol instance.
  700. Return Value:
  701. EFI_SUCCESS on success.
  702. EFI_DEVICE_ERROR if the device had an error and could not complete the
  703. request.
  704. EFI_UNSUPPORTED if the output device is not in a valid text mode.
  705. --*/
  706. {
  707. PEFI_GRAPHICS_CONSOLE Console;
  708. Console = EFI_GRAPHICS_CONSOLE_FROM_THIS(This);
  709. ASSERT(Console->Magic == EFI_GRAPHICS_CONSOLE_MAGIC);
  710. VidClearScreen(&EfiVideoContext, 0, 0, -1, -1);
  711. return This->SetCursorPosition(This, 0, 0);
  712. }
  713. EFIAPI
  714. EFI_STATUS
  715. EfipGraphicsTextSetCursorPosition (
  716. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
  717. UINTN Column,
  718. UINTN Row
  719. )
  720. /*++
  721. Routine Description:
  722. This routine sets the current coordinates of the cursor position.
  723. Arguments:
  724. This - Supplies a pointer to the protocol instance.
  725. Column - Supplies the desired column. This must be greater than or equal to
  726. zero and less than the number of columns as reported by the query mode
  727. function.
  728. Row - Supplies the desired row. This must be greater than or equal to zero
  729. and less than the number of rows as reported by the query mode function.
  730. Return Value:
  731. EFI_SUCCESS on success.
  732. EFI_DEVICE_ERROR if the device had an error and could not complete the
  733. request.
  734. EFI_UNSUPPORTED if the output device is not in a valid text mode, or the
  735. requested cursor position is out of range.
  736. --*/
  737. {
  738. UINTN ColumnCount;
  739. PEFI_GRAPHICS_CONSOLE Console;
  740. UINTN RowCount;
  741. EFI_STATUS Status;
  742. Console = EFI_GRAPHICS_CONSOLE_FROM_THIS(This);
  743. ASSERT(Console->Magic == EFI_GRAPHICS_CONSOLE_MAGIC);
  744. Status = This->QueryMode(This,
  745. This->Mode->Mode,
  746. &ColumnCount,
  747. &RowCount);
  748. if (EFI_ERROR(Status)) {
  749. return EFI_DEVICE_ERROR;
  750. }
  751. if ((Column >= ColumnCount) || (Row >= RowCount)) {
  752. return EFI_UNSUPPORTED;
  753. }
  754. This->Mode->CursorColumn = Column;
  755. This->Mode->CursorRow = Row;
  756. return EFI_SUCCESS;
  757. }
  758. EFIAPI
  759. EFI_STATUS
  760. EfipGraphicsTextEnableCursor (
  761. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
  762. BOOLEAN Visible
  763. )
  764. /*++
  765. Routine Description:
  766. This routine makes the cursor visible or invisible.
  767. Arguments:
  768. This - Supplies a pointer to the protocol instance.
  769. Visible - Supplies a boolean indicating whether to make the cursor visible
  770. (TRUE) or invisible (FALSE).
  771. Return Value:
  772. EFI_SUCCESS on success.
  773. EFI_DEVICE_ERROR if the device had an error and could not complete the
  774. request.
  775. EFI_UNSUPPORTED if the output device is not in a valid text mode.
  776. --*/
  777. {
  778. return EFI_UNSUPPORTED;
  779. }