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 virtual void ClearScreen(); 33 virtual int32 Width(); 34 virtual int32 Height(); 35 virtual void SetCursor(int32 x, int32 y); 36 virtual void SetCursorVisible(bool visible); 37 virtual void SetColors(int32 foreground, int32 background); 38 }; 39 40 41 extern ConsoleNode* gConsoleNode; 42 static Console sConsole; 43 FILE *stdin, *stdout, *stderr; 44 45 46 Console::Console() 47 : ConsoleNode() 48 { 49 } 50 51 52 ssize_t 53 Console::ReadAt(void */*cookie*/, off_t /*pos*/, void *_buffer, 54 size_t bufferSize) 55 { 56 char *buffer = (char*)_buffer; 57 int c; 58 ssize_t bytesTotal = 0; 59 60 while (bytesTotal < bufferSize && (c = mg->mg_try_getc())) { 61 *buffer++ = (char)c; 62 bytesTotal++; 63 } 64 65 return bytesTotal; 66 } 67 68 69 ssize_t 70 Console::WriteAt(void */*cookie*/, off_t /*pos*/, const void *buffer, 71 size_t bufferSize) 72 { 73 const char *string = (const char *)buffer; 74 size_t i; 75 76 for (i = 0; i < bufferSize; i++) { 77 if (string[i] == '\0') 78 break; 79 mg->mg_putc(string[i]); 80 } 81 82 return bufferSize; 83 } 84 85 86 void 87 Console::ClearScreen() 88 { 89 sConsole.WriteAt(NULL, 0LL, "\033E", 2); 90 } 91 92 93 int32 94 Console::Width() 95 { 96 int columnCount = 80; //XXX: check video mode 97 return columnCount; 98 } 99 100 101 int32 102 Console::Height() 103 { 104 int lineCount = 25; //XXX: check video mode 105 return lineCount; 106 } 107 108 109 void 110 Console::SetCursor(int32 x, int32 y) 111 { 112 char buff[] = "\033Y "; 113 x = MIN(79,MAX(0,x)); 114 y = MIN(24,MAX(0,y)); 115 buff[3] += (char)x; 116 buff[2] += (char)y; 117 sConsole.WriteAt(NULL, 0LL, buff, 4); 118 } 119 120 121 static int 122 translate_color(int32 color) 123 { 124 /* 125 r g b 126 0: 0 0 0 // black 127 1: 0 0 aa // dark blue 128 2: 0 aa 0 // dark green 129 3: 0 aa aa // cyan 130 4: aa 0 0 // dark red 131 5: aa 0 aa // purple 132 6: aa 55 0 // brown 133 7: aa aa aa // light gray 134 8: 55 55 55 // dark gray 135 9: 55 55 ff // light blue 136 a: 55 ff 55 // light green 137 b: 55 ff ff // light cyan 138 c: ff 55 55 // light red 139 d: ff 55 ff // magenta 140 e: ff ff 55 // yellow 141 f: ff ff ff // white 142 */ 143 // cf. http://www.fortunecity.com/skyscraper/apple/308/html/chap4.htm 144 static const char cmap[] = { 145 15, 4, 2, 6, 1, 5, 3, 7, 146 8, 12, 10, 14, 9, 13, 11, 0 }; 147 148 if (color < 0 || color >= 16) 149 return 0; 150 return cmap[color]; 151 //return color; 152 } 153 154 155 void 156 Console::SetColors(int32 foreground, int32 background) 157 { 158 char buff[] = "\033b \033c "; 159 if (sForceBW) { 160 if (background == 0) { 161 foreground = 15; 162 } else { 163 background = 15; 164 foreground = 0; 165 } 166 } 167 buff[2] += (char)translate_color(foreground); 168 buff[5] += (char)translate_color(background); 169 sConsole.WriteAt(NULL, 0LL, buff, 6); 170 } 171 172 173 void 174 Console::SetCursorVisible(bool) 175 { 176 // TODO? 177 } 178 179 180 // #pragma mark - 181 182 183 static void 184 dump_colors() 185 { 186 int bg, fg; 187 dprintf("colors:\n"); 188 for (bg = 0; bg < 16; bg++) { 189 for (fg = 0; fg < 16; fg++) { 190 console_set_color(fg, bg); 191 dprintf("#"); 192 } 193 console_set_color(0, 15); 194 dprintf("\n"); 195 } 196 } 197 198 199 status_t 200 console_init(void) 201 { 202 gConsoleNode = &sConsole; 203 204 // now that we're initialized, enable stdio functionality 205 stdin = (FILE *)&sConsole; 206 stdout = stderr = (FILE *)&sConsole; 207 208 //dump_colors(); 209 210 return B_OK; 211 } 212 213 214 // #pragma mark - 215 216 217 int 218 console_wait_for_key(void) 219 { 220 #if 0 221 // XXX: do this way and remove keyboard.cpp ? 222 // wait for a key 223 char buffer[3]; 224 ssize_t bytesRead; 225 do { 226 bytesRead = sConsole.ReadAt(NULL, 0, buffer, 3); 227 if (bytesRead < 0) 228 return 0; 229 } while (bytesRead == 0); 230 #endif 231 union key key = wait_for_key(); 232 233 if (key.code.ascii == 0) { 234 switch (key.code.bios) { 235 case BIOS_KEY_UP: 236 return TEXT_CONSOLE_KEY_UP; 237 case BIOS_KEY_DOWN: 238 return TEXT_CONSOLE_KEY_DOWN; 239 case BIOS_KEY_PAGE_UP: 240 return TEXT_CONSOLE_KEY_PAGE_UP; 241 case BIOS_KEY_PAGE_DOWN: 242 return TEXT_CONSOLE_KEY_PAGE_DOWN; 243 case BIOS_KEY_HOME: 244 return TEXT_CONSOLE_KEY_HOME; 245 case BIOS_KEY_END: 246 return TEXT_CONSOLE_KEY_END; 247 default: 248 return 0; 249 } 250 } else 251 return key.code.ascii; 252 } 253