Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/genarch/src/fb/fb.c

    r888c06e rde96d3b  
    8181        ((glyph) * (instance)->glyphbytes + (y) * (instance)->glyphscanline)
    8282
    83 #define TAB_WIDTH 8
    84 
    8583typedef void (*rgb_conv_t)(void *, uint32_t);
    8684
     
    10199
    102100        /** Number of rows that fit on framebuffer */
    103         unsigned int screen_rows;
     101        unsigned int rowtrim;
    104102
    105103        unsigned int scanline;
     
    123121        /** Current backbuffer position */
    124122        unsigned int position;
    125 
    126         /** Partial character between writes */
    127         mbstate_t mbstate;
    128 
    129         unsigned int row;
    130         unsigned int column;
    131123} fb_instance_t;
    132124
    133 static void fb_write(outdev_t *, const char *, size_t);
     125static void fb_putuchar(outdev_t *, char32_t);
    134126static void fb_redraw(outdev_t *);
    135127static void fb_scroll_up(outdev_t *);
     
    137129
    138130static outdev_operations_t fbdev_ops = {
    139         .write = fb_write,
     131        .write = fb_putuchar,
    140132        .redraw = fb_redraw,
    141133        .scroll_up = fb_scroll_up,
     
    255247
    256248        unsigned int rel_row = row - instance->offset_row;
    257         if (rel_row >= instance->screen_rows)
     249        if (rel_row >= instance->rowtrim)
    258250                return;
    259251
     
    267259}
    268260
     261/** Scroll screen down by one row
     262 *
     263 */
     264static void screen_scroll(fb_instance_t *instance)
     265{
     266        if ((!instance->parea.mapped) || (console_override)) {
     267                for (unsigned int rel_row = 0; rel_row < instance->rowtrim; rel_row++) {
     268                        unsigned int y = ROW2Y(rel_row);
     269                        unsigned int row = rel_row + instance->offset_row;
     270
     271                        for (unsigned int yd = 0; yd < FONT_SCANLINES; yd++) {
     272                                unsigned int x;
     273                                unsigned int col;
     274                                size_t bb_pos = BB_POS(instance, 0, row);
     275                                size_t bb_pos1 = BB_POS(instance, 0, row + 1);
     276
     277                                for (col = 0, x = 0; col < instance->cols;
     278                                    col++, x += FONT_WIDTH) {
     279                                        uint16_t glyph;
     280
     281                                        if (row < instance->rows - 1) {
     282                                                if (instance->backbuf[bb_pos] ==
     283                                                    instance->backbuf[bb_pos1])
     284                                                        goto skip;
     285
     286                                                glyph = instance->backbuf[bb_pos1];
     287                                        } else
     288                                                glyph = 0;
     289
     290                                        memcpy(&instance->addr[FB_POS(instance, x, y + yd)],
     291                                            &instance->glyphs[GLYPH_POS(instance, glyph, yd)],
     292                                            instance->glyphscanline);
     293                                skip:
     294                                        BB_NEXT_COL(bb_pos);
     295                                        BB_NEXT_COL(bb_pos1);
     296                                }
     297                        }
     298                }
     299        }
     300
     301        /*
     302         * Implement backbuffer scrolling by wrapping around
     303         * the cyclic buffer.
     304         */
     305
     306        instance->start_row++;
     307        if (instance->start_row == instance->rows)
     308                instance->start_row = 0;
     309
     310        memsetw(&instance->backbuf[BB_POS(instance, 0, instance->rows - 1)],
     311            instance->cols, 0);
     312}
     313
    269314static void cursor_put(fb_instance_t *instance)
    270315{
    271         unsigned int col = instance->column;
    272         unsigned int row = instance->row;
     316        unsigned int col = instance->position % instance->cols;
     317        unsigned int row = instance->position / instance->cols;
    273318
    274319        glyph_draw(instance, fb_font_glyph(U_CURSOR), col, row, true);
     
    277322static void cursor_remove(fb_instance_t *instance)
    278323{
    279         unsigned int col = instance->column;
    280         unsigned int row = instance->row;
     324        unsigned int col = instance->position % instance->cols;
     325        unsigned int row = instance->position / instance->cols;
    281326
    282327        glyph_draw(instance, instance->backbuf[BB_POS(instance, col, row)],
     
    328373static void fb_redraw_internal(fb_instance_t *instance)
    329374{
    330         for (unsigned int rel_row = 0; rel_row < instance->screen_rows; rel_row++) {
     375        for (unsigned int rel_row = 0; rel_row < instance->rowtrim; rel_row++) {
    331376                unsigned int y = ROW2Y(rel_row);
    332377                unsigned int row = rel_row + instance->offset_row;
     
    359404        }
    360405
    361         if (ROW2Y(instance->screen_rows) < instance->yres) {
     406        if (ROW2Y(instance->rowtrim) < instance->yres) {
    362407                unsigned int y;
    363408
    364                 for (y = ROW2Y(instance->screen_rows); y < instance->yres; y++)
     409                for (y = ROW2Y(instance->rowtrim); y < instance->yres; y++)
    365410                        memcpy(&instance->addr[FB_POS(instance, 0, y)],
    366411                            instance->bgscan, instance->bgscanbytes);
     
    368413}
    369414
    370 /** Scroll screen down by one row
    371  *
    372  */
    373 static void screen_scroll(fb_instance_t *instance)
    374 {
    375         /*
    376          * Implement backbuffer scrolling by wrapping around
    377          * the cyclic buffer.
    378          */
    379 
    380         instance->start_row++;
    381         if (instance->start_row == instance->rows)
    382                 instance->start_row = 0;
    383 
    384         if ((!instance->parea.mapped) || (console_override)) {
    385                 fb_redraw_internal(instance);
    386         }
    387 }
    388 
    389 static void _advance_row(fb_instance_t *instance)
    390 {
    391         instance->column = 0;
    392         instance->row++;
    393 }
    394 
    395 static void _advance_column(fb_instance_t *instance)
    396 {
    397         instance->column++;
    398         if (instance->column == instance->cols)
    399                 _advance_row(instance);
    400 }
    401 
    402415/** Print character to screen
    403416 *
     
    405418 *
    406419 */
    407 static void _putuchar(fb_instance_t *instance, char32_t ch)
    408 {
     420static void fb_putuchar(outdev_t *dev, char32_t ch)
     421{
     422        fb_instance_t *instance = (fb_instance_t *) dev->data;
     423        spinlock_lock(&instance->lock);
     424
    409425        switch (ch) {
    410426        case '\n':
    411                 _advance_row(instance);
     427                cursor_remove(instance);
     428                instance->position += instance->cols;
     429                instance->position -= instance->position % instance->cols;
    412430                break;
    413431        case '\r':
    414                 instance->column = 0;
     432                cursor_remove(instance);
     433                instance->position -= instance->position % instance->cols;
    415434                break;
    416435        case '\b':
    417                 if (instance->column > 0)
    418                         instance->column--;
     436                cursor_remove(instance);
     437                if (instance->position % instance->cols)
     438                        instance->position--;
    419439                break;
    420440        case '\t':
     441                cursor_remove(instance);
    421442                do {
    422443                        glyph_draw(instance, fb_font_glyph(' '),
    423                             instance->column,
    424                             instance->row, false);
    425                         _advance_column(instance);
    426                 } while (instance->column % TAB_WIDTH != 0);
     444                            instance->position % instance->cols,
     445                            instance->position / instance->cols, false);
     446                        instance->position++;
     447                } while (((instance->position % instance->cols) % 8 != 0) &&
     448                    (instance->position < instance->cols * instance->rows));
    427449                break;
    428450        default:
    429451                glyph_draw(instance, fb_font_glyph(ch),
    430                     instance->column,
    431                     instance->row, false);
    432                 _advance_column(instance);
    433         }
    434 
    435         while (instance->row >= instance->rows) {
    436                 instance->row--;
     452                    instance->position % instance->cols,
     453                    instance->position / instance->cols, false);
     454                instance->position++;
     455        }
     456
     457        if (instance->position >= instance->cols * instance->rows) {
     458                instance->position -= instance->cols;
    437459                screen_scroll(instance);
    438460        }
    439 }
    440 
    441 static void fb_write(outdev_t *dev, const char *s, size_t n)
    442 {
    443         fb_instance_t *instance = (fb_instance_t *) dev->data;
    444 
    445         spinlock_lock(&instance->lock);
    446         cursor_remove(instance);
    447 
    448         size_t offset = 0;
    449         char32_t ch;
    450 
    451         while ((ch = str_decode_r(s, &offset, n, U_SPECIAL, &instance->mbstate)))
    452                 _putuchar(instance, ch);
    453461
    454462        cursor_put(instance);
     463
    455464        spinlock_unlock(&instance->lock);
    456465}
     
    464473        spinlock_lock(&instance->lock);
    465474
    466         if (instance->offset_row >= instance->screen_rows / 2)
    467                 instance->offset_row -= instance->screen_rows / 2;
     475        if (instance->offset_row >= instance->rowtrim / 2)
     476                instance->offset_row -= instance->rowtrim / 2;
    468477        else
    469478                instance->offset_row = 0;
     
    483492        spinlock_lock(&instance->lock);
    484493
    485         if (instance->offset_row + instance->screen_rows / 2 <=
    486             instance->rows - instance->screen_rows)
    487                 instance->offset_row += instance->screen_rows / 2;
     494        if (instance->offset_row + instance->rowtrim / 2 <=
     495            instance->rows - instance->rowtrim)
     496                instance->offset_row += instance->rowtrim / 2;
    488497        else
    489                 instance->offset_row = instance->rows - instance->screen_rows;
     498                instance->offset_row = instance->rows - instance->rowtrim;
    490499
    491500        fb_redraw_internal(instance);
     
    606615        instance->scanline = props->scan;
    607616
    608         instance->screen_rows = Y2ROW(instance->yres);
     617        instance->rowtrim = Y2ROW(instance->yres);
    609618
    610619        instance->cols = X2COL(instance->xres);
    611         instance->rows = FB_PAGES * instance->screen_rows;
    612 
    613         instance->start_row = instance->rows - instance->screen_rows;
     620        instance->rows = FB_PAGES * instance->rowtrim;
     621
     622        instance->start_row = instance->rows - instance->rowtrim;
    614623        instance->offset_row = instance->start_row;
    615         instance->row = instance->start_row;
    616         instance->column = 0;
     624        instance->position = instance->start_row * instance->cols;
    617625
    618626        instance->glyphscanline = FONT_WIDTH * instance->pixelbytes;
Note: See TracChangeset for help on using the changeset viewer.