Changeset 46c20c8 in mainline for uspace/srv/hid/fb/serial_console.c
- Timestamp:
- 2010-11-26T20:08:10Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 45df59a
- Parents:
- fb150d78 (diff), ffdd2b9 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/fb/serial_console.c
rfb150d78 r46c20c8 31 31 /** 32 32 * @defgroup serial Serial console 33 * @brief 33 * @brief Serial console services (putc, puts, clear screen, cursor goto,...) 34 34 * @{ 35 */ 35 */ 36 36 37 37 /** @file … … 46 46 #include <io/color.h> 47 47 #include <io/style.h> 48 #include <string.h> 49 50 #include "../console/screenbuffer.h" 48 #include <str.h> 49 #include <inttypes.h> 50 #include <io/screenbuffer.h> 51 51 52 #include "main.h" 52 53 #include "serial_console.h" … … 54 55 #define MAX_CONTROL 20 55 56 56 static void serial_sgr(const unsigned int mode); 57 void serial_putchar(wchar_t ch); 58 59 static int scr_width; 60 static int scr_height; 61 static bool color = true; /** True if producing color output. */ 62 static bool utf8 = false; /** True if producing UTF8 output. */ 57 static ipcarg_t scr_width; 58 static ipcarg_t scr_height; 59 static bool color = true; /**< True if producing color output. */ 60 static bool utf8 = false; /**< True if producing UTF8 output. */ 63 61 static putc_function_t putc_function; 62 63 static ipcarg_t lastcol = 0; 64 static ipcarg_t lastrow = 0; 65 static attrs_t cur_attr = { 66 .t = at_style, 67 .a.s.style = STYLE_NORMAL 68 }; 64 69 65 70 /* Allow only 1 connection */ … … 67 72 68 73 enum sgr_color_index { 69 CI_BLACK 70 CI_RED 71 CI_GREEN 72 CI_BROWN 73 CI_BLUE 74 CI_MAGENTA 75 CI_CYAN 76 CI_WHITE = 7,74 CI_BLACK = 0, 75 CI_RED = 1, 76 CI_GREEN = 2, 77 CI_BROWN = 3, 78 CI_BLUE = 4, 79 CI_MAGENTA = 5, 80 CI_CYAN = 6, 81 CI_WHITE = 7 77 82 }; 78 83 79 84 enum sgr_command { 80 SGR_RESET = 0, 81 SGR_BOLD = 1, 82 SGR_BLINK = 5, 83 SGR_REVERSE = 7, 84 SGR_NORMAL_INT = 22, 85 SGR_BLINK_OFF = 25, 86 SGR_REVERSE_OFF = 27, 87 SGR_FGCOLOR = 30, 88 SGR_BGCOLOR = 40 85 SGR_RESET = 0, 86 SGR_BOLD = 1, 87 SGR_UNDERLINE = 4, 88 SGR_BLINK = 5, 89 SGR_REVERSE = 7, 90 SGR_FGCOLOR = 30, 91 SGR_BGCOLOR = 40 89 92 }; 90 93 91 94 static int color_map[] = { 92 [COLOR_BLACK] 93 [COLOR_BLUE] 94 [COLOR_GREEN] 95 [COLOR_CYAN] 96 [COLOR_RED] 95 [COLOR_BLACK] = CI_BLACK, 96 [COLOR_BLUE] = CI_RED, 97 [COLOR_GREEN] = CI_GREEN, 98 [COLOR_CYAN] = CI_CYAN, 99 [COLOR_RED] = CI_RED, 97 100 [COLOR_MAGENTA] = CI_MAGENTA, 98 [COLOR_YELLOW] 99 [COLOR_WHITE] 101 [COLOR_YELLOW] = CI_BROWN, 102 [COLOR_WHITE] = CI_WHITE 100 103 }; 101 104 102 void serial_puts(c har *str)105 void serial_puts(const char *str) 103 106 { 104 107 while (*str) … … 106 109 } 107 110 108 void serial_putchar(wchar_t ch) 109 { 110 uint8_t buf[STR_BOUNDS(1)]; 111 size_t offs; 112 size_t i; 113 111 static void serial_putchar(wchar_t ch) 112 { 114 113 if (utf8 != true) { 115 114 if (ch >= 0 && ch < 128) 116 115 (*putc_function)((uint8_t) ch); 117 else 116 else 118 117 (*putc_function)('?'); 118 119 119 return; 120 120 } 121 122 offs = 0; 121 122 size_t offs = 0; 123 char buf[STR_BOUNDS(1)]; 123 124 if (chr_encode(ch, buf, &offs, STR_BOUNDS(1)) == EOK) { 125 size_t i; 124 126 for (i = 0; i < offs; i++) 125 127 (*putc_function)(buf[i]); 126 } else {128 } else 127 129 (*putc_function)('?'); 128 } 129 130 } 131 132 void serial_goto(const unsigned int col, const unsigned int row) 130 } 131 132 void serial_goto(const ipcarg_t col, const ipcarg_t row) 133 133 { 134 134 if ((col > scr_width) || (row > scr_height)) … … 136 136 137 137 char control[MAX_CONTROL]; 138 snprintf(control, MAX_CONTROL, "\033[%u;%uf", row + 1, col + 1); 138 snprintf(control, MAX_CONTROL, "\033[%" PRIun ";%" PRIun "f", 139 row + 1, col + 1); 139 140 serial_puts(control); 141 } 142 143 /** ECMA-48 Set Graphics Rendition. */ 144 static void serial_sgr(const unsigned int mode) 145 { 146 char control[MAX_CONTROL]; 147 snprintf(control, MAX_CONTROL, "\033[%um", mode); 148 serial_puts(control); 149 } 150 151 static void serial_set_style(console_style_t style) 152 { 153 switch (style) { 154 case STYLE_EMPHASIS: 155 serial_sgr(SGR_RESET); 156 if (color) { 157 serial_sgr(SGR_FGCOLOR + CI_RED); 158 serial_sgr(SGR_BGCOLOR + CI_WHITE); 159 } 160 serial_sgr(SGR_BOLD); 161 break; 162 case STYLE_INVERTED: 163 serial_sgr(SGR_RESET); 164 if (color) { 165 serial_sgr(SGR_FGCOLOR + CI_WHITE); 166 serial_sgr(SGR_BGCOLOR + CI_BLACK); 167 } else 168 serial_sgr(SGR_REVERSE); 169 break; 170 case STYLE_SELECTED: 171 serial_sgr(SGR_RESET); 172 if (color) { 173 serial_sgr(SGR_FGCOLOR + CI_WHITE); 174 serial_sgr(SGR_BGCOLOR + CI_RED); 175 } else 176 serial_sgr(SGR_UNDERLINE); 177 break; 178 default: 179 serial_sgr(SGR_RESET); 180 if (color) { 181 serial_sgr(SGR_FGCOLOR + CI_BLACK); 182 serial_sgr(SGR_BGCOLOR + CI_WHITE); 183 } 184 } 185 } 186 187 static void serial_set_idx(uint8_t fgcolor, uint8_t bgcolor, 188 uint8_t flags) 189 { 190 serial_sgr(SGR_RESET); 191 if (color) { 192 serial_sgr(SGR_FGCOLOR + color_map[fgcolor & 7]); 193 serial_sgr(SGR_BGCOLOR + color_map[bgcolor & 7]); 194 if (flags & CATTR_BRIGHT) 195 serial_sgr(SGR_BOLD); 196 } else { 197 if (fgcolor >= bgcolor) 198 serial_sgr(SGR_REVERSE); 199 } 200 } 201 202 static void serial_set_rgb(uint32_t fgcolor, uint32_t bgcolor) 203 { 204 serial_sgr(SGR_RESET); 205 206 if (fgcolor >= bgcolor) 207 serial_sgr(SGR_REVERSE); 208 } 209 210 static void serial_set_attrs(attrs_t *a) 211 { 212 switch (a->t) { 213 case at_style: 214 serial_set_style(a->a.s.style); 215 break; 216 case at_rgb: 217 serial_set_rgb(a->a.r.fg_color, a->a.r.bg_color); 218 break; 219 case at_idx: 220 serial_set_idx(a->a.i.fg_color, a->a.i.bg_color, 221 a->a.i.flags); 222 break; 223 } 140 224 } 141 225 … … 148 232 serial_sgr(SGR_BGCOLOR + CI_WHITE); 149 233 } 150 234 151 235 serial_puts("\033[2J"); 152 } 153 154 void serial_scroll(int i) 236 237 serial_set_attrs(&cur_attr); 238 } 239 240 void serial_scroll(ssize_t i) 155 241 { 156 242 if (i > 0) { … … 165 251 } 166 252 167 /** ECMA-48 Set Graphics Rendition. */168 static void serial_sgr(const unsigned int mode)253 /** Set scrolling region. */ 254 void serial_set_scroll_region(ipcarg_t last_row) 169 255 { 170 256 char control[MAX_CONTROL]; 171 snprintf(control, MAX_CONTROL, "\033[ %um", mode);257 snprintf(control, MAX_CONTROL, "\033[0;%" PRIun "r", last_row); 172 258 serial_puts(control); 173 259 } 174 260 175 /** Set scrolling region. */176 void serial_set_scroll_region(unsigned last_row)177 {178 char control[MAX_CONTROL];179 snprintf(control, MAX_CONTROL, "\033[0;%ur", last_row);180 serial_puts(control);181 }182 183 261 void serial_cursor_disable(void) 184 262 { … … 191 269 } 192 270 193 void serial_console_init(putc_function_t putc_fn, uint32_t w, uint32_t h)271 void serial_console_init(putc_function_t putc_fn, ipcarg_t w, ipcarg_t h) 194 272 { 195 273 scr_width = w; … … 198 276 } 199 277 200 static void serial_set_style(int style)201 {202 if (style == STYLE_EMPHASIS) {203 if (color) {204 serial_sgr(SGR_RESET);205 serial_sgr(SGR_FGCOLOR + CI_RED);206 serial_sgr(SGR_BGCOLOR + CI_WHITE);207 }208 serial_sgr(SGR_BOLD);209 } else {210 if (color) {211 serial_sgr(SGR_RESET);212 serial_sgr(SGR_FGCOLOR + CI_BLACK);213 serial_sgr(SGR_BGCOLOR + CI_WHITE);214 }215 serial_sgr(SGR_NORMAL_INT);216 }217 }218 219 static void serial_set_idx(unsigned fgcolor, unsigned bgcolor,220 unsigned flags)221 {222 if (color) {223 serial_sgr(SGR_RESET);224 serial_sgr(SGR_FGCOLOR + color_map[fgcolor]);225 serial_sgr(SGR_BGCOLOR + color_map[bgcolor]);226 } else {227 if (fgcolor < bgcolor)228 serial_sgr(SGR_RESET);229 else230 serial_sgr(SGR_REVERSE);231 }232 }233 234 static void serial_set_rgb(uint32_t fgcolor, uint32_t bgcolor)235 {236 if (fgcolor < bgcolor)237 serial_sgr(SGR_REVERSE_OFF);238 else239 serial_sgr(SGR_REVERSE);240 }241 242 static void serial_set_attrs(const attrs_t *a)243 {244 switch (a->t) {245 case at_style:246 serial_set_style(a->a.s.style);247 break;248 case at_rgb:249 serial_set_rgb(a->a.r.fg_color, a->a.r.bg_color);250 break;251 case at_idx:252 serial_set_idx(a->a.i.fg_color,253 a->a.i.bg_color, a->a.i.flags);254 break;255 default:256 break;257 }258 }259 260 278 /** Draw text data to viewport. 261 279 * 262 * @param vport Viewport id 263 * @param data Text data. 264 * @param x Leftmost column of the area. 265 * @param y Topmost row of the area. 266 * @param w Number of rows. 267 * @param h Number of columns. 268 */ 269 static void draw_text_data(keyfield_t *data, unsigned int x, 270 unsigned int y, unsigned int w, unsigned int h) 271 { 272 unsigned int i, j; 273 keyfield_t *field; 274 attrs_t *a0, *a1; 275 276 serial_goto(x, y); 277 a0 = &data[0].attrs; 280 * @param vport Viewport id 281 * @param data Text data. 282 * @param x0 Leftmost column of the area. 283 * @param y0 Topmost row of the area. 284 * @param width Number of rows. 285 * @param height Number of columns. 286 * 287 */ 288 static void draw_text_data(keyfield_t *data, ipcarg_t x0, ipcarg_t y0, 289 ipcarg_t width, ipcarg_t height) 290 { 291 attrs_t *a0 = &data[0].attrs; 278 292 serial_set_attrs(a0); 279 280 for (j = 0; j < h; j++) { 281 if (j > 0 && w != scr_width) 282 serial_goto(x, j); 283 284 for (i = 0; i < w; i++) { 285 field = &data[j * w + i]; 286 287 a1 = &field->attrs; 288 if (!attrs_same(*a0, *a1)) 289 serial_set_attrs(a1); 290 serial_putchar(field->character); 291 a0 = a1; 293 294 ipcarg_t y; 295 for (y = 0; y < height; y++) { 296 serial_goto(x0, y0 + y); 297 298 ipcarg_t x; 299 for (x = 0; x < width; x++) { 300 attrs_t *attr = &data[y * width + x].attrs; 301 302 if (!attrs_same(*a0, *attr)) { 303 serial_set_attrs(attr); 304 a0 = attr; 305 } 306 307 serial_putchar(data[y * width + x].character); 292 308 } 293 309 } 294 310 } 295 296 int lastcol = 0;297 int lastrow = 0;298 311 299 312 /** … … 302 315 void serial_client_connection(ipc_callid_t iid, ipc_call_t *icall) 303 316 { 304 int retval;305 ipc_callid_t callid;306 ipc_call_t call;307 317 keyfield_t *interbuf = NULL; 308 318 size_t intersize = 0; 309 310 wchar_t c;311 int col, row, w, h;312 int i;313 314 attrs_t cur_attr;315 319 316 320 if (client_connected) { … … 321 325 client_connected = 1; 322 326 ipc_answer_0(iid, EOK); 323 324 cur_attr.t = at_style;325 cur_attr.a.s.style = STYLE_NORMAL;326 327 327 328 /* Clear the terminal, set scrolling region … … 332 333 333 334 while (true) { 334 callid = async_get_call(&call); 335 ipc_call_t call; 336 ipc_callid_t callid = async_get_call(&call); 337 338 wchar_t c; 339 ipcarg_t col; 340 ipcarg_t row; 341 ipcarg_t w; 342 ipcarg_t h; 343 ssize_t rows; 344 345 int retval; 346 335 347 switch (IPC_GET_METHOD(call)) { 336 348 case IPC_M_PHONE_HUNGUP: 337 349 client_connected = 0; 338 350 ipc_answer_0(callid, EOK); 351 352 /* Exit thread */ 339 353 return; 340 354 case IPC_M_SHARE_OUT: … … 347 361 continue; 348 362 } 363 349 364 retval = EINVAL; 350 365 break; … … 354 369 w = IPC_GET_ARG3(call); 355 370 h = IPC_GET_ARG4(call); 371 356 372 if (!interbuf) { 357 373 retval = EINVAL; 358 374 break; 359 375 } 360 if (col + w > scr_width || row + h > scr_height) { 376 377 if ((col + w > scr_width) || (row + h > scr_height)) { 361 378 retval = EINVAL; 362 379 break; 363 380 } 381 364 382 draw_text_data(interbuf, col, row, w, h); 365 383 lastcol = col + w; … … 371 389 col = IPC_GET_ARG2(call); 372 390 row = IPC_GET_ARG3(call); 391 373 392 if ((lastcol != col) || (lastrow != row)) 374 393 serial_goto(col, row); 394 375 395 lastcol = col + 1; 376 396 lastrow = row; … … 400 420 cur_attr.t = at_style; 401 421 cur_attr.a.s.style = IPC_GET_ARG1(call); 402 cur_attr.a.i.bg_color = IPC_GET_ARG2(call);403 422 serial_set_attrs(&cur_attr); 404 405 423 retval = 0; 406 424 break; … … 411 429 cur_attr.a.i.flags = IPC_GET_ARG3(call); 412 430 serial_set_attrs(&cur_attr); 413 414 431 retval = 0; 415 432 break; 416 433 case FB_SET_RGB_COLOR: 417 434 cur_attr.t = at_rgb; 418 cur_attr.a. i.fg_color = IPC_GET_ARG1(call);419 cur_attr.a. i.bg_color = IPC_GET_ARG2(call);435 cur_attr.a.r.fg_color = IPC_GET_ARG1(call); 436 cur_attr.a.r.bg_color = IPC_GET_ARG2(call); 420 437 serial_set_attrs(&cur_attr); 421 422 438 retval = 0; 423 439 break; 424 440 case FB_SCROLL: 425 i = IPC_GET_ARG1(call); 426 if ((i > scr_height) || (i < -scr_height)) { 427 retval = EINVAL; 428 break; 441 rows = IPC_GET_ARG1(call); 442 443 if (rows >= 0) { 444 if ((ipcarg_t) rows > scr_height) { 445 retval = EINVAL; 446 break; 447 } 448 } else { 449 if ((ipcarg_t) (-rows) > scr_height) { 450 retval = EINVAL; 451 break; 452 } 429 453 } 430 serial_scroll(i); 454 455 serial_scroll(rows); 431 456 serial_goto(lastcol, lastrow); 432 457 retval = 0; … … 448 473 case FB_SCREEN_RECLAIM: 449 474 serial_clrscr(); 450 serial_set_attrs(&cur_attr);451 475 retval = 0; 452 476 break;
Note:
See TracChangeset
for help on using the changeset viewer.