Changeset d2cc7e1 in mainline for uspace/srv/console/console.c
- Timestamp:
- 2009-03-21T11:26:31Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0a5116db
- Parents:
- 5b8c75a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/console/console.c
r5b8c75a rd2cc7e1 90 90 * faster virtual console 91 91 * switching */ 92 /** Size of fb_buf. */ 93 #define FB_BUF_SIZE 256 94 95 /** Buffer for sending characters to FB driver. */ 96 static char fb_buf[FB_BUF_SIZE]; 97 98 /* Properties of fb_buf data. */ 99 static int fb_buf_row; /**< Row where fb_buf data belong. */ 100 static int fb_buf_col; /**< Column where fb_buf data start. */ 101 static int fb_console; /**< VC to which fb_buf data belong. */ 102 int fb_bi = 0; /**< Number of valid chars in fb_buf. */ 103 104 /** Size of cwrite_buf. */ 105 #define CWRITE_BUF_SIZE 256 106 107 /** Buffer for receiving data via the CONSOLE_WRITE call from the client. */ 108 static char cwrite_buf[CWRITE_BUF_SIZE]; 92 109 93 110 … … 159 176 } 160 177 178 /** Write a character vector to FB driver via IPC. */ 179 static ssize_t fb_write(const char *buf, size_t nbyte, int row, int col) 180 { 181 ipcarg_t rc; 182 ipc_call_t answer; 183 aid_t req; 184 185 async_serialize_start(); 186 187 req = async_send_2(fb_info.phone, FB_WRITE, row, col, &answer); 188 rc = ipc_data_write_start(fb_info.phone, (void *) buf, nbyte); 189 190 if (rc != EOK) { 191 async_wait_for(req, NULL); 192 async_serialize_end(); 193 return (ssize_t) rc; 194 } 195 196 async_wait_for(req, &rc); 197 async_serialize_end(); 198 199 if (rc == EOK) 200 return (ssize_t) IPC_GET_ARG1(answer); 201 else 202 return -1; 203 } 204 205 /** Flush buffered characters to FB. */ 206 static void fb_buf_flush(void) 207 { 208 screenbuffer_t *scr; 209 int i; 210 211 scr = &(connections[fb_console].screenbuffer); 212 213 if (fb_bi > 0) { 214 if (fb_write(fb_buf, fb_bi, fb_buf_row, fb_buf_col) < 0) { 215 /* Try falling back to char-by-char. */ 216 for (i = 0; i < fb_bi; i++) { 217 async_msg_3(fb_info.phone, FB_PUTCHAR, fb_buf[i], 218 fb_buf_row, fb_buf_col + i); 219 } 220 } 221 fb_bi = 0; 222 } 223 } 224 225 /** Print a character to the active VC with buffering. */ 161 226 static void prtchr(char c, int row, int col) 162 227 { 163 async_msg_3(fb_info.phone, FB_PUTCHAR, c, row, col); 228 if (fb_bi >= FB_BUF_SIZE) 229 fb_buf_flush(); 230 231 if (fb_bi == 0) { 232 fb_buf_row = row; 233 fb_buf_col = col; 234 fb_console = active_console; 235 } 236 237 fb_buf[fb_bi++] = c; 164 238 } 165 239 … … 170 244 static void write_char(int console, char key) 171 245 { 246 bool flush_cursor = false; 172 247 screenbuffer_t *scr = &(connections[console].screenbuffer); 173 248 174 249 switch (key) { 175 250 case '\n': 251 fb_buf_flush(); 252 flush_cursor = true; 176 253 scr->position_y++; 177 254 scr->position_x = 0; 178 255 break; 179 256 case '\r': 257 fb_buf_flush(); 180 258 break; 181 259 case '\t': 260 fb_buf_flush(); 182 261 scr->position_x += 8; 183 262 scr->position_x -= scr->position_x % 8; 184 263 break; 185 264 case '\b': 265 fb_buf_flush(); 186 266 if (scr->position_x == 0) 187 267 break; … … 198 278 scr->position_x++; 199 279 } 200 201 scr->position_y += (scr->position_x >= scr->size_x); 280 281 if (scr->position_x >= scr->size_x) { 282 fb_buf_flush(); 283 flush_cursor = true; 284 scr->position_y++; 285 } 202 286 203 287 if (scr->position_y >= scr->size_y) { … … 208 292 async_msg_1(fb_info.phone, FB_SCROLL, 1); 209 293 } 210 294 211 295 scr->position_x = scr->position_x % scr->size_x; 212 213 if (console == active_console )296 297 if (console == active_console && flush_cursor) 214 298 curs_goto(scr->position_y, scr->position_x); 215 216 299 } 217 300 … … 226 309 if (newcons == active_console) 227 310 return; 228 311 312 fb_buf_flush(); 313 229 314 if (newcons == KERNEL_CONSOLE) { 230 315 async_serialize_start(); … … 361 446 } 362 447 448 /** Handle CONSOLE_WRITE call. */ 449 static void cons_write(int consnum, ipc_callid_t rid, ipc_call_t *request) 450 { 451 ipc_callid_t callid; 452 size_t len; 453 size_t i; 454 455 if (!ipc_data_write_receive(&callid, &len)) { 456 ipc_answer_0(callid, EINVAL); 457 ipc_answer_0(rid, EINVAL); 458 } 459 460 if (len > CWRITE_BUF_SIZE) 461 len = CWRITE_BUF_SIZE; 462 463 (void) ipc_data_write_finalize(callid, cwrite_buf, len); 464 465 for (i = 0; i < len; i++) { 466 write_char(consnum, cwrite_buf[i]); 467 } 468 469 gcons_notify_char(consnum); 470 ipc_answer_1(rid, EOK, len); 471 } 472 363 473 /** Default thread for new connections */ 364 474 static void client_connection(ipc_callid_t iid, ipc_call_t *icall) … … 412 522 gcons_notify_char(consnum); 413 523 break; 524 case CONSOLE_WRITE: 525 cons_write(consnum, callid, &call); 526 continue; 414 527 case CONSOLE_CLEAR: 415 528 /* Send message to fb */ … … 422 535 break; 423 536 case CONSOLE_GOTO: 537 fb_buf_flush(); 424 538 screenbuffer_goto(&conn->screenbuffer, 425 539 IPC_GET_ARG2(call), IPC_GET_ARG1(call)); … … 433 547 break; 434 548 case CONSOLE_FLUSH: 549 fb_buf_flush(); 435 550 if (consnum == active_console) 436 551 async_req_0_0(fb_info.phone, FB_FLUSH); 437 552 break; 438 553 case CONSOLE_SET_STYLE: 554 fb_buf_flush(); 439 555 arg1 = IPC_GET_ARG1(call); 440 556 screenbuffer_set_style(&conn->screenbuffer, arg1); … … 443 559 break; 444 560 case CONSOLE_SET_COLOR: 561 fb_buf_flush(); 445 562 arg1 = IPC_GET_ARG1(call); 446 563 arg2 = IPC_GET_ARG2(call); … … 452 569 break; 453 570 case CONSOLE_SET_RGB_COLOR: 571 fb_buf_flush(); 454 572 arg1 = IPC_GET_ARG1(call); 455 573 arg2 = IPC_GET_ARG2(call); … … 460 578 break; 461 579 case CONSOLE_CURSOR_VISIBILITY: 580 fb_buf_flush(); 462 581 arg1 = IPC_GET_ARG1(call); 463 582 conn->screenbuffer.is_cursor_visible = arg1;
Note:
See TracChangeset
for help on using the changeset viewer.