1 /* 2 * Copyright 2021, Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #include <boot/stage2.h> 7 #include <boot/platform/generic/text_console.h> 8 #include <boot/platform/generic/video.h> 9 10 #include <frame_buffer_console.h> 11 12 13 extern console_module_info gFrameBufferConsoleModule; 14 15 16 class VideoTextConsole : public ConsoleNode { 17 public: 18 VideoTextConsole(addr_t framebuffer); 19 20 virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer, 21 size_t bufferSize); 22 virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer, 23 size_t bufferSize); 24 25 virtual void ClearScreen(); 26 virtual int32 Width(); 27 virtual int32 Height(); 28 virtual void SetCursor(int32 x, int32 y); 29 virtual void SetCursorVisible(bool visible); 30 virtual void SetColors(int32 foreground, int32 background); 31 32 private: 33 uint16 fColor = 0x0f00; 34 bool fShowCursor; 35 int32 fCursorX, fCursorY; 36 int32 fScreenWidth, fScreenHeight; 37 }; 38 39 40 // #pragma mark - 41 42 43 VideoTextConsole::VideoTextConsole(addr_t framebuffer) 44 : ConsoleNode() 45 { 46 frame_buffer_update(framebuffer, gKernelArgs.frame_buffer.width, 47 gKernelArgs.frame_buffer.height, gKernelArgs.frame_buffer.depth, 48 gKernelArgs.frame_buffer.bytes_per_row); 49 gFrameBufferConsoleModule.get_size(&fScreenWidth, &fScreenHeight); 50 51 SetCursorVisible(false); 52 ClearScreen(); 53 } 54 55 56 ssize_t 57 VideoTextConsole::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize) 58 { 59 return B_ERROR; 60 } 61 62 63 ssize_t 64 VideoTextConsole::WriteAt(void *cookie, off_t /*pos*/, const void *buffer, 65 size_t bufferSize) 66 { 67 const char *string = (const char *)buffer; 68 for (size_t i = 0; i < bufferSize; i++) { 69 const char c = string[i]; 70 if (c == '\n' || fCursorX >= fScreenWidth) { 71 fCursorX = 0; 72 if (fCursorY == (fScreenHeight - 1)) { 73 // Move the screen up and clear the bottom line. 74 gFrameBufferConsoleModule.blit(0, 1, fScreenWidth, 0, 75 0, fScreenHeight - 1); 76 gFrameBufferConsoleModule.fill_glyph(0, fCursorY, fScreenWidth, 77 1, ' ', fColor); 78 } else { 79 fCursorY++; 80 } 81 } 82 83 switch (c) { 84 case '\n': 85 // already handled above 86 break; 87 88 default: 89 gFrameBufferConsoleModule.put_glyph(fCursorX, fCursorY, c, fColor); 90 break; 91 } 92 fCursorX++; 93 } 94 return bufferSize; 95 } 96 97 98 void 99 VideoTextConsole::ClearScreen() 100 { 101 gFrameBufferConsoleModule.clear(fColor); 102 } 103 104 105 int32 106 VideoTextConsole::Width() 107 { 108 return fScreenWidth; 109 } 110 111 112 int32 113 VideoTextConsole::Height() 114 { 115 return fScreenHeight; 116 } 117 118 119 void 120 VideoTextConsole::SetCursor(int32 x, int32 y) 121 { 122 fCursorX = x; 123 fCursorY = y; 124 if (fShowCursor) 125 SetCursorVisible(true); 126 } 127 128 129 void 130 VideoTextConsole::SetCursorVisible(bool visible) 131 { 132 fShowCursor = visible; 133 if (fShowCursor) 134 gFrameBufferConsoleModule.move_cursor(fCursorX, fCursorY); 135 else 136 gFrameBufferConsoleModule.move_cursor(-1, -1); 137 } 138 139 140 void 141 VideoTextConsole::SetColors(int32 foreground, int32 background) 142 { 143 fColor = (background & 0xf) << 4 | (foreground & 0xf); 144 } 145 146 147 ConsoleNode* 148 video_text_console_init(addr_t frameBuffer) 149 { 150 return new VideoTextConsole(frameBuffer); 151 } 152