1 /* 2 * Copyright 2007-2010, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT license. 4 * 5 * Author: 6 * François Revol, revol@free.fr. 7 */ 8 9 #include <SupportDefs.h> 10 #include <string.h> 11 #include "nextrom.h" 12 #include <util/kernel_cpp.h> 13 14 #include "console.h" 15 #include "keyboard.h" 16 17 18 static bool sForceBW = false; // force black & white for Milan 19 20 // bootrom has more console info but we don't know the structure 21 // so we just use getc & putc for now. 22 23 class Console : public ConsoleNode { 24 public: 25 Console(); 26 27 virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer, 28 size_t bufferSize); 29 virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer, 30 size_t bufferSize); 31 32 void PutChar(char c); 33 void PutChars(const char *buffer, int count); 34 char GetChar(); 35 }; 36 37 38 static Console sInput; 39 static Console sOutput; 40 FILE *stdin, *stdout, *stderr; 41 42 43 Console::Console() 44 : ConsoleNode() 45 { 46 } 47 48 49 ssize_t 50 Console::ReadAt(void */*cookie*/, off_t /*pos*/, void *_buffer, 51 size_t bufferSize) 52 { 53 char *buffer = (char*)_buffer; 54 int c; 55 ssize_t bytesTotal = 0; 56 57 while (bytesTotal < bufferSize && (c = mg->mg_try_getc())) { 58 *buffer++ = (char)c; 59 bytesTotal++; 60 } 61 62 return bytesTotal; 63 } 64 65 66 ssize_t 67 Console::WriteAt(void */*cookie*/, off_t /*pos*/, const void *buffer, 68 size_t bufferSize) 69 { 70 const char *string = (const char *)buffer; 71 size_t i; 72 73 for (i = 0; i < bufferSize; i++) { 74 if (string[i] == '\0') 75 break; 76 mg->mg_putc(string[i]); 77 } 78 79 return bufferSize; 80 } 81 82 83 void 84 Console::PutChar(char c) 85 { 86 mg->mg_putc(c); 87 } 88 89 90 void 91 Console::PutChars(const char *buffer, int count) 92 { 93 for (int i = 0; i < count; i++) 94 mg->mg_putc(buffer[i]); 95 } 96 97 98 char 99 Console::GetChar() 100 { 101 return (char)(mg->mg_getc()); 102 } 103 104 105 // #pragma mark - 106 107 108 static void 109 dump_colors() 110 { 111 int bg, fg; 112 dprintf("colors:\n"); 113 for (bg = 0; bg < 16; bg++) { 114 for (fg = 0; fg < 16; fg++) { 115 console_set_color(fg, bg); 116 dprintf("#"); 117 } 118 console_set_color(0, 15); 119 dprintf("\n"); 120 } 121 } 122 123 124 status_t 125 console_init(void) 126 { 127 // now that we're initialized, enable stdio functionality 128 stdin = (FILE *)&sInput; 129 stdout = stderr = (FILE *)&sOutput; 130 131 //dump_colors(); 132 133 return B_OK; 134 } 135 136 137 // #pragma mark - 138 139 140 void 141 console_clear_screen(void) 142 { 143 sInput.WriteAt(NULL, 0LL, "\033E", 2); 144 } 145 146 147 int32 148 console_width(void) 149 { 150 int columnCount = 80; //XXX: check video mode 151 return columnCount; 152 } 153 154 155 int32 156 console_height(void) 157 { 158 int lineCount = 25; //XXX: check video mode 159 return lineCount; 160 } 161 162 163 void 164 console_set_cursor(int32 x, int32 y) 165 { 166 char buff[] = "\033Y "; 167 x = MIN(79,MAX(0,x)); 168 y = MIN(24,MAX(0,y)); 169 buff[3] += (char)x; 170 buff[2] += (char)y; 171 sInput.WriteAt(NULL, 0LL, buff, 4); 172 } 173 174 175 static int 176 translate_color(int32 color) 177 { 178 /* 179 r g b 180 0: 0 0 0 // black 181 1: 0 0 aa // dark blue 182 2: 0 aa 0 // dark green 183 3: 0 aa aa // cyan 184 4: aa 0 0 // dark red 185 5: aa 0 aa // purple 186 6: aa 55 0 // brown 187 7: aa aa aa // light gray 188 8: 55 55 55 // dark gray 189 9: 55 55 ff // light blue 190 a: 55 ff 55 // light green 191 b: 55 ff ff // light cyan 192 c: ff 55 55 // light red 193 d: ff 55 ff // magenta 194 e: ff ff 55 // yellow 195 f: ff ff ff // white 196 */ 197 // cf. http://www.fortunecity.com/skyscraper/apple/308/html/chap4.htm 198 static const char cmap[] = { 199 15, 4, 2, 6, 1, 5, 3, 7, 200 8, 12, 10, 14, 9, 13, 11, 0 }; 201 202 if (color < 0 || color >= 16) 203 return 0; 204 return cmap[color]; 205 //return color; 206 } 207 208 209 void 210 console_set_color(int32 foreground, int32 background) 211 { 212 char buff[] = "\033b \033c "; 213 if (sForceBW) { 214 if (background == 0) 215 foreground = 15; 216 else { 217 background = 15; 218 foreground = 0; 219 } 220 221 } 222 buff[2] += (char)translate_color(foreground); 223 buff[5] += (char)translate_color(background); 224 sInput.WriteAt(NULL, 0LL, buff, 6); 225 } 226 227 228 void 229 console_show_cursor(void) 230 { 231 } 232 233 234 void 235 console_hide_cursor(void) 236 { 237 } 238 239 240 int 241 console_wait_for_key(void) 242 { 243 #if 0 244 // XXX: do this way and remove keyboard.cpp ? 245 // wait for a key 246 char buffer[3]; 247 ssize_t bytesRead; 248 do { 249 bytesRead = sInput.ReadAt(NULL, 0, buffer, 3); 250 if (bytesRead < 0) 251 return 0; 252 } while (bytesRead == 0); 253 #endif 254 union key key = wait_for_key(); 255 256 if (key.code.ascii == 0) { 257 switch (key.code.bios) { 258 case BIOS_KEY_UP: 259 return TEXT_CONSOLE_KEY_UP; 260 case BIOS_KEY_DOWN: 261 return TEXT_CONSOLE_KEY_DOWN; 262 case BIOS_KEY_PAGE_UP: 263 return TEXT_CONSOLE_KEY_PAGE_UP; 264 case BIOS_KEY_PAGE_DOWN: 265 return TEXT_CONSOLE_KEY_PAGE_DOWN; 266 case BIOS_KEY_HOME: 267 return TEXT_CONSOLE_KEY_HOME; 268 case BIOS_KEY_END: 269 return TEXT_CONSOLE_KEY_END; 270 default: 271 return 0; 272 } 273 } else 274 return key.code.ascii; 275 } 276 277