Ignore:
File:
1 edited

Legend:

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

    reb2187c4 re037cf37  
    4545#include <align.h>
    4646#include <panic.h>
    47 #include <memw.h>
     47#include <mem.h>
    4848#include <config.h>
    4949#include <bitops.h>
     
    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
     
    273265{
    274266        if ((!instance->parea.mapped) || (console_override)) {
    275                 for (unsigned int rel_row = 0; rel_row < instance->screen_rows; rel_row++) {
     267                for (unsigned int rel_row = 0; rel_row < instance->rowtrim; rel_row++) {
    276268                        unsigned int y = ROW2Y(rel_row);
    277269                        unsigned int row = rel_row + instance->offset_row;
     
    322314static void cursor_put(fb_instance_t *instance)
    323315{
    324         unsigned int col = instance->column;
    325         unsigned int row = instance->row;
     316        unsigned int col = instance->position % instance->cols;
     317        unsigned int row = instance->position / instance->cols;
    326318
    327319        glyph_draw(instance, fb_font_glyph(U_CURSOR), col, row, true);
     
    330322static void cursor_remove(fb_instance_t *instance)
    331323{
    332         unsigned int col = instance->column;
    333         unsigned int row = instance->row;
     324        unsigned int col = instance->position % instance->cols;
     325        unsigned int row = instance->position / instance->cols;
    334326
    335327        glyph_draw(instance, instance->backbuf[BB_POS(instance, col, row)],
     
    381373static void fb_redraw_internal(fb_instance_t *instance)
    382374{
    383         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++) {
    384376                unsigned int y = ROW2Y(rel_row);
    385377                unsigned int row = rel_row + instance->offset_row;
     
    412404        }
    413405
    414         if (ROW2Y(instance->screen_rows) < instance->yres) {
     406        if (ROW2Y(instance->rowtrim) < instance->yres) {
    415407                unsigned int y;
    416408
    417                 for (y = ROW2Y(instance->screen_rows); y < instance->yres; y++)
     409                for (y = ROW2Y(instance->rowtrim); y < instance->yres; y++)
    418410                        memcpy(&instance->addr[FB_POS(instance, 0, y)],
    419411                            instance->bgscan, instance->bgscanbytes);
     
    421413}
    422414
    423 static void _advance_row(fb_instance_t *instance)
    424 {
    425         instance->column = 0;
    426         instance->row++;
    427 }
    428 
    429 static void _advance_column(fb_instance_t *instance)
    430 {
    431         instance->column++;
    432         if (instance->column == instance->cols)
    433                 _advance_row(instance);
    434 }
    435 
    436415/** Print character to screen
    437416 *
     
    439418 *
    440419 */
    441 static void _putuchar(fb_instance_t *instance, char32_t ch)
    442 {
     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
    443425        switch (ch) {
    444426        case '\n':
    445                 _advance_row(instance);
     427                cursor_remove(instance);
     428                instance->position += instance->cols;
     429                instance->position -= instance->position % instance->cols;
    446430                break;
    447431        case '\r':
    448                 instance->column = 0;
     432                cursor_remove(instance);
     433                instance->position -= instance->position % instance->cols;
    449434                break;
    450435        case '\b':
    451                 if (instance->column > 0)
    452                         instance->column--;
     436                cursor_remove(instance);
     437                if (instance->position % instance->cols)
     438                        instance->position--;
    453439                break;
    454440        case '\t':
     441                cursor_remove(instance);
    455442                do {
    456443                        glyph_draw(instance, fb_font_glyph(' '),
    457                             instance->column,
    458                             instance->row, false);
    459                         _advance_column(instance);
    460                 } 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));
    461449                break;
    462450        default:
    463451                glyph_draw(instance, fb_font_glyph(ch),
    464                     instance->column,
    465                     instance->row, false);
    466                 _advance_column(instance);
    467         }
    468 
    469         while (instance->row >= instance->rows) {
    470                 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;
    471459                screen_scroll(instance);
    472460        }
    473 }
    474 
    475 static void fb_write(outdev_t *dev, const char *s, size_t n)
    476 {
    477         fb_instance_t *instance = (fb_instance_t *) dev->data;
    478 
    479         spinlock_lock(&instance->lock);
    480         cursor_remove(instance);
    481 
    482         size_t offset = 0;
    483         char32_t ch;
    484 
    485         while ((ch = str_decode_r(s, &offset, n, U_SPECIAL, &instance->mbstate)))
    486                 _putuchar(instance, ch);
    487461
    488462        cursor_put(instance);
     463
    489464        spinlock_unlock(&instance->lock);
    490465}
     
    498473        spinlock_lock(&instance->lock);
    499474
    500         if (instance->offset_row >= instance->screen_rows / 2)
    501                 instance->offset_row -= instance->screen_rows / 2;
     475        if (instance->offset_row >= instance->rowtrim / 2)
     476                instance->offset_row -= instance->rowtrim / 2;
    502477        else
    503478                instance->offset_row = 0;
     
    517492        spinlock_lock(&instance->lock);
    518493
    519         if (instance->offset_row + instance->screen_rows / 2 <=
    520             instance->rows - instance->screen_rows)
    521                 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;
    522497        else
    523                 instance->offset_row = instance->rows - instance->screen_rows;
     498                instance->offset_row = instance->rows - instance->rowtrim;
    524499
    525500        fb_redraw_internal(instance);
     
    640615        instance->scanline = props->scan;
    641616
    642         instance->screen_rows = Y2ROW(instance->yres);
     617        instance->rowtrim = Y2ROW(instance->yres);
    643618
    644619        instance->cols = X2COL(instance->xres);
    645         instance->rows = FB_PAGES * instance->screen_rows;
    646 
    647         instance->start_row = instance->rows - instance->screen_rows;
     620        instance->rows = FB_PAGES * instance->rowtrim;
     621
     622        instance->start_row = instance->rows - instance->rowtrim;
    648623        instance->offset_row = instance->start_row;
    649         instance->row = instance->start_row;
    650         instance->column = 0;
     624        instance->position = instance->start_row * instance->cols;
    651625
    652626        instance->glyphscanline = FONT_WIDTH * instance->pixelbytes;
     
    659633
    660634        instance->addr = (uint8_t *) km_map((uintptr_t) props->addr, fbsize,
    661             KM_NATURAL_ALIGNMENT, PAGE_WRITE | PAGE_WRITE_COMBINE);
     635            KM_NATURAL_ALIGNMENT, PAGE_WRITE | PAGE_NOT_CACHEABLE);
    662636        if (!instance->addr) {
    663637                LOG("Unable to map framebuffer.");
Note: See TracChangeset for help on using the changeset viewer.