Changeset a71c158 in mainline for kernel/genarch/src/fb/fb.c


Ignore:
Timestamp:
2009-08-21T14:12:45Z (15 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0e6dce8, b50b5af2, e5792d1
Parents:
90c8b8d
Message:

kernel output devices now suport multiple instances (except ski and sgcn, which respect the same interface, but behave as singletons)
if more than one output device gets initialized, the output is cloned to all of them
get rid of arch_grab_console() and arch_release_console() (output devices can implement a generic "redraw" method, input devices respect the "silent" global variable)
related cleanups and modifications

File:
1 edited

Legend:

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

    r90c8b8d ra71c158  
    5353#include <byteorder.h>
    5454
    55 SPINLOCK_INITIALIZE(fb_lock);
    56 
    57 static uint8_t *fb_addr;
    58 static uint16_t *backbuf;
    59 static uint8_t *glyphs;
    60 static uint8_t *bgscan;
    61 
    62 static unsigned int xres;
    63 static unsigned int yres;
    64 
    65 static unsigned int ylogo;
    66 static unsigned int ytrim;
    67 static unsigned int rowtrim;
    68 
    69 static unsigned int scanline;
    70 static unsigned int glyphscanline;
    71 
    72 static unsigned int pixelbytes;
    73 static unsigned int glyphbytes;
    74 static unsigned int bgscanbytes;
    75 
    76 static unsigned int cols;
    77 static unsigned int rows;
    78 static unsigned int position = 0;
    79 
    8055#define BG_COLOR     0x000080
    8156#define FG_COLOR     0xffff00
    8257#define INV_COLOR    0xaaaaaa
    8358
    84 #define RED(x, bits)         (((x) >> (8 + 8 + 8 - (bits))) & ((1 << (bits)) - 1))
    85 #define GREEN(x, bits)       (((x) >> (8 + 8 - (bits))) & ((1 << (bits)) - 1))
    86 #define BLUE(x, bits)        (((x) >> (8 - (bits))) & ((1 << (bits)) - 1))
    87 
    88 #define COL2X(col)           ((col) * FONT_WIDTH)
    89 #define ROW2Y(row)           ((row) * FONT_SCANLINES)
    90 
    91 #define X2COL(x)             ((x) / FONT_WIDTH)
    92 #define Y2ROW(y)             ((y) / FONT_SCANLINES)
    93 
    94 #define FB_POS(x, y)         ((y) * scanline + (x) * pixelbytes)
    95 #define BB_POS(col, row)     ((row) * cols + (col))
    96 #define GLYPH_POS(glyph, y)  ((glyph) * glyphbytes + (y) * glyphscanline)
    97 
    98 
    99 static void (*rgb_conv)(void *, uint32_t);
     59#define RED(x, bits)    (((x) >> (8 + 8 + 8 - (bits))) & ((1 << (bits)) - 1))
     60#define GREEN(x, bits)  (((x) >> (8 + 8 - (bits))) & ((1 << (bits)) - 1))
     61#define BLUE(x, bits)   (((x) >> (8 - (bits))) & ((1 << (bits)) - 1))
     62
     63#define COL2X(col)  ((col) * FONT_WIDTH)
     64#define ROW2Y(row)  ((row) * FONT_SCANLINES)
     65
     66#define X2COL(x)  ((x) / FONT_WIDTH)
     67#define Y2ROW(y)  ((y) / FONT_SCANLINES)
     68
     69#define FB_POS(instance, x, y) \
     70        ((y) * (instance)->scanline + (x) * (instance)->pixelbytes)
     71
     72#define BB_POS(instance, col, row) \
     73        ((row) * (instance)->cols + (col))
     74
     75#define GLYPH_POS(instance, glyph, y) \
     76        ((glyph) * (instance)->glyphbytes + (y) * (instance)->glyphscanline)
     77
     78typedef void (* rgb_conv_t)(void *, uint32_t);
     79
     80typedef struct {
     81        SPINLOCK_DECLARE(lock);
     82       
     83        uint8_t *addr;
     84        uint16_t *backbuf;
     85        uint8_t *glyphs;
     86        uint8_t *bgscan;
     87       
     88        rgb_conv_t rgb_conv;
     89       
     90        unsigned int xres;
     91        unsigned int yres;
     92       
     93        unsigned int ylogo;
     94        unsigned int ytrim;
     95        unsigned int rowtrim;
     96       
     97        unsigned int scanline;
     98        unsigned int glyphscanline;
     99       
     100        unsigned int pixelbytes;
     101        unsigned int glyphbytes;
     102        unsigned int bgscanbytes;
     103       
     104        unsigned int cols;
     105        unsigned int rows;
     106       
     107        unsigned int position;
     108} fb_instance_t;
     109
     110static void fb_putchar(outdev_t *dev, wchar_t ch, bool silent);
     111static void fb_redraw_internal(fb_instance_t *instance);
     112static void fb_redraw(outdev_t *dev);
     113
     114static outdev_operations_t fbdev_ops = {
     115        .write = fb_putchar,
     116        .redraw = fb_redraw
     117};
    100118
    101119/*
     
    169187            GREEN(rgb, 6) << 5 | BLUE(rgb, 5));
    170188}
    171 
    172189
    173190/** BGR 3:2:3
     
    179196 * and setting it to simulate the 8-bit truecolor.
    180197 *
    181  * Currently we set the palette on the ia32, amd64 and sparc64 port.
     198 * Currently we set the palette on the ia32, amd64, ppc32 and sparc64 port.
    182199 *
    183200 * Note that the byte is being inverted by this function. The reason is
     
    194211}
    195212
    196 
    197213/** Hide logo and refresh screen
    198214 *
    199215 */
    200 static void logo_hide(bool silent)
    201 {
    202         ylogo = 0;
    203         ytrim = yres;
    204         rowtrim = rows;
     216static void logo_hide(fb_instance_t *instance, bool silent)
     217{
     218        instance->ylogo = 0;
     219        instance->ytrim = instance->yres;
     220        instance->rowtrim = instance->rows;
     221       
    205222        if (!silent)
    206                 fb_redraw();
    207 }
    208 
     223                fb_redraw_internal(instance);
     224}
    209225
    210226/** Draw character at given position
    211227 *
    212228 */
    213 static void glyph_draw(uint16_t glyph, unsigned int col, unsigned int row, bool silent, bool overlay)
     229static void glyph_draw(fb_instance_t *instance, uint16_t glyph,
     230    unsigned int col, unsigned int row, bool silent, bool overlay)
    214231{
    215232        unsigned int x = COL2X(col);
     
    217234        unsigned int yd;
    218235       
    219         if (y >= ytrim)
    220                 logo_hide(silent);
     236        if (y >= instance->ytrim)
     237                logo_hide(instance, silent);
    221238       
    222239        if (!overlay)
    223                 backbuf[BB_POS(col, row)] = glyph;
     240                instance->backbuf[BB_POS(instance, col, row)] = glyph;
    224241       
    225242        if (!silent) {
    226243                for (yd = 0; yd < FONT_SCANLINES; yd++)
    227                         memcpy(&fb_addr[FB_POS(x, y + yd + ylogo)],
    228                             &glyphs[GLYPH_POS(glyph, yd)], glyphscanline);
    229         }
    230 }
    231 
     244                        memcpy(&instance->addr[FB_POS(instance, x, y + yd + instance->ylogo)],
     245                            &instance->glyphs[GLYPH_POS(instance, glyph, yd)],
     246                            instance->glyphscanline);
     247        }
     248}
    232249
    233250/** Scroll screen down by one row
     
    235252 *
    236253 */
    237 static void screen_scroll(bool silent)
    238 {
    239         if (ylogo > 0) {
    240                 logo_hide(silent);
     254static void screen_scroll(fb_instance_t *instance, bool silent)
     255{
     256        if (instance->ylogo > 0) {
     257                logo_hide(instance, silent);
    241258                return;
    242259        }
     
    245262                unsigned int row;
    246263               
    247                 for (row = 0; row < rows; row++) {
     264                for (row = 0; row < instance->rows; row++) {
    248265                        unsigned int y = ROW2Y(row);
    249266                        unsigned int yd;
     
    253270                                unsigned int col;
    254271                               
    255                                 for (col = 0, x = 0; col < cols; col++,
    256                                     x += FONT_WIDTH) {
     272                                for (col = 0, x = 0; col < instance->cols;
     273                                    col++, x += FONT_WIDTH) {
    257274                                        uint16_t glyph;
    258275                                       
    259                                         if (row < rows - 1) {
    260                                                 if (backbuf[BB_POS(col, row)] ==
    261                                                     backbuf[BB_POS(col, row + 1)])
     276                                        if (row < instance->rows - 1) {
     277                                                if (instance->backbuf[BB_POS(instance, col, row)] ==
     278                                                    instance->backbuf[BB_POS(instance, col, row + 1)])
    262279                                                        continue;
    263280                                               
    264                                                 glyph = backbuf[BB_POS(col, row + 1)];
     281                                                glyph = instance->backbuf[BB_POS(instance, col, row + 1)];
    265282                                        } else
    266283                                                glyph = 0;
    267284                                       
    268                                         memcpy(&fb_addr[FB_POS(x, y + yd)],
    269                                             &glyphs[GLYPH_POS(glyph, yd)],
    270                                             glyphscanline);
     285                                        memcpy(&instance->addr[FB_POS(instance, x, y + yd)],
     286                                            &instance->glyphs[GLYPH_POS(instance, glyph, yd)],
     287                                            instance->glyphscanline);
    271288                                }
    272289                        }
     
    274291        }
    275292       
    276         memmove(backbuf, &backbuf[BB_POS(0, 1)], cols * (rows - 1) * sizeof(uint16_t));
    277         memsetw(&backbuf[BB_POS(0, rows - 1)], cols, 0);
    278 }
    279 
    280 
    281 static void cursor_put(bool silent)
    282 {
    283         unsigned int col = position % cols;
    284         unsigned int row = position / cols;
    285        
    286         glyph_draw(fb_font_glyph(U_CURSOR), col, row, silent, true);
    287 }
    288 
    289 
    290 static void cursor_remove(bool silent)
    291 {
    292         unsigned int col = position % cols;
    293         unsigned int row = position / cols;
    294        
    295         glyph_draw(backbuf[BB_POS(col, row)], col, row, silent, true);
    296 }
    297 
    298 
    299 /** Print character to screen
    300  *
    301  * Emulate basic terminal commands.
    302  *
    303  */
    304 static void fb_putchar(outdev_t *dev, wchar_t ch, bool silent)
    305 {
    306         spinlock_lock(&fb_lock);
    307        
    308         switch (ch) {
    309         case '\n':
    310                 cursor_remove(silent);
    311                 position += cols;
    312                 position -= position % cols;
    313                 break;
    314         case '\r':
    315                 cursor_remove(silent);
    316                 position -= position % cols;
    317                 break;
    318         case '\b':
    319                 cursor_remove(silent);
    320                 if (position % cols)
    321                         position--;
    322                 break;
    323         case '\t':
    324                 cursor_remove(silent);
    325                 do {
    326                         glyph_draw(fb_font_glyph(' '), position % cols,
    327                             position / cols, silent, false);
    328                         position++;
    329                 } while ((position % 8) && (position < cols * rows));
    330                 break;
    331         default:
    332                 glyph_draw(fb_font_glyph(ch), position % cols,
    333                     position / cols, silent, false);
    334                 position++;
    335         }
    336        
    337         if (position >= cols * rows) {
    338                 position -= cols;
    339                 screen_scroll(silent);
    340         }
    341        
    342         cursor_put(silent);
    343        
    344         spinlock_unlock(&fb_lock);
    345 }
    346 
    347 static outdev_t fb_console;
    348 static outdev_operations_t fb_ops = {
    349         .write = fb_putchar
    350 };
    351 
     293        memmove(instance->backbuf, &instance->backbuf[BB_POS(instance, 0, 1)],
     294            instance->cols * (instance->rows - 1) * sizeof(uint16_t));
     295        memsetw(&instance->backbuf[BB_POS(instance, 0, instance->rows - 1)],
     296            instance->cols, 0);
     297}
     298
     299static void cursor_put(fb_instance_t *instance, bool silent)
     300{
     301        unsigned int col = instance->position % instance->cols;
     302        unsigned int row = instance->position / instance->cols;
     303       
     304        glyph_draw(instance, fb_font_glyph(U_CURSOR), col, row, silent, true);
     305}
     306
     307static void cursor_remove(fb_instance_t *instance, bool silent)
     308{
     309        unsigned int col = instance->position % instance->cols;
     310        unsigned int row = instance->position / instance->cols;
     311       
     312        glyph_draw(instance, instance->backbuf[BB_POS(instance, col, row)],
     313            col, row, silent, true);
     314}
    352315
    353316/** Render glyphs
     
    357320 *
    358321 */
    359 static void glyphs_render(void)
     322static void glyphs_render(fb_instance_t *instance)
    360323{
    361324        /* Prerender glyphs */
     
    376339                       
    377340                        for (x = 0; x < FONT_WIDTH; x++) {
    378                                 void *dst = &glyphs[GLYPH_POS(glyph, y) +
    379                                     x * pixelbytes];
     341                                void *dst =
     342                                    &instance->glyphs[GLYPH_POS(instance, glyph, y) +
     343                                    x * instance->pixelbytes];
    380344                                uint32_t rgb = (fb_font[glyph][y] &
    381345                                    (1 << (7 - x))) ? fg_color : BG_COLOR;
    382                                 rgb_conv(dst, rgb);
     346                                instance->rgb_conv(dst, rgb);
    383347                        }
    384348                }
     
    388352        unsigned int x;
    389353       
    390         for (x = 0; x < xres; x++)
    391                 rgb_conv(&bgscan[x * pixelbytes], BG_COLOR);
    392 }
    393 
    394 
    395 /** Refresh the screen
    396  *
    397  */
    398 void fb_redraw(void)
    399 {
    400         if (ylogo > 0) {
     354        for (x = 0; x < instance->xres; x++)
     355                instance->rgb_conv(&instance->bgscan[x * instance->pixelbytes], BG_COLOR);
     356}
     357
     358/** Print character to screen
     359 *
     360 * Emulate basic terminal commands.
     361 *
     362 */
     363static void fb_putchar(outdev_t *dev, wchar_t ch, bool silent)
     364{
     365        fb_instance_t *instance = (fb_instance_t *) dev->data;
     366        spinlock_lock(&instance->lock);
     367       
     368        switch (ch) {
     369        case '\n':
     370                cursor_remove(instance, silent);
     371                instance->position += instance->cols;
     372                instance->position -= instance->position % instance->cols;
     373                break;
     374        case '\r':
     375                cursor_remove(instance, silent);
     376                instance->position -= instance->position % instance->cols;
     377                break;
     378        case '\b':
     379                cursor_remove(instance, silent);
     380                if (instance->position % instance->cols)
     381                        instance->position--;
     382                break;
     383        case '\t':
     384                cursor_remove(instance, silent);
     385                do {
     386                        glyph_draw(instance, fb_font_glyph(' '),
     387                            instance->position % instance->cols,
     388                            instance->position / instance->cols, silent, false);
     389                        instance->position++;
     390                } while ((instance->position % 8)
     391                    && (instance->position < instance->cols * instance->rows));
     392                break;
     393        default:
     394                glyph_draw(instance, fb_font_glyph(ch),
     395                    instance->position % instance->cols,
     396                    instance->position / instance->cols, silent, false);
     397                instance->position++;
     398        }
     399       
     400        if (instance->position >= instance->cols * instance->rows) {
     401                instance->position -= instance->cols;
     402                screen_scroll(instance, silent);
     403        }
     404       
     405        cursor_put(instance, silent);
     406       
     407        spinlock_unlock(&instance->lock);
     408}
     409
     410static void fb_redraw_internal(fb_instance_t *instance)
     411{
     412        if (instance->ylogo > 0) {
    401413                unsigned int y;
    402414               
     
    404416                        unsigned int x;
    405417                       
    406                         for (x = 0; x < xres; x++)
    407                                 rgb_conv(&fb_addr[FB_POS(x, y)],
     418                        for (x = 0; x < instance->xres; x++)
     419                                instance->rgb_conv(&instance->addr[FB_POS(instance, x, y)],
    408420                                    (x < LOGO_WIDTH) ?
    409421                                    fb_logo[y * LOGO_WIDTH + x] :
     
    414426        unsigned int row;
    415427       
    416         for (row = 0; row < rowtrim; row++) {
    417                 unsigned int y = ylogo + ROW2Y(row);
     428        for (row = 0; row < instance->rowtrim; row++) {
     429                unsigned int y = instance->ylogo + ROW2Y(row);
    418430                unsigned int yd;
    419431               
     
    422434                        unsigned int col;
    423435                       
    424                         for (col = 0, x = 0; col < cols;
     436                        for (col = 0, x = 0; col < instance->cols;
    425437                            col++, x += FONT_WIDTH) {
    426                                 uint16_t glyph = backbuf[BB_POS(col, row)];
    427                                 void *dst = &fb_addr[FB_POS(x, y + yd)];
    428                                 void *src = &glyphs[GLYPH_POS(glyph, yd)];
    429                                 memcpy(dst, src, glyphscanline);
     438                                uint16_t glyph =
     439                                    instance->backbuf[BB_POS(instance, col, row)];
     440                                void *dst = &instance->addr[FB_POS(instance, x, y + yd)];
     441                                void *src = &instance->glyphs[GLYPH_POS(instance, glyph, yd)];
     442                                memcpy(dst, src, instance->glyphscanline);
    430443                        }
    431444                }
    432445        }
    433446       
    434         if (COL2X(cols) < xres) {
     447        if (COL2X(instance->cols) < instance->xres) {
    435448                unsigned int y;
    436                 unsigned int size = (xres - COL2X(cols)) * pixelbytes;
    437                
    438                 for (y = ylogo; y < yres; y++)
    439                         memcpy(&fb_addr[FB_POS(COL2X(cols), y)], bgscan, size);
    440         }
    441        
    442         if (ROW2Y(rowtrim) + ylogo < yres) {
     449                unsigned int size =
     450                    (instance->xres - COL2X(instance->cols)) * instance->pixelbytes;
     451               
     452                for (y = instance->ylogo; y < instance->yres; y++)
     453                        memcpy(&instance->addr[FB_POS(instance, COL2X(instance->cols), y)],
     454                            instance->bgscan, size);
     455        }
     456       
     457        if (ROW2Y(instance->rowtrim) + instance->ylogo < instance->yres) {
    443458                unsigned int y;
    444459               
    445                 for (y = ROW2Y(rowtrim) + ylogo; y < yres; y++)
    446                         memcpy(&fb_addr[FB_POS(0, y)], bgscan, bgscanbytes);
    447         }
    448 }
    449 
     460                for (y = ROW2Y(instance->rowtrim) + instance->ylogo;
     461                    y < instance->yres; y++)
     462                        memcpy(&instance->addr[FB_POS(instance, 0, y)],
     463                            instance->bgscan, instance->bgscanbytes);
     464        }
     465}
     466
     467/** Refresh the screen
     468 *
     469 */
     470static void fb_redraw(outdev_t *dev)
     471{
     472        fb_instance_t *instance = (fb_instance_t *) dev->data;
     473       
     474        spinlock_lock(&instance->lock);
     475        fb_redraw_internal(instance);
     476        spinlock_unlock(&instance->lock);
     477}
    450478
    451479/** Initialize framebuffer as a output character device
    452480 *
    453  * @param addr   Physical address of the framebuffer
    454  * @param x      Screen width in pixels
    455  * @param y      Screen height in pixels
    456  * @param scan   Bytes per one scanline
    457  * @param visual Color model
    458  *
    459  */
    460 bool fb_init(fb_properties_t *props)
     481 */
     482outdev_t *fb_init(fb_properties_t *props)
    461483{
    462484        ASSERT(props);
     
    465487        ASSERT(props->scan > 0);
    466488       
     489        rgb_conv_t rgb_conv;
     490        unsigned int pixelbytes;
     491       
    467492        switch (props->visual) {
    468493        case VISUAL_INDIRECT_8:
     
    512537        default:
    513538                LOG("Unsupported visual.");
    514                 return false;
    515         }
    516        
    517         xres = props->x;
    518         yres = props->y;
    519         scanline = props->scan;
    520        
    521         cols = X2COL(xres);
    522         rows = Y2ROW(yres);
    523        
    524         if (yres > ylogo) {
    525                 ylogo = LOGO_HEIGHT;
    526                 rowtrim = rows - Y2ROW(ylogo);
    527                 if (ylogo % FONT_SCANLINES > 0)
    528                         rowtrim--;
    529                 ytrim = ROW2Y(rowtrim);
     539                return NULL;
     540        }
     541       
     542        outdev_t *fbdev = malloc(sizeof(outdev_t), FRAME_ATOMIC);
     543        if (!fbdev)
     544                return NULL;
     545       
     546        fb_instance_t *instance = malloc(sizeof(fb_instance_t), FRAME_ATOMIC);
     547        if (!instance) {
     548                free(fbdev);
     549                return NULL;
     550        }
     551       
     552        outdev_initialize("fbdev", fbdev, &fbdev_ops);
     553        fbdev->data = instance;
     554       
     555        spinlock_initialize(&instance->lock, "*fb_lock");
     556        instance->rgb_conv = rgb_conv;
     557        instance->pixelbytes = pixelbytes;
     558        instance->xres = props->x;
     559        instance->yres = props->y;
     560        instance->scanline = props->scan;
     561        instance->position = 0;
     562       
     563        instance->cols = X2COL(instance->xres);
     564        instance->rows = Y2ROW(instance->yres);
     565       
     566        if (instance->yres > LOGO_HEIGHT) {
     567                instance->ylogo = LOGO_HEIGHT;
     568                instance->rowtrim = instance->rows - Y2ROW(instance->ylogo);
     569                if (instance->ylogo % FONT_SCANLINES > 0)
     570                        instance->rowtrim--;
     571                instance->ytrim = ROW2Y(instance->rowtrim);
    530572        } else {
    531                 ylogo = 0;
    532                 ytrim = yres;
    533                 rowtrim = rows;
    534         }
    535        
    536         glyphscanline = FONT_WIDTH * pixelbytes;
    537         glyphbytes = ROW2Y(glyphscanline);
    538         bgscanbytes = xres * pixelbytes;
    539        
    540         size_t fbsize = scanline * yres;
    541         size_t bbsize = cols * rows * sizeof(uint16_t);
    542         size_t glyphsize = FONT_GLYPHS * glyphbytes;
    543        
    544         fb_addr = (uint8_t *) hw_map((uintptr_t) props->addr, fbsize);
    545         if (!fb_addr) {
     573                instance->ylogo = 0;
     574                instance->ytrim = instance->yres;
     575                instance->rowtrim = instance->rows;
     576        }
     577       
     578        instance->glyphscanline = FONT_WIDTH * instance->pixelbytes;
     579        instance->glyphbytes = ROW2Y(instance->glyphscanline);
     580        instance->bgscanbytes = instance->xres * instance->pixelbytes;
     581       
     582        size_t fbsize = instance->scanline * instance->yres;
     583        size_t bbsize = instance->cols * instance->rows * sizeof(uint16_t);
     584        size_t glyphsize = FONT_GLYPHS * instance->glyphbytes;
     585       
     586        instance->addr = (uint8_t *) hw_map((uintptr_t) props->addr, fbsize);
     587        if (!instance->addr) {
    546588                LOG("Unable to map framebuffer.");
    547                 return false;
    548         }
    549        
    550         backbuf = (uint16_t *) malloc(bbsize, 0);
    551         if (!backbuf) {
     589                free(instance);
     590                free(fbdev);
     591                return NULL;
     592        }
     593       
     594        instance->backbuf = (uint16_t *) malloc(bbsize, 0);
     595        if (!instance->backbuf) {
    552596                LOG("Unable to allocate backbuffer.");
    553                 return false;
    554         }
    555        
    556         glyphs = (uint8_t *) malloc(glyphsize, 0);
    557         if (!glyphs) {
    558                 free(backbuf);
     597                free(instance);
     598                free(fbdev);
     599                return NULL;
     600        }
     601       
     602        instance->glyphs = (uint8_t *) malloc(glyphsize, 0);
     603        if (!instance->glyphs) {
    559604                LOG("Unable to allocate glyphs.");
    560                 return false;
    561         }
    562        
    563         bgscan = malloc(bgscanbytes, 0);
    564         if (!bgscan) {
    565                 free(glyphs);
    566                 free(backbuf);
     605                free(instance->backbuf);
     606                free(instance);
     607                free(fbdev);
     608                return NULL;
     609        }
     610       
     611        instance->bgscan = malloc(instance->bgscanbytes, 0);
     612        if (!instance->bgscan) {
    567613                LOG("Unable to allocate background pixel.");
    568                 return false;
    569         }
    570        
    571         memsetw(backbuf, cols * rows, 0);
    572         glyphs_render();
    573        
    574         sysinfo_set_item_val("fb", NULL, true);
    575         sysinfo_set_item_val("fb.kind", NULL, 1);
    576         sysinfo_set_item_val("fb.width", NULL, xres);
    577         sysinfo_set_item_val("fb.height", NULL, yres);
    578         sysinfo_set_item_val("fb.scanline", NULL, scanline);
    579         sysinfo_set_item_val("fb.visual", NULL, props->visual);
    580         sysinfo_set_item_val("fb.address.physical", NULL, props->addr);
    581        
    582         fb_redraw();
    583        
    584         outdev_initialize("fb", &fb_console, &fb_ops);
    585         stdout_wire(&fb_console);
    586        
    587         return true;
     614                free(instance->glyphs);
     615                free(instance->backbuf);
     616                free(instance);
     617                free(fbdev);
     618                return NULL;
     619        }
     620       
     621        memsetw(instance->backbuf, instance->cols * instance->rows, 0);
     622        glyphs_render(instance);
     623       
     624        if (!fb_exported) {
     625                /*
     626                 * This is the necessary evil until the userspace driver is entirely
     627                 * self-sufficient.
     628                 */
     629                sysinfo_set_item_val("fb", NULL, true);
     630                sysinfo_set_item_val("fb.kind", NULL, 1);
     631                sysinfo_set_item_val("fb.width", NULL, instance->xres);
     632                sysinfo_set_item_val("fb.height", NULL, instance->yres);
     633                sysinfo_set_item_val("fb.scanline", NULL, instance->scanline);
     634                sysinfo_set_item_val("fb.visual", NULL, props->visual);
     635                sysinfo_set_item_val("fb.address.physical", NULL, props->addr);
     636               
     637                fb_exported = true;
     638        }
     639       
     640        fb_redraw(fbdev);
     641        return fbdev;
    588642}
    589643
Note: See TracChangeset for help on using the changeset viewer.