Changeset dc033a1 in mainline


Ignore:
Timestamp:
2009-03-22T17:45:15Z (15 years ago)
Author:
Jiri Svoboda <jirik.svoboda@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
3fe00ee
Parents:
0a5116db
Message:

Get rid of FB_WRITE. We can use FB_DRAW_TEXT_DATA if we extend it just a little bit.

Location:
uspace
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libc/include/ipc/fb.h

    r0a5116db rdc033a1  
    4040typedef enum {
    4141        FB_PUTCHAR = IPC_FIRST_USER_METHOD,
    42         FB_WRITE,
    4342        FB_CLEAR,
    4443        FB_GET_CSIZE,
  • uspace/srv/console/console.c

    r0a5116db rdc033a1  
    6363int prev_console = 0;
    6464
    65 /** Information about framebuffer
    66  */
     65/** Information about framebuffer */
    6766struct {
    6867        int phone;              /**< Framebuffer phone */
     
    9089                                                 * faster virtual console
    9190                                                 * 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. */
     91
     92/** Information on row-span yet unsent to FB driver. */
     93struct {
     94        int row;                /**< Row where the span lies. */
     95        int col;                /**< Leftmost column of the span. */
     96        int n;                  /**< Width of the span. */
     97} fb_pending;
    10398
    10499/** Size of cwrite_buf. */
     
    107102/** Buffer for receiving data via the CONSOLE_WRITE call from the client. */
    108103static char cwrite_buf[CWRITE_BUF_SIZE];
     104
     105static void fb_putchar(char c, int row, int col);
    109106
    110107
     
    176173}
    177174
    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)
     175/** Send an area of screenbuffer to the FB driver. */
     176static void fb_update_area(connection_t *conn, int x, int y, int w, int h)
     177{
     178        int i, j;
     179        int rc;
     180        attrs_t *attrs;
     181        keyfield_t *field;
     182
     183        if (interbuffer) {
     184                for (j = 0; j < h; j++) {
     185                        for (i = 0; i < w; i++) {
     186                                interbuffer[i + j * w] =
     187                                    *get_field_at(&conn->screenbuffer,
     188                                        x + i, y + j);
     189                        }
     190                }
     191
     192                rc = async_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,
     193                    x, y, w, h);
     194        } else {
     195                rc = ENOTSUP;
     196        }
     197
     198        if (rc != 0) {
     199                attrs = &conn->screenbuffer.attrs;
     200
     201                for (j = 0; j < h; j++) {
     202                        for (i = 0; i < w; i++) {
     203                                field = get_field_at(&conn->screenbuffer,
     204                                    x + i, y + j);
     205                                if (!attrs_same(*attrs, field->attrs))
     206                                        set_attrs(&field->attrs);
     207                                attrs = &field->attrs;
     208
     209                                fb_putchar(field->character, y + j, x + i);
     210                        }
     211                }
     212        }
     213}
     214
     215/** Flush pending cells to FB. */
     216static void fb_pending_flush(void)
    207217{
    208218        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 }
     219
     220        scr = &(connections[active_console].screenbuffer);
     221
     222        if (fb_pending.n > 0) {
     223                fb_update_area(&connections[active_console], fb_pending.col,
     224                    fb_pending.row, fb_pending.n, 1);
     225                fb_pending.n = 0;
     226        }
     227}
     228
     229/** Mark a character cell as changed.
     230 *
     231 * This adds the cell to the pending rowspan if possible. Otherwise
     232 * the old span is flushed first.
     233 */
     234static void cell_mark_changed(int row, int col)
     235{
     236        if (fb_pending.n != 0) {
     237                if (row != fb_pending.row ||
     238                    col != fb_pending.col + fb_pending.n) {
     239                        fb_pending_flush();
     240                }
     241        }
     242
     243        if (fb_pending.n == 0) {
     244                fb_pending.row = row;
     245                fb_pending.col = col;
     246        }
     247
     248        ++fb_pending.n;
     249}
     250
    224251
    225252/** Print a character to the active VC with buffering. */
    226 static void prtchr(char c, int row, int col)
    227 {
    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;
    238 }
    239 
    240 /** Check key and process special keys.
    241  *
    242  *
    243  */
     253static void fb_putchar(char c, int row, int col)
     254{
     255        async_msg_3(fb_info.phone, FB_PUTCHAR, c, row, col);
     256}
     257
     258/** Process a character from the client (TTY emulation). */
    244259static void write_char(int console, char key)
    245260{
     
    249264        switch (key) {
    250265        case '\n':
    251                 fb_buf_flush();
     266                fb_pending_flush();
    252267                flush_cursor = true;
    253268                scr->position_y++;
     
    255270                break;
    256271        case '\r':
    257                 fb_buf_flush();
    258272                break;
    259273        case '\t':
    260                 fb_buf_flush();
    261274                scr->position_x += 8;
    262275                scr->position_x -= scr->position_x % 8;
    263276                break;
    264277        case '\b':
    265                 fb_buf_flush();
    266278                if (scr->position_x == 0)
    267279                        break;
    268280                scr->position_x--;
    269281                if (console == active_console)
    270                         prtchr(' ', scr->position_y, scr->position_x);
     282                        cell_mark_changed(scr->position_y, scr->position_x);
    271283                screenbuffer_putchar(scr, ' ');
    272284                break;
    273285        default:       
    274286                if (console == active_console)
    275                         prtchr(key, scr->position_y, scr->position_x);
     287                        cell_mark_changed(scr->position_y, scr->position_x);
    276288
    277289                screenbuffer_putchar(scr, key);
     
    280292
    281293        if (scr->position_x >= scr->size_x) {
    282                 fb_buf_flush();
    283294                flush_cursor = true;
    284295                scr->position_y++;
     
    286297       
    287298        if (scr->position_y >= scr->size_y) {
     299                fb_pending_flush();
    288300                scr->position_y = scr->size_y - 1;
    289301                screenbuffer_clear_line(scr, scr->top_line);
     
    310322                return;
    311323
    312         fb_buf_flush();
     324        fb_pending_flush();
    313325
    314326        if (newcons == KERNEL_CONSOLE) {
     
    338350                curs_visibility(false);
    339351                if (interbuffer) {
    340                         for (i = 0; i < conn->screenbuffer.size_x; i++)
    341                                 for (j = 0; j < conn->screenbuffer.size_y; j++) {
     352                        for (j = 0; j < conn->screenbuffer.size_y; j++) {
     353                                for (i = 0; i < conn->screenbuffer.size_x; i++) {
    342354                                        unsigned int size_x;
    343355                                       
    344356                                        size_x = conn->screenbuffer.size_x;
    345                                         interbuffer[i + j * size_x] =
     357                                        interbuffer[j * size_x + i] =
    346358                                            *get_field_at(&conn->screenbuffer, i, j);
    347359                                }
     360                        }
    348361                        /* This call can preempt, but we are already at the end */
    349                         rc = async_req_0_0(fb_info.phone, FB_DRAW_TEXT_DATA);
     362                        rc = async_req_4_0(fb_info.phone, FB_DRAW_TEXT_DATA,
     363                            0, 0, conn->screenbuffer.size_x,
     364                            conn->screenbuffer.size_y);
    350365                }
    351366               
     
    366381                                                continue;
    367382
    368                                         prtchr(field->character, j, i);
     383                                        fb_putchar(field->character, j, i);
    369384                                }
    370385                }
     
    479494        ipcarg_t arg1, arg2, arg3, arg4;
    480495        connection_t *conn;
     496        screenbuffer_t *scr;
    481497       
    482498        if ((consnum = find_free_connection()) == -1) {
     
    535551                        break;
    536552                case CONSOLE_GOTO:
    537                         fb_buf_flush();
    538553                        screenbuffer_goto(&conn->screenbuffer,
    539554                            IPC_GET_ARG2(call), IPC_GET_ARG1(call));
     
    547562                        break;
    548563                case CONSOLE_FLUSH:
    549                         fb_buf_flush();
    550                         if (consnum == active_console)
     564                        fb_pending_flush();
     565                        if (consnum == active_console) {
    551566                                async_req_0_0(fb_info.phone, FB_FLUSH);
     567
     568                                scr = &(connections[consnum].screenbuffer);
     569                                curs_goto(scr->position_y, scr->position_x);
     570                        }
    552571                        break;
    553572                case CONSOLE_SET_STYLE:
    554                         fb_buf_flush();
     573                        fb_pending_flush();
    555574                        arg1 = IPC_GET_ARG1(call);
    556575                        screenbuffer_set_style(&conn->screenbuffer, arg1);
     
    559578                        break;
    560579                case CONSOLE_SET_COLOR:
    561                         fb_buf_flush();
     580                        fb_pending_flush();
    562581                        arg1 = IPC_GET_ARG1(call);
    563582                        arg2 = IPC_GET_ARG2(call);
     
    569588                        break;
    570589                case CONSOLE_SET_RGB_COLOR:
    571                         fb_buf_flush();
     590                        fb_pending_flush();
    572591                        arg1 = IPC_GET_ARG1(call);
    573592                        arg2 = IPC_GET_ARG2(call);
     
    578597                        break;
    579598                case CONSOLE_CURSOR_VISIBILITY:
    580                         fb_buf_flush();
     599                        fb_pending_flush();
    581600                        arg1 = IPC_GET_ARG1(call);
    582601                        conn->screenbuffer.is_cursor_visible = arg1;
     
    684703        interbuffer = as_get_mappable_page(ib_size);
    685704
     705        fb_pending.n = 0;
     706
    686707        if (as_area_create(interbuffer, ib_size, AS_AREA_READ |
    687708            AS_AREA_WRITE | AS_AREA_CACHEABLE) != interbuffer) {
  • uspace/srv/fb/ega.c

    r0a5116db rdc033a1  
    7979static unsigned int scr_width;
    8080static unsigned int scr_height;
    81 static char *scr_addr;
     81static uint8_t *scr_addr;
    8282
    8383static unsigned int style;
     
    152152}
    153153
    154 static void draw_text_data(keyfield_t *data)
    155 {
    156         int i;
    157 
    158         for (i = 0; i < scr_width * scr_height; i++) {
    159                 scr_addr[i * 2] = data[i].character;
    160                 scr_addr[i * 2 + 1] = attr_to_ega_style(&data[i].attrs);
     154/** Draw text data to viewport.
     155 *
     156 * @param vport Viewport id
     157 * @param data  Text data.
     158 * @param x     Leftmost column of the area.
     159 * @param y     Topmost row of the area.
     160 * @param w     Number of rows.
     161 * @param h     Number of columns.
     162 */
     163static void draw_text_data(keyfield_t *data, unsigned int x,
     164    unsigned int y, unsigned int w, unsigned int h)
     165{
     166        unsigned int i, j;
     167        keyfield_t *field;
     168        uint8_t *dp;
     169
     170        for (j = 0; j < h; j++) {
     171                for (i = 0; i < w; i++) {
     172                        field = &data[j * w + i];
     173                        dp = &scr_addr[2 * ((y + j) * scr_width + (x + i))];
     174
     175                        dp[0] = field->character;
     176                        dp[1] = attr_to_ega_style(&field->attrs);
     177                }
    161178        }
    162179}
     
    232249}
    233250
    234 #define FB_WRITE_BUF_SIZE 256
    235 static char fb_write_buf[FB_WRITE_BUF_SIZE];
    236 
    237 static void fb_write(ipc_callid_t rid, ipc_call_t *request)
    238 {
    239         int row, col;
    240         ipc_callid_t callid;
    241         size_t len;
    242         size_t i;
    243 
    244         row = IPC_GET_ARG1(*request);
    245         col = IPC_GET_ARG2(*request);
    246 
    247         if ((col >= scr_width) || (row >= scr_height)) {
    248                 ipc_answer_0(callid, EINVAL);
    249                 ipc_answer_0(rid, EINVAL);
    250                 return;
    251         }
    252 
    253         if (!ipc_data_write_receive(&callid, &len)) {
    254                 ipc_answer_0(callid, EINVAL);
    255                 ipc_answer_0(rid, EINVAL);
    256                 return;
    257         }
    258 
    259         if (len > FB_WRITE_BUF_SIZE)
    260                 len = FB_WRITE_BUF_SIZE;
    261         if (len >= scr_width - col)
    262                 len = scr_width - col;
    263 
    264         (void) ipc_data_write_finalize(callid, fb_write_buf, len);
    265 
    266         for (i = 0; i < len; i++) {
    267                 printchar(fb_write_buf[i], row, col++);
    268         }
    269 
    270         ipc_answer_1(rid, EOK, len);
    271 }
    272 
    273251static void ega_client_connection(ipc_callid_t iid, ipc_call_t *icall)
    274252{
     
    277255        ipc_call_t call;
    278256        char c;
    279         unsigned int row, col;
     257        unsigned int row, col, w, h;
    280258        int bg_color, fg_color, attr;
    281259        uint32_t bg_rgb, fg_rgb;
     
    310288                        break;
    311289                case FB_DRAW_TEXT_DATA:
     290                        col = IPC_GET_ARG1(call);
     291                        row = IPC_GET_ARG2(call);
     292                        w = IPC_GET_ARG3(call);
     293                        h = IPC_GET_ARG4(call);
    312294                        if (!interbuf) {
    313295                                retval = EINVAL;
    314296                                break;
    315297                        }
    316                         draw_text_data(interbuf);
     298                        if (col + w > scr_width || row + h > scr_height) {
     299                                retval = EINVAL;
     300                                break;
     301                        }
     302                        draw_text_data(interbuf, col, row, w, h);
    317303                        retval = 0;
    318304                        break;
     
    335321                        retval = 0;
    336322                        break;
    337                 case FB_WRITE:
    338                         fb_write(callid, &call);
    339 
    340                         /* Message already answered */
    341                         continue;
    342323                case FB_CURSOR_GOTO:
    343324                        row = IPC_GET_ARG1(call);
  • uspace/srv/fb/fb.c

    r0a5116db rdc033a1  
    867867}
    868868
    869 
    870 /** Draw text data to viewport
     869/** Draw text data to viewport.
    871870 *
    872871 * @param vport Viewport id
    873  * @param data  Text data fitting exactly into viewport
    874  *
    875  */
    876 static void draw_text_data(viewport_t *vport, keyfield_t *data)
    877 {
    878         unsigned int i;
     872 * @param data  Text data.
     873 * @param x     Leftmost column of the area.
     874 * @param y     Topmost row of the area.
     875 * @param w     Number of rows.
     876 * @param h     Number of columns.
     877 */
     878static void draw_text_data(viewport_t *vport, keyfield_t *data, unsigned int x,
     879    unsigned int y, unsigned int w, unsigned int h)
     880{
     881        unsigned int i, j;
    879882        bb_cell_t *bbp;
    880883        attrs_t *a;
    881884        attr_rgb_t rgb;
    882        
    883         for (i = 0; i < vport->cols * vport->rows; i++) {
    884                 unsigned int col = i % vport->cols;
    885                 unsigned int row = i / vport->cols;
    886                
    887                 bbp = &vport->backbuf[BB_POS(vport, col, row)];
    888                 uint8_t glyph = bbp->glyph;
    889 
    890                 a = &data[i].attrs;
    891                 rgb_from_attr(&rgb, a);
    892 
    893                 bbp->glyph = data[i].character;
    894                 bbp->fg_color = rgb.fg_color;
    895                 bbp->bg_color = rgb.bg_color;
    896 
    897                 draw_vp_glyph(vport, false, col, row);
     885
     886        for (j = 0; j < h; j++) {
     887                for (i = 0; i < w; i++) {
     888                        unsigned int col = x + i;
     889                        unsigned int row = y + j;
     890
     891                        bbp = &vport->backbuf[BB_POS(vport, col, row)];
     892                        uint8_t glyph = bbp->glyph;
     893
     894                        a = &data[j * w + i].attrs;
     895                        rgb_from_attr(&rgb, a);
     896
     897                        bbp->glyph = data[j * w + i].character;
     898                        bbp->fg_color = rgb.fg_color;
     899                        bbp->bg_color = rgb.bg_color;
     900
     901                        draw_vp_glyph(vport, false, col, row);
     902                }
    898903        }
    899904        cursor_show(vport);
     
    9991004        unsigned int x;
    10001005        unsigned int y;
     1006        unsigned int w;
     1007        unsigned int h;
    10011008       
    10021009        switch (IPC_GET_METHOD(*call)) {
     
    10591066                break;
    10601067        case FB_DRAW_TEXT_DATA:
     1068                x = IPC_GET_ARG1(*call);
     1069                y = IPC_GET_ARG2(*call);
     1070                w = IPC_GET_ARG3(*call);
     1071                h = IPC_GET_ARG4(*call);
    10611072                if (!interbuffer) {
    10621073                        retval = EINVAL;
    10631074                        break;
    10641075                }
    1065                 if (intersize < vport->cols * vport->rows * sizeof(*interbuffer)) {
     1076                if (x + w > vport->cols || y + h > vport->rows) {
    10661077                        retval = EINVAL;
    10671078                        break;
    10681079                }
    1069                 draw_text_data(vport, interbuffer);
     1080                if (intersize < w * h * sizeof(*interbuffer)) {
     1081                        retval = EINVAL;
     1082                        break;
     1083                }
     1084                draw_text_data(vport, interbuffer, x, y, w, h);
    10701085                break;
    10711086        default:
     
    14721487        return rgb_from_idx(&vport->attr, fg_color, bg_color, flags);
    14731488}
    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 
    15141489
    15151490/** Function for handling connections to FB
     
    15871562                        /* Message already answered */
    15881563                        continue;
    1589                 case FB_WRITE:
    1590                         fb_write(vport, callid, &call);
    1591                        
    1592                         /* Message already answered */
    1593                         continue;
    15941564                case FB_CLEAR:
    15951565                        vport_clear(vport);
  • uspace/srv/fb/msim.c

    r0a5116db rdc033a1  
    4646
    4747#define WIDTH 80
    48 #define HEIGHT 25
     48#define HEIGHT 24
    4949
    5050static char *virt_addr;
  • uspace/srv/fb/serial_console.c

    r0a5116db rdc033a1  
    224224}
    225225
    226 static void draw_text_data(keyfield_t *data)
    227 {
    228         int i, j;
     226/** Draw text data to viewport.
     227 *
     228 * @param vport Viewport id
     229 * @param data  Text data.
     230 * @param x     Leftmost column of the area.
     231 * @param y     Topmost row of the area.
     232 * @param w     Number of rows.
     233 * @param h     Number of columns.
     234 */
     235static void draw_text_data(keyfield_t *data, unsigned int x,
     236    unsigned int y, unsigned int w, unsigned int h)
     237{
     238        unsigned int i, j;
     239        keyfield_t *field;
    229240        attrs_t *a0, *a1;
    230241
    231         serial_goto(0, 0);
     242        serial_goto(y, x);
    232243        a0 = &data[0].attrs;
    233244        serial_set_attrs(a0);
    234245
    235         for (i = 0; i < scr_height; i++) {
    236                 for (j = 0; j < scr_width; j++) {
    237                         a1 = &data[i * scr_width + j].attrs;
     246        for (j = 0; j < h; j++) {
     247                if (j > 0 && w != scr_width)
     248                        serial_goto(y, x);
     249
     250                for (i = 0; i < w; i++) {
     251                        unsigned int col = x + i;
     252                        unsigned int row = y + j;
     253
     254                        field = &data[j * w + i];
     255
     256                        a1 = &field->attrs;
    238257                        if (!attrs_same(*a0, *a1))
    239258                                serial_set_attrs(a1);
    240                         (*putc_function)(data[i * scr_width + j].character);
     259                        (*putc_function)(field->character);
    241260                        a0 = a1;
    242261                }
     
    246265int lastcol = 0;
    247266int 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 }
    293267
    294268/**
     
    304278
    305279        char c;
    306         int newcol;
    307         int newrow;
     280        int col, row, w, h;
    308281        int fgcolor;
    309282        int bgcolor;
     
    346319                        break;
    347320                case FB_DRAW_TEXT_DATA:
     321                        col = IPC_GET_ARG1(call);
     322                        row = IPC_GET_ARG2(call);
     323                        w = IPC_GET_ARG3(call);
     324                        h = IPC_GET_ARG4(call);
    348325                        if (!interbuf) {
    349326                                retval = EINVAL;
    350327                                break;
    351328                        }
    352                         draw_text_data(interbuf);
     329                        if (col + w > scr_width || row + h > scr_height) {
     330                                retval = EINVAL;
     331                                break;
     332                        }
     333                        draw_text_data(interbuf, col, row, w, h);
     334                        lastrow = row + h - 1;
     335                        lastcol = col + w;
    353336                        retval = 0;
    354337                        break;
    355338                case FB_PUTCHAR:
    356339                        c = IPC_GET_ARG1(call);
    357                         newrow = IPC_GET_ARG2(call);
    358                         newcol = IPC_GET_ARG3(call);
    359                         if ((lastcol != newcol) || (lastrow != newrow))
    360                                 serial_goto(newrow, newcol);
    361                         lastcol = newcol + 1;
    362                         lastrow = newrow;
     340                        row = IPC_GET_ARG2(call);
     341                        col = IPC_GET_ARG3(call);
     342                        if ((lastcol != col) || (lastrow != row))
     343                                serial_goto(row, col);
     344                        lastcol = col + 1;
     345                        lastrow = row;
    363346                        (*putc_function)(c);
    364347                        retval = 0;
    365348                        break;
    366                 case FB_WRITE:
    367                         fb_write(callid, &call);
    368                        
    369                         /* Message already answered */
    370                         continue;
    371349                case FB_CURSOR_GOTO:
    372                         newrow = IPC_GET_ARG1(call);
    373                         newcol = IPC_GET_ARG2(call);
    374                         serial_goto(newrow, newcol);
    375                         lastrow = newrow;
    376                         lastcol = newcol;
     350                        row = IPC_GET_ARG1(call);
     351                        col = IPC_GET_ARG2(call);
     352                        serial_goto(row, col);
     353                        lastrow = row;
     354                        lastcol = col;
    377355                        retval = 0;
    378356                        break;
  • uspace/srv/fb/ski.c

    r0a5116db rdc033a1  
    4848
    4949#define WIDTH 80
    50 #define HEIGHT 25
     50#define HEIGHT 24
    5151
    5252/** Display character on ski debug console
Note: See TracChangeset for help on using the changeset viewer.