xref: /haiku/src/system/kernel/debug/blue_screen.cpp (revision ea6253d0ba561f923f74af1febaf250d2419b1ae)
1 /*
2  * Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "blue_screen.h"
8 
9 #include <frame_buffer_console.h>
10 #include <console.h>
11 #include <arch/debug_console.h>
12 
13 #include <string.h>
14 #include <stdio.h>
15 
16 
17 #define USE_SCROLLING 0
18 #define NO_CLEAR 1
19 
20 struct screen_info {
21 	int32	columns;
22 	int32	rows;
23 	int32	x, y;
24 	uint8	attr;
25 } sScreen;
26 
27 console_module_info *sModule;
28 
29 
30 static inline void
31 hide_cursor(void)
32 {
33 	sModule->move_cursor(-1, -1);
34 }
35 
36 
37 static inline void
38 update_cursor(int32 x, int32 y)
39 {
40 	sModule->move_cursor(x, y);
41 }
42 
43 
44 #if USE_SCROLLING
45 
46 /** scroll from the cursor line up to the top of the scroll region up one line */
47 
48 static void
49 scroll_up(void)
50 {
51 	// move the screen up one
52 	sModule->blit(0, 1, sScreen.columns, sScreen.rows - 1, 0, 0);
53 
54 	// clear the bottom line
55 	sModule->fill_glyph(0, 0, sScreen.columns, 1, ' ', sScreen.attr);
56 }
57 #endif
58 
59 
60 static void
61 next_line(void)
62 {
63 	if (sScreen.y == sScreen.rows - 1) {
64 #if USE_SCROLLING
65  		scroll_up();
66 #else
67 		sScreen.y = 0;
68 #endif
69 	} else if (sScreen.y < sScreen.rows - 1) {
70 		sScreen.y++;
71 	}
72 
73 #if NO_CLEAR
74 	sModule->fill_glyph(0, (sScreen.y + 2) % sScreen.rows, sScreen.columns, 1, ' ', sScreen.attr);
75 #endif
76 	sScreen.x = 0;
77 }
78 
79 
80 static void
81 back_space(void)
82 {
83 	if (sScreen.x <= 0)
84 		return;
85 
86 	sScreen.x--;
87 	sModule->put_glyph(sScreen.x, sScreen.y, ' ', sScreen.attr);
88 }
89 
90 
91 static void
92 put_character(char c)
93 {
94 	if (++sScreen.x >= sScreen.columns) {
95 		next_line();
96 		sScreen.x++;
97 	}
98 
99 	sModule->put_glyph(sScreen.x - 1, sScreen.y, c, sScreen.attr);
100 }
101 
102 
103 static void
104 parse_character(char c)
105 {
106 	// just output the stuff
107 	switch (c) {
108 		case '\n':
109 			next_line();
110 			break;
111 		case 0x8:
112 			back_space();
113 			break;
114 		case '\t':
115 			put_character(' ');
116 			break;
117 
118 		case '\r':
119 		case '\0':
120 			break;
121 
122 		default:
123 			put_character(c);
124 	}
125 }
126 
127 
128 //	#pragma mark -
129 
130 
131 status_t
132 blue_screen_init(void)
133 {
134 	extern console_module_info gFrameBufferConsoleModule;
135 
136 	// we can't use get_module() here, since it's too early in the boot process
137 
138 	if (!frame_buffer_console_available())
139 		return B_ERROR;
140 
141 	sModule = &gFrameBufferConsoleModule;
142 	return B_OK;
143 }
144 
145 
146 void
147 blue_screen_enter(void)
148 {
149 	sScreen.attr = 0x0f;	// black on white
150 	sScreen.x = sScreen.y = 0;
151 
152 	sModule->get_size(&sScreen.columns, &sScreen.rows);
153 #if !NO_CLEAR
154 	sModule->clear(sScreen.attr);
155 #else
156 	sModule->fill_glyph(0, sScreen.y, sScreen.columns, 3, ' ', sScreen.attr);
157 #endif
158 }
159 
160 
161 char
162 blue_screen_getchar(void)
163 {
164 	return arch_debug_blue_screen_getchar();
165 }
166 
167 
168 void
169 blue_screen_putchar(char c)
170 {
171 	hide_cursor();
172 
173 	parse_character(c);
174 
175 	update_cursor(sScreen.x, sScreen.y);
176 }
177 
178 
179 void
180 blue_screen_puts(const char *text)
181 {
182 	hide_cursor();
183 
184 	while (text[0] != '\0') {
185 		parse_character(text[0]);
186 		text++;
187 	}
188 
189 	update_cursor(sScreen.x, sScreen.y);
190 }
191