Changeset d2cc7e1 in mainline
- Timestamp:
- 2009-03-21T11:26:31Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0a5116db
- Parents:
- 5b8c75a
- Location:
- uspace
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/tetris/screen.c
r5b8c75a rd2cc7e1 116 116 { 117 117 console_goto(r, c); 118 }119 120 static void fflush(void)121 {122 console_flush();123 118 } 124 119 … … 275 270 if (cur_so) 276 271 resume_normal(); 277 fflush( );272 fflush(stdout); 278 273 } 279 274 -
uspace/app/tetris/tetris.c
r5b8c75a rd2cc7e1 391 391 scr_msg(key_msg, 0); 392 392 scr_msg(msg, 1); 393 //(void) fflush(stdout);393 (void) fflush(stdout); 394 394 } while (rwait((struct timeval *)NULL) == -1); 395 395 scr_msg(msg, 0); -
uspace/lib/libc/generic/console.c
r5b8c75a rd2cc7e1 39 39 #include <ipc/console.h> 40 40 #include <ipc/services.h> 41 #include <errno.h> 42 #include <string.h> 41 43 #include <console.h> 42 44 43 45 static int console_phone = -1; 46 47 /** Size of cbuffer. */ 48 #define CBUFFER_SIZE 256 49 50 /** Buffer for writing characters to the console. */ 51 static char cbuffer[CBUFFER_SIZE]; 52 53 /** Pointer to end of cbuffer. */ 54 static char *cbuffer_end = cbuffer + CBUFFER_SIZE; 55 56 /** Pointer to first available field in cbuffer. */ 57 static char *cbp = cbuffer; 58 59 static ssize_t cons_write(const char *buf, size_t nbyte); 60 static void cons_putchar(int c); 61 62 static void cbuffer_flush(void); 63 static void cbuffer_drain(void); 64 static void cbuffer_putc(int c); 65 44 66 45 67 void console_open(bool blocking) … … 85 107 { 86 108 int cons_phone = console_phone_get(true); 109 110 cbuffer_drain(); 87 111 async_msg_0(cons_phone, CONSOLE_CLEAR); 88 112 } … … 91 115 { 92 116 int cons_phone = console_phone_get(true); 117 118 cbuffer_flush(); 93 119 async_msg_2(cons_phone, CONSOLE_GOTO, row, col); 94 120 } … … 96 122 void console_putchar(int c) 97 123 { 124 cbuffer_putc(c); 125 } 126 127 /** Write all data from output buffer to the console. */ 128 static void cbuffer_flush(void) 129 { 130 int rc; 131 int len; 132 133 len = cbp - cbuffer; 134 135 while (len > 0) { 136 rc = cons_write(cbuffer, cbp - cbuffer); 137 if (rc < 0) 138 return; 139 140 len -= rc; 141 } 142 143 cbp = cbuffer; 144 } 145 146 /** Drop all data in console output buffer. */ 147 static void cbuffer_drain(void) 148 { 149 cbp = cbuffer; 150 } 151 152 /** Write one character to the output buffer. */ 153 static inline void cbuffer_putc(int c) 154 { 155 if (cbp == cbuffer_end) 156 cbuffer_flush(); 157 158 *cbp++ = c; 159 160 if (c == '\n') 161 cbuffer_flush(); 162 } 163 164 /** Write one character to the console via IPC. */ 165 static void cons_putchar(int c) 166 { 98 167 int cons_phone = console_phone_get(true); 99 168 async_msg_1(cons_phone, CONSOLE_PUTCHAR, c); 100 169 } 101 170 171 /** Write characters to the console via IPC. */ 172 static ssize_t cons_write(const char *buf, size_t nbyte) 173 { 174 int cons_phone = console_phone_get(true); 175 ipcarg_t rc; 176 ipc_call_t answer; 177 aid_t req; 178 179 async_serialize_start(); 180 181 req = async_send_0(cons_phone, CONSOLE_WRITE, &answer); 182 rc = ipc_data_write_start(cons_phone, (void *) buf, nbyte); 183 184 if (rc != EOK) { 185 async_wait_for(req, NULL); 186 async_serialize_end(); 187 return (ssize_t) rc; 188 } 189 190 async_wait_for(req, &rc); 191 async_serialize_end(); 192 193 if (rc == EOK) 194 return (ssize_t) IPC_GET_ARG1(answer); 195 else 196 return -1; 197 } 198 199 /** Write characters to the console. */ 200 ssize_t console_write(const char *buf, size_t nbyte) 201 { 202 size_t left; 203 204 left = nbyte; 205 206 while (left > 0) { 207 cbuffer_putc(*buf++); 208 --left; 209 } 210 211 return nbyte; 212 } 213 214 /** Write a NULL-terminated string to the console. */ 215 void console_putstr(const char *s) 216 { 217 size_t len; 218 ssize_t rc; 219 220 len = strlen(s); 221 while (len > 0) { 222 rc = console_write(s, len); 223 if (rc < 0) 224 return; /* Error */ 225 s += rc; 226 len -= rc; 227 } 228 } 229 230 /** Flush all output to the console. */ 102 231 void console_flush(void) 103 232 { 104 int cons_phone = console_phone_get(true); 233 int cons_phone = console_phone_get(false); 234 235 cbuffer_flush(); 105 236 async_msg_0(cons_phone, CONSOLE_FLUSH); 106 237 } … … 123 254 { 124 255 int cons_phone = console_phone_get(true); 256 257 cbuffer_flush(); 125 258 async_msg_1(cons_phone, CONSOLE_SET_STYLE, style); 126 259 } … … 129 262 { 130 263 int cons_phone = console_phone_get(true); 264 265 cbuffer_flush(); 131 266 async_msg_3(cons_phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags); 132 267 } … … 135 270 { 136 271 int cons_phone = console_phone_get(true); 272 273 cbuffer_flush(); 137 274 async_msg_2(cons_phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color); 138 275 } … … 141 278 { 142 279 int cons_phone = console_phone_get(true); 280 281 cbuffer_flush(); 143 282 async_msg_1(cons_phone, CONSOLE_CURSOR_VISIBILITY, show != 0); 144 283 } -
uspace/lib/libc/generic/io/io.c
r5b8c75a rd2cc7e1 98 98 { 99 99 unsigned char c; 100 101 flush_stdout(); 100 102 if (read_stdin((void *) &c, 1) == 1) 101 103 return c; … … 104 106 } 105 107 108 int fflush(FILE *f) 109 { 110 (void) f; 111 return flush_stdout(); 112 } 113 106 114 /** @} 107 115 */ -
uspace/lib/libc/generic/io/stream.c
r5b8c75a rd2cc7e1 81 81 { 82 82 int cons_phone = console_phone_get(false); 83 int left, rc; 83 84 84 85 if (cons_phone >= 0) { 85 86 int i; 86 87 87 for (i = 0; i < count; i++) 88 console_putchar(((const char *) buf)[i]); 88 left = count; 89 while (left > 0) { 90 rc = console_write(buf, left); 91 if (rc < 0) 92 break; 93 buf += rc; 94 left -= rc; 95 } 89 96 90 97 return count; 91 98 } else 92 99 return __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, count); 100 } 101 102 int flush_stdout(void) 103 { 104 console_flush(); 105 return 0; 93 106 } 94 107 -
uspace/lib/libc/include/console.h
r5b8c75a rd2cc7e1 49 49 extern void console_goto(int, int); 50 50 extern void console_putchar(int); 51 extern ssize_t console_write(const char *buf, size_t nbyte); 52 extern void console_putstr(const char *s); 51 53 extern void console_flush(void); 52 54 -
uspace/lib/libc/include/io/stream.h
r5b8c75a rd2cc7e1 45 45 extern ssize_t write_stdout(const void *, size_t); 46 46 extern ssize_t write_stderr(const void *, size_t); 47 extern int flush_stdout(void); 47 48 48 49 #endif -
uspace/lib/libc/include/ipc/console.h
r5b8c75a rd2cc7e1 41 41 CONSOLE_GETKEY = IPC_FIRST_USER_METHOD, 42 42 CONSOLE_PUTCHAR, 43 CONSOLE_WRITE, 43 44 CONSOLE_CLEAR, 44 45 CONSOLE_GOTO, -
uspace/lib/libc/include/ipc/fb.h
r5b8c75a rd2cc7e1 40 40 typedef enum { 41 41 FB_PUTCHAR = IPC_FIRST_USER_METHOD, 42 FB_WRITE, 42 43 FB_CLEAR, 43 44 FB_GET_CSIZE, -
uspace/lib/libc/include/stdio.h
r5b8c75a rd2cc7e1 70 70 extern int puts(const char *); 71 71 extern int putchar(int); 72 extern int fflush(FILE *); 72 73 73 74 extern int printf(const char *, ...); -
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; -
uspace/srv/fb/ega.c
r5b8c75a rd2cc7e1 360 360 361 361 default: 362 retval = E NOENT;362 retval = EINVAL; 363 363 } 364 364 ipc_answer_0(callid, retval); -
uspace/srv/fb/fb.c
r5b8c75a rd2cc7e1 1472 1472 return rgb_from_idx(&vport->attr, fg_color, bg_color, flags); 1473 1473 } 1474 1475 #define FB_WRITE_BUF_SIZE 256 1476 static char fb_write_buf[FB_WRITE_BUF_SIZE]; 1477 1478 static void fb_write(viewport_t *vport, ipc_callid_t rid, ipc_call_t *request) 1479 { 1480 int row, col; 1481 ipc_callid_t callid; 1482 size_t len; 1483 size_t i; 1484 1485 row = IPC_GET_ARG1(*request); 1486 col = IPC_GET_ARG2(*request); 1487 1488 if ((col >= vport->cols) || (row >= vport->rows)) { 1489 ipc_answer_0(callid, EINVAL); 1490 ipc_answer_0(rid, EINVAL); 1491 return; 1492 } 1493 1494 if (!ipc_data_write_receive(&callid, &len)) { 1495 ipc_answer_0(callid, EINVAL); 1496 ipc_answer_0(rid, EINVAL); 1497 return; 1498 } 1499 1500 if (len > FB_WRITE_BUF_SIZE) 1501 len = FB_WRITE_BUF_SIZE; 1502 if (len >= vport->cols - col) 1503 len = vport->cols - col; 1504 1505 (void) ipc_data_write_finalize(callid, fb_write_buf, len); 1506 1507 for (i = 0; i < len; i++) { 1508 draw_char(vport, fb_write_buf[i], col++, row); 1509 } 1510 1511 ipc_answer_1(rid, EOK, len); 1512 } 1513 1474 1514 1475 1515 /** Function for handling connections to FB … … 1547 1587 /* Message already answered */ 1548 1588 continue; 1589 case FB_WRITE: 1590 fb_write(vport, callid, &call); 1591 1592 /* Message already answered */ 1593 continue; 1549 1594 case FB_CLEAR: 1550 1595 vport_clear(vport); -
uspace/srv/fb/serial_console.c
r5b8c75a rd2cc7e1 244 244 } 245 245 246 int lastcol = 0; 247 int lastrow = 0; 248 249 #define FB_WRITE_BUF_SIZE 256 250 static char fb_write_buf[FB_WRITE_BUF_SIZE]; 251 252 static void fb_write(ipc_callid_t rid, ipc_call_t *request) 253 { 254 int row, col; 255 ipc_callid_t callid; 256 size_t len; 257 size_t i; 258 259 row = IPC_GET_ARG1(*request); 260 col = IPC_GET_ARG2(*request); 261 262 if ((col >= scr_width) || (row >= scr_height)) { 263 ipc_answer_0(callid, EINVAL); 264 ipc_answer_0(rid, EINVAL); 265 return; 266 } 267 268 if (!ipc_data_write_receive(&callid, &len)) { 269 ipc_answer_0(callid, EINVAL); 270 ipc_answer_0(rid, EINVAL); 271 return; 272 } 273 274 if (len > FB_WRITE_BUF_SIZE) 275 len = FB_WRITE_BUF_SIZE; 276 if (len >= scr_width - col) 277 len = scr_width - col; 278 279 (void) ipc_data_write_finalize(callid, fb_write_buf, len); 280 281 if ((lastcol != col) || (lastrow != row)) 282 serial_goto(row, col); 283 284 for (i = 0; i < len; i++) { 285 (*putc_function)(fb_write_buf[i]); 286 } 287 288 lastcol = col + len; 289 lastrow = row; 290 291 ipc_answer_1(rid, EOK, len); 292 } 293 246 294 /** 247 295 * Main function of the thread serving client connections. … … 256 304 257 305 char c; 258 int lastcol = 0;259 int lastrow = 0;260 306 int newcol; 261 307 int newrow; … … 318 364 retval = 0; 319 365 break; 366 case FB_WRITE: 367 fb_write(callid, &call); 368 369 /* Message already answered */ 370 continue; 320 371 case FB_CURSOR_GOTO: 321 372 newrow = IPC_GET_ARG1(call);
Note:
See TracChangeset
for help on using the changeset viewer.