Changeset 1601f3c in mainline for uspace/srv/console/console.c
- Timestamp:
- 2009-05-21T15:32:42Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7d158097
- Parents:
- a095d20
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/console/console.c
ra095d20 r1601f3c 28 28 29 29 /** @addtogroup console 30 * @{ 30 * @{ 31 31 */ 32 32 /** @file … … 56 56 #include "gcons.h" 57 57 58 #define MAX_KEYREQUESTS_BUFFERED 32 59 60 #define NAME "console" 58 #define NAME "console" 59 60 #define MAX_KEYREQUESTS_BUFFERED 32 61 62 /** Size of cwrite_buf. */ 63 #define CWRITE_BUF_SIZE 256 61 64 62 65 /** Index of currently used virtual console. … … 70 73 /** Information about framebuffer */ 71 74 struct { 72 int phone; 73 ipcarg_t rows; 74 ipcarg_t cols; 75 int phone; /**< Framebuffer phone */ 76 ipcarg_t rows; /**< Framebuffer rows */ 77 ipcarg_t cols; /**< Framebuffer columns */ 75 78 } fb_info; 76 79 77 80 typedef struct { 78 keybuffer_t keybuffer; /**< Buffer for incoming keys. */ 81 keybuffer_t keybuffer; /**< Buffer for incoming keys. */ 82 79 83 /** Buffer for unsatisfied request for keys. */ 80 84 FIFO_CREATE_STATIC(keyrequests, ipc_callid_t, 81 MAX_KEYREQUESTS_BUFFERED); 82 int keyrequest_counter; /**< Number of requests in buffer. */ 83 int client_phone; /**< Phone to connected client. */ 84 int used; /**< 1 if this virtual console is 85 * connected to some client.*/ 86 screenbuffer_t screenbuffer; /**< Screenbuffer for saving screen 87 * contents and related settings. */ 85 MAX_KEYREQUESTS_BUFFERED); 86 87 int keyrequest_counter; /**< Number of requests in buffer. */ 88 int client_phone; /**< Phone to connected client. */ 89 int used; /**< 1 if this virtual console is 90 connected to some client. */ 91 screenbuffer_t screenbuffer; /**< Screenbuffer for saving screen 92 contents and related settings. */ 88 93 } connection_t; 89 94 90 static connection_t connections[CONSOLE_COUNT]; /**< Array of data for virtual 91 * consoles */ 92 static keyfield_t *interbuffer = NULL; /**< Pointer to memory shared 93 *with framebufer used for94 * faster virtual console 95 * switching */ 95 /** Array of data for virtual consoles */ 96 static connection_t connections[CONSOLE_COUNT]; 97 98 /** Pointer to memory shared with framebufer used for 99 faster virtual console switching */ 100 static keyfield_t *interbuffer = NULL; 96 101 97 102 /** Information on row-span yet unsent to FB driver. */ 98 103 struct { 99 int row; 100 int col; 101 int n;/**< Width of the span. */104 int row; /**< Row where the span lies. */ 105 int col; /**< Leftmost column of the span. */ 106 int cnt; /**< Width of the span. */ 102 107 } fb_pending; 103 104 /** Size of cwrite_buf. */105 #define CWRITE_BUF_SIZE 256106 108 107 109 /** Buffer for receiving data via the CONSOLE_WRITE call from the client. */ 108 110 static char cwrite_buf[CWRITE_BUF_SIZE]; 109 110 static void fb_putchar(wchar_t c, int row, int col);111 112 111 113 112 /** Find unused virtual console. … … 122 121 return i; 123 122 } 123 124 124 return -1; 125 125 } … … 186 186 set_style(attrs->a.s.style); 187 187 break; 188 189 188 case at_idx: 190 189 set_color(attrs->a.i.fg_color, attrs->a.i.bg_color, 191 190 attrs->a.i.flags); 192 191 break; 193 194 192 case at_rgb: 195 193 set_rgb_color(attrs->a.r.fg_color, attrs->a.r.bg_color); … … 201 199 static void fb_update_area(connection_t *conn, int x, int y, int w, int h) 202 200 { 203 int i , j;204 int rc;201 int i; 202 int j; 205 203 attrs_t *attrs; 206 204 keyfield_t *field; 207 205 208 206 if (interbuffer) { 209 207 for (j = 0; j < h; j++) { 210 208 for (i = 0; i < w; i++) { 211 209 interbuffer[i + j * w] = 212 *get_field_at(&conn->screenbuffer, 213 x + i, y + j); 210 *get_field_at(&conn->screenbuffer, x + i, y + j); 214 211 } 215 212 } 216 217 rc =async_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,213 214 async_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA, 218 215 x, y, w, h); 219 } else {220 rc = ENOTSUP;221 }222 223 if (rc != 0) {224 /*225 attrs = &conn->screenbuffer.attrs;226 227 for (j = 0; j < h; j++) {228 for (i = 0; i < w; i++) {229 field = get_field_at(&conn->screenbuffer,230 x + i, y + j);231 if (!attrs_same(*attrs, field->attrs))232 set_attrs(&field->attrs);233 attrs = &field->attrs;234 235 fb_putchar(field->character, y + j, x + i);236 }237 }*/238 216 } 239 217 } … … 242 220 static void fb_pending_flush(void) 243 221 { 244 screenbuffer_t *scr; 245 246 scr = &(connections[active_console].screenbuffer); 247 248 if (fb_pending.n > 0) { 222 screenbuffer_t *scr 223 = &(connections[active_console].screenbuffer); 224 225 if (fb_pending.cnt > 0) { 249 226 fb_update_area(&connections[active_console], fb_pending.col, 250 fb_pending.row, fb_pending. n, 1);251 fb_pending. n= 0;227 fb_pending.row, fb_pending.cnt, 1); 228 fb_pending.cnt = 0; 252 229 } 253 230 } … … 257 234 * This adds the cell to the pending rowspan if possible. Otherwise 258 235 * the old span is flushed first. 236 * 259 237 */ 260 238 static void cell_mark_changed(int row, int col) 261 239 { 262 if (fb_pending. n!= 0) {263 if ( row != fb_pending.row ||264 col != fb_pending.col + fb_pending.n) {240 if (fb_pending.cnt != 0) { 241 if ((row != fb_pending.row) 242 || (col != fb_pending.col + fb_pending.cnt)) { 265 243 fb_pending_flush(); 266 244 } 267 245 } 268 269 if (fb_pending. n== 0) {246 247 if (fb_pending.cnt == 0) { 270 248 fb_pending.row = row; 271 249 fb_pending.col = col; 272 250 } 273 274 ++fb_pending.n; 275 } 276 251 252 fb_pending.cnt++; 253 } 277 254 278 255 /** Print a character to the active VC with buffering. */ … … 287 264 bool flush_cursor = false; 288 265 screenbuffer_t *scr = &(connections[console].screenbuffer); 289 266 290 267 switch (ch) { 291 268 case '\n': … … 299 276 case '\t': 300 277 scr->position_x += 8; 301 scr->position_x -= scr->position_x % 8; 278 scr->position_x -= scr->position_x % 8; 302 279 break; 303 280 case '\b': … … 309 286 screenbuffer_putchar(scr, ' '); 310 287 break; 311 default: 288 default: 312 289 if (console == active_console) 313 290 cell_mark_changed(scr->position_y, scr->position_x); 314 291 315 292 screenbuffer_putchar(scr, ch); 316 293 scr->position_x++; 317 294 } 318 295 319 296 if (scr->position_x >= scr->size_x) { 320 297 flush_cursor = true; … … 330 307 async_msg_1(fb_info.phone, FB_SCROLL, 1); 331 308 } 332 309 333 310 scr->position_x = scr->position_x % scr->size_x; 334 311 335 312 if (console == active_console && flush_cursor) 336 313 curs_goto(scr->position_y, scr->position_x); … … 341 318 { 342 319 connection_t *conn; 343 int i, j, rc; 320 int i; 321 int j; 322 int rc; 344 323 keyfield_t *field; 345 324 attrs_t *attrs; … … 347 326 if (newcons == active_console) 348 327 return; 349 328 350 329 fb_pending_flush(); 351 330 352 331 if (newcons == KERNEL_CONSOLE) { 353 332 async_serialize_start(); … … 357 336 kbd_yield(); 358 337 async_serialize_end(); 359 338 360 339 361 340 if (__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE)) { … … 409 388 attrs = &field->attrs; 410 389 if ((field->character == ' ') && 411 (attrs_same(field->attrs, 412 conn->screenbuffer.attrs))) 390 (attrs_same(field->attrs, conn->screenbuffer.attrs))) 413 391 continue; 414 392 415 393 fb_putchar(field->character, j, i); 416 394 } … … 436 414 437 415 /* Ignore parameters, the connection is alread opened */ 438 while ( 1) {416 while (true) { 439 417 callid = async_get_call(&call); 440 418 switch (IPC_GET_METHOD(call)) { … … 461 439 ev.c = IPC_GET_ARG4(call); 462 440 463 /* switch to another virtual console */ 464 441 /* Switch to another virtual console */ 465 442 conn = &connections[active_console]; 466 443 467 444 if ((ev.key >= KC_F1) && (ev.key < KC_F1 + 468 445 CONSOLE_COUNT) && ((ev.mods & KM_CTRL) == 0)) { … … 474 451 } 475 452 476 /* if client is awaiting key, send it */477 if (conn->keyrequest_counter > 0) { 453 /* If client is awaiting key, send it */ 454 if (conn->keyrequest_counter > 0) { 478 455 conn->keyrequest_counter--; 479 456 ipc_answer_4(fifo_pop(conn->keyrequests), EOK, … … 481 458 break; 482 459 } 483 460 484 461 keybuffer_push(&conn->keybuffer, &ev); 485 462 retval = 0; 486 463 487 464 break; 488 465 default: … … 500 477 wchar_t ch; 501 478 size_t off; 502 479 503 480 if (!ipc_data_write_receive(&callid, &size)) { 504 481 ipc_answer_0(callid, EINVAL); … … 506 483 return; 507 484 } 508 485 509 486 if (size > CWRITE_BUF_SIZE) 510 487 size = CWRITE_BUF_SIZE; 511 488 512 489 (void) ipc_data_write_finalize(callid, cwrite_buf, size); 513 490 514 491 async_serialize_start(); 515 492 516 493 off = 0; 517 494 while (off < size) { … … 519 496 write_char(consnum, ch); 520 497 } 521 498 522 499 async_serialize_end(); 523 500 524 501 gcons_notify_char(consnum); 525 502 ipc_answer_1(rid, EOK, size); … … 553 530 ipc_answer_0(iid, EOK); 554 531 555 while ( 1) {532 while (true) { 556 533 async_serialize_end(); 557 534 callid = async_get_call(&call); … … 562 539 arg3 = 0; 563 540 arg4 = 0; 564 541 565 542 switch (IPC_GET_METHOD(call)) { 566 543 case IPC_M_PHONE_HUNGUP: … … 609 586 if (consnum == active_console) { 610 587 async_req_0_0(fb_info.phone, FB_FLUSH); 611 588 612 589 scr = &(connections[consnum].screenbuffer); 613 590 curs_goto(scr->position_y, scr->position_x); … … 651 628 /* buffer is empty -> store request */ 652 629 if (conn->keyrequest_counter < 653 MAX_KEYREQUESTS_BUFFERED) { 630 MAX_KEYREQUESTS_BUFFERED) { 654 631 fifo_push(conn->keyrequests, callid); 655 632 conn->keyrequest_counter++; … … 744 721 } 745 722 connections[KERNEL_CONSOLE].used = 1; 746 723 747 724 /* Set up shared memory buffer. */ 748 725 ib_size = sizeof(keyfield_t) * fb_info.cols * fb_info.rows; 749 726 interbuffer = as_get_mappable_page(ib_size); 750 751 fb_pending. n= 0;752 727 728 fb_pending.cnt = 0; 729 753 730 if (as_area_create(interbuffer, ib_size, AS_AREA_READ | 754 731 AS_AREA_WRITE | AS_AREA_CACHEABLE) != interbuffer) { 755 732 interbuffer = NULL; 756 733 } 757 734 758 735 if (interbuffer) { 759 736 if (ipc_share_out_start(fb_info.phone, interbuffer, … … 775 752 if (event_subscribe(EVENT_KCONSOLE, 0) != EOK) 776 753 printf(NAME ": Error registering kconsole notifications\n"); 777 754 778 755 async_set_interrupt_received(interrupt_received); 779 756
Note:
See TracChangeset
for help on using the changeset viewer.