Changes in uspace/srv/hid/fb/serial_console.c [7e752b2:b3d513f] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/fb/serial_console.c
r7e752b2 rb3d513f 31 31 /** 32 32 * @defgroup serial Serial console 33 * @brief Serial console services (putc, puts, clear screen, cursor goto,...)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 <str.h> 49 #include <inttypes.h> 50 #include <io/screenbuffer.h> 51 48 #include <string.h> 49 50 #include "../console/screenbuffer.h" 52 51 #include "main.h" 53 52 #include "serial_console.h" … … 55 54 #define MAX_CONTROL 20 56 55 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. */ 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. */ 61 63 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_NORMAL68 };69 64 70 65 /* Allow only 1 connection */ … … 72 67 73 68 enum sgr_color_index { 74 CI_BLACK 75 CI_RED 76 CI_GREEN 77 CI_BROWN 78 CI_BLUE 79 CI_MAGENTA 80 CI_CYAN 81 CI_WHITE = 769 CI_BLACK = 0, 70 CI_RED = 1, 71 CI_GREEN = 2, 72 CI_BROWN = 3, 73 CI_BLUE = 4, 74 CI_MAGENTA = 5, 75 CI_CYAN = 6, 76 CI_WHITE = 7, 82 77 }; 83 78 84 79 enum sgr_command { 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 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 92 89 }; 93 90 94 91 static int color_map[] = { 95 [COLOR_BLACK] 96 [COLOR_BLUE] 97 [COLOR_GREEN] 98 [COLOR_CYAN] 99 [COLOR_RED] 92 [COLOR_BLACK] = CI_BLACK, 93 [COLOR_BLUE] = CI_RED, 94 [COLOR_GREEN] = CI_GREEN, 95 [COLOR_CYAN] = CI_CYAN, 96 [COLOR_RED] = CI_RED, 100 97 [COLOR_MAGENTA] = CI_MAGENTA, 101 [COLOR_YELLOW] 102 [COLOR_WHITE] 98 [COLOR_YELLOW] = CI_BROWN, 99 [COLOR_WHITE] = CI_WHITE 103 100 }; 104 101 105 void serial_puts(c onst char *str)102 void serial_puts(char *str) 106 103 { 107 104 while (*str) … … 109 106 } 110 107 111 static void serial_putchar(wchar_t ch) 112 { 108 void serial_putchar(wchar_t ch) 109 { 110 uint8_t buf[STR_BOUNDS(1)]; 111 size_t offs; 112 size_t i; 113 113 114 if (utf8 != true) { 114 115 if (ch >= 0 && ch < 128) 115 116 (*putc_function)((uint8_t) ch); 116 else 117 else 117 118 (*putc_function)('?'); 118 119 119 return; 120 120 } 121 122 size_t offs = 0; 123 char buf[STR_BOUNDS(1)]; 121 122 offs = 0; 124 123 if (chr_encode(ch, buf, &offs, STR_BOUNDS(1)) == EOK) { 125 size_t i;126 124 for (i = 0; i < offs; i++) 127 125 (*putc_function)(buf[i]); 128 } else 126 } else { 129 127 (*putc_function)('?'); 130 } 131 132 void serial_goto(const ipcarg_t col, const ipcarg_t row) 128 } 129 130 } 131 132 void serial_goto(const unsigned int col, const unsigned int 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[%" PRIun ";%" PRIun "f", 139 row + 1, col + 1); 138 snprintf(control, MAX_CONTROL, "\033[%u;%uf", row + 1, col + 1); 140 139 serial_puts(control); 140 } 141 142 void serial_clrscr(void) 143 { 144 /* Initialize graphic rendition attributes. */ 145 serial_sgr(SGR_RESET); 146 if (color) { 147 serial_sgr(SGR_FGCOLOR + CI_BLACK); 148 serial_sgr(SGR_BGCOLOR + CI_WHITE); 149 } 150 151 serial_puts("\033[2J"); 152 } 153 154 void serial_scroll(int i) 155 { 156 if (i > 0) { 157 serial_goto(0, scr_height - 1); 158 while (i--) 159 serial_puts("\033D"); 160 } else if (i < 0) { 161 serial_goto(0, 0); 162 while (i++) 163 serial_puts("\033M"); 164 } 141 165 } 142 166 … … 149 173 } 150 174 151 static void serial_set_style(console_style_t style) 152 { 153 switch (style) { 154 case STYLE_EMPHASIS: 155 serial_sgr(SGR_RESET); 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 void serial_cursor_disable(void) 184 { 185 serial_puts("\033[?25l"); 186 } 187 188 void serial_cursor_enable(void) 189 { 190 serial_puts("\033[?25h"); 191 } 192 193 void serial_console_init(putc_function_t putc_fn, uint32_t w, uint32_t h) 194 { 195 scr_width = w; 196 scr_height = h; 197 putc_function = putc_fn; 198 } 199 200 static void serial_set_style(int style) 201 { 202 if (style == STYLE_EMPHASIS) { 156 203 if (color) { 204 serial_sgr(SGR_RESET); 157 205 serial_sgr(SGR_FGCOLOR + CI_RED); 158 206 serial_sgr(SGR_BGCOLOR + CI_WHITE); 159 207 } 160 208 serial_sgr(SGR_BOLD); 161 break; 162 case STYLE_INVERTED: 163 serial_sgr(SGR_RESET); 209 } else { 164 210 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) { 211 serial_sgr(SGR_RESET); 181 212 serial_sgr(SGR_FGCOLOR + CI_BLACK); 182 213 serial_sgr(SGR_BGCOLOR + CI_WHITE); 183 214 } 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); 215 serial_sgr(SGR_NORMAL_INT); 216 } 217 } 218 219 static void serial_set_idx(unsigned fgcolor, unsigned bgcolor, 220 unsigned flags) 221 { 191 222 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); 223 serial_sgr(SGR_RESET); 224 serial_sgr(SGR_FGCOLOR + color_map[fgcolor]); 225 serial_sgr(SGR_BGCOLOR + color_map[bgcolor]); 196 226 } else { 197 if (fgcolor >= bgcolor) 227 if (fgcolor < bgcolor) 228 serial_sgr(SGR_RESET); 229 else 198 230 serial_sgr(SGR_REVERSE); 199 } 231 } 200 232 } 201 233 202 234 static void serial_set_rgb(uint32_t fgcolor, uint32_t bgcolor) 203 235 { 204 serial_sgr(SGR_RESET);205 206 if (fgcolor >= bgcolor)236 if (fgcolor < bgcolor) 237 serial_sgr(SGR_REVERSE_OFF); 238 else 207 239 serial_sgr(SGR_REVERSE); 208 240 } 209 241 210 static void serial_set_attrs( attrs_t *a)242 static void serial_set_attrs(const attrs_t *a) 211 243 { 212 244 switch (a->t) { … … 218 250 break; 219 251 case at_idx: 220 serial_set_idx(a->a.i.fg_color, a->a.i.bg_color,221 a->a.i. flags);252 serial_set_idx(a->a.i.fg_color, 253 a->a.i.bg_color, a->a.i.flags); 222 254 break; 223 } 224 } 225 226 void serial_clrscr(void) 227 { 228 /* Initialize graphic rendition attributes. */ 229 serial_sgr(SGR_RESET); 230 if (color) { 231 serial_sgr(SGR_FGCOLOR + CI_BLACK); 232 serial_sgr(SGR_BGCOLOR + CI_WHITE); 233 } 234 235 serial_puts("\033[2J"); 236 237 serial_set_attrs(&cur_attr); 238 } 239 240 void serial_scroll(ssize_t i) 241 { 242 if (i > 0) { 243 serial_goto(0, scr_height - 1); 244 while (i--) 245 serial_puts("\033D"); 246 } else if (i < 0) { 247 serial_goto(0, 0); 248 while (i++) 249 serial_puts("\033M"); 250 } 251 } 252 253 /** Set scrolling region. */ 254 void serial_set_scroll_region(ipcarg_t last_row) 255 { 256 char control[MAX_CONTROL]; 257 snprintf(control, MAX_CONTROL, "\033[0;%" PRIun "r", last_row); 258 serial_puts(control); 259 } 260 261 void serial_cursor_disable(void) 262 { 263 serial_puts("\033[?25l"); 264 } 265 266 void serial_cursor_enable(void) 267 { 268 serial_puts("\033[?25h"); 269 } 270 271 void serial_console_init(putc_function_t putc_fn, ipcarg_t w, ipcarg_t h) 272 { 273 scr_width = w; 274 scr_height = h; 275 putc_function = putc_fn; 255 default: 256 break; 257 } 276 258 } 277 259 278 260 /** Draw text data to viewport. 279 261 * 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 * 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. 287 268 */ 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; 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; 292 278 serial_set_attrs(a0); 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); 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; 308 292 } 309 293 } 310 294 } 295 296 int lastcol = 0; 297 int lastrow = 0; 311 298 312 299 /** … … 315 302 void serial_client_connection(ipc_callid_t iid, ipc_call_t *icall) 316 303 { 304 int retval; 305 ipc_callid_t callid; 306 ipc_call_t call; 317 307 keyfield_t *interbuf = NULL; 318 308 size_t intersize = 0; 309 310 wchar_t c; 311 int col, row, w, h; 312 int i; 313 314 attrs_t cur_attr; 319 315 320 316 if (client_connected) { … … 325 321 client_connected = 1; 326 322 ipc_answer_0(iid, EOK); 323 324 cur_attr.t = at_style; 325 cur_attr.a.s.style = STYLE_NORMAL; 327 326 328 327 /* Clear the terminal, set scrolling region … … 333 332 334 333 while (true) { 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 334 callid = async_get_call(&call); 347 335 switch (IPC_GET_METHOD(call)) { 348 336 case IPC_M_PHONE_HUNGUP: 349 337 client_connected = 0; 350 338 ipc_answer_0(callid, EOK); 351 352 /* Exit thread */353 339 return; 354 340 case IPC_M_SHARE_OUT: … … 361 347 continue; 362 348 } 363 364 349 retval = EINVAL; 365 350 break; … … 369 354 w = IPC_GET_ARG3(call); 370 355 h = IPC_GET_ARG4(call); 371 372 356 if (!interbuf) { 373 357 retval = EINVAL; 374 358 break; 375 359 } 376 377 if ((col + w > scr_width) || (row + h > scr_height)) { 360 if (col + w > scr_width || row + h > scr_height) { 378 361 retval = EINVAL; 379 362 break; 380 363 } 381 382 364 draw_text_data(interbuf, col, row, w, h); 383 365 lastcol = col + w; … … 389 371 col = IPC_GET_ARG2(call); 390 372 row = IPC_GET_ARG3(call); 391 392 373 if ((lastcol != col) || (lastrow != row)) 393 374 serial_goto(col, row); 394 395 375 lastcol = col + 1; 396 376 lastrow = row; … … 420 400 cur_attr.t = at_style; 421 401 cur_attr.a.s.style = IPC_GET_ARG1(call); 402 cur_attr.a.i.bg_color = IPC_GET_ARG2(call); 422 403 serial_set_attrs(&cur_attr); 404 423 405 retval = 0; 424 406 break; … … 429 411 cur_attr.a.i.flags = IPC_GET_ARG3(call); 430 412 serial_set_attrs(&cur_attr); 413 431 414 retval = 0; 432 415 break; 433 416 case FB_SET_RGB_COLOR: 434 417 cur_attr.t = at_rgb; 435 cur_attr.a. r.fg_color = IPC_GET_ARG1(call);436 cur_attr.a. r.bg_color = IPC_GET_ARG2(call);418 cur_attr.a.i.fg_color = IPC_GET_ARG1(call); 419 cur_attr.a.i.bg_color = IPC_GET_ARG2(call); 437 420 serial_set_attrs(&cur_attr); 421 438 422 retval = 0; 439 423 break; 440 424 case FB_SCROLL: 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 } 425 i = IPC_GET_ARG1(call); 426 if ((i > scr_height) || (i < -scr_height)) { 427 retval = EINVAL; 428 break; 453 429 } 454 455 serial_scroll(rows); 430 serial_scroll(i); 456 431 serial_goto(lastcol, lastrow); 457 432 retval = 0; … … 473 448 case FB_SCREEN_RECLAIM: 474 449 serial_clrscr(); 450 serial_set_attrs(&cur_attr); 475 451 retval = 0; 476 452 break;
Note:
See TracChangeset
for help on using the changeset viewer.