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
VideoTextConsole(addr_t framebuffer)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
ReadAt(void * cookie,off_t pos,void * buffer,size_t bufferSize)57 VideoTextConsole::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
58 {
59 return B_ERROR;
60 }
61
62
63 ssize_t
WriteAt(void * cookie,off_t,const void * buffer,size_t bufferSize)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
ClearScreen()99 VideoTextConsole::ClearScreen()
100 {
101 gFrameBufferConsoleModule.clear(fColor);
102 }
103
104
105 int32
Width()106 VideoTextConsole::Width()
107 {
108 return fScreenWidth;
109 }
110
111
112 int32
Height()113 VideoTextConsole::Height()
114 {
115 return fScreenHeight;
116 }
117
118
119 void
SetCursor(int32 x,int32 y)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
SetCursorVisible(bool visible)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
SetColors(int32 foreground,int32 background)141 VideoTextConsole::SetColors(int32 foreground, int32 background)
142 {
143 fColor = (background & 0xf) << 4 | (foreground & 0xf);
144 }
145
146
147 ConsoleNode*
video_text_console_init(addr_t frameBuffer)148 video_text_console_init(addr_t frameBuffer)
149 {
150 return new VideoTextConsole(frameBuffer);
151 }
152