Changeset d2cc7e1 in mainline for uspace/srv/console/console.c


Ignore:
Timestamp:
2009-03-21T11:26:31Z (16 years ago)
Author:
Jiri Svoboda <jirik.svoboda@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0a5116db
Parents:
5b8c75a
Message:

Buffer console output with line granularity. Makes esp. msim/ski console faster. EGA-fb needs fixing.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/console/console.c

    r5b8c75a rd2cc7e1  
    9090                                                 * faster virtual console
    9191                                                 * switching */
     92/** Size of fb_buf. */
     93#define FB_BUF_SIZE 256
     94
     95/** Buffer for sending characters to FB driver. */
     96static char fb_buf[FB_BUF_SIZE];
     97
     98/* Properties of fb_buf data. */
     99static int fb_buf_row;          /**< Row where fb_buf data belong. */
     100static int fb_buf_col;          /**< Column where fb_buf data start. */
     101static int fb_console;          /**< VC to which fb_buf data belong. */
     102int 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. */
     108static char cwrite_buf[CWRITE_BUF_SIZE];
    92109
    93110
     
    159176}
    160177
     178/** Write a character vector to FB driver via IPC. */
     179static 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. */
     206static 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. */
    161226static void prtchr(char c, int row, int col)
    162227{
    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;
    164238}
    165239
     
    170244static void write_char(int console, char key)
    171245{
     246        bool flush_cursor = false;
    172247        screenbuffer_t *scr = &(connections[console].screenbuffer);
    173        
     248
    174249        switch (key) {
    175250        case '\n':
     251                fb_buf_flush();
     252                flush_cursor = true;
    176253                scr->position_y++;
    177254                scr->position_x = 0;
    178255                break;
    179256        case '\r':
     257                fb_buf_flush();
    180258                break;
    181259        case '\t':
     260                fb_buf_flush();
    182261                scr->position_x += 8;
    183262                scr->position_x -= scr->position_x % 8;
    184263                break;
    185264        case '\b':
     265                fb_buf_flush();
    186266                if (scr->position_x == 0)
    187267                        break;
     
    198278                scr->position_x++;
    199279        }
    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        }
    202286       
    203287        if (scr->position_y >= scr->size_y) {
     
    208292                        async_msg_1(fb_info.phone, FB_SCROLL, 1);
    209293        }
    210        
     294
    211295        scr->position_x = scr->position_x % scr->size_x;
    212        
    213         if (console == active_console)
     296
     297        if (console == active_console && flush_cursor)
    214298                curs_goto(scr->position_y, scr->position_x);
    215        
    216299}
    217300
     
    226309        if (newcons == active_console)
    227310                return;
    228        
     311
     312        fb_buf_flush();
     313
    229314        if (newcons == KERNEL_CONSOLE) {
    230315                async_serialize_start();
     
    361446}
    362447
     448/** Handle CONSOLE_WRITE call. */
     449static 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
    363473/** Default thread for new connections */
    364474static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
     
    412522                        gcons_notify_char(consnum);
    413523                        break;
     524                case CONSOLE_WRITE:
     525                        cons_write(consnum, callid, &call);
     526                        continue;
    414527                case CONSOLE_CLEAR:
    415528                        /* Send message to fb */
     
    422535                        break;
    423536                case CONSOLE_GOTO:
     537                        fb_buf_flush();
    424538                        screenbuffer_goto(&conn->screenbuffer,
    425539                            IPC_GET_ARG2(call), IPC_GET_ARG1(call));
     
    433547                        break;
    434548                case CONSOLE_FLUSH:
     549                        fb_buf_flush();
    435550                        if (consnum == active_console)
    436551                                async_req_0_0(fb_info.phone, FB_FLUSH);
    437552                        break;
    438553                case CONSOLE_SET_STYLE:
     554                        fb_buf_flush();
    439555                        arg1 = IPC_GET_ARG1(call);
    440556                        screenbuffer_set_style(&conn->screenbuffer, arg1);
     
    443559                        break;
    444560                case CONSOLE_SET_COLOR:
     561                        fb_buf_flush();
    445562                        arg1 = IPC_GET_ARG1(call);
    446563                        arg2 = IPC_GET_ARG2(call);
     
    452569                        break;
    453570                case CONSOLE_SET_RGB_COLOR:
     571                        fb_buf_flush();
    454572                        arg1 = IPC_GET_ARG1(call);
    455573                        arg2 = IPC_GET_ARG2(call);
     
    460578                        break;
    461579                case CONSOLE_CURSOR_VISIBILITY:
     580                        fb_buf_flush();
    462581                        arg1 = IPC_GET_ARG1(call);
    463582                        conn->screenbuffer.is_cursor_visible = arg1;
Note: See TracChangeset for help on using the changeset viewer.