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.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