Changeset 1787e527 in mainline for kernel/genarch/src/fb/fb.c


Ignore:
Timestamp:
2009-11-16T21:22:54Z (14 years ago)
Author:
Lenka Trochtova <trochtova.lenka@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5ebdf94
Parents:
fcbd1be (diff), 9c70ed6 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

merged with head (unstable)

File:
1 edited

Legend:

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

    rfcbd1be r1787e527  
    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 void fb_init(fb_properties_t *props)
    461 {
     481 */
     482outdev_t *fb_init(fb_properties_t *props)
     483{
     484        ASSERT(props);
     485        ASSERT(props->x > 0);
     486        ASSERT(props->y > 0);
     487        ASSERT(props->scan > 0);
     488       
     489        rgb_conv_t rgb_conv;
     490        unsigned int pixelbytes;
     491       
    462492        switch (props->visual) {
    463493        case VISUAL_INDIRECT_8:
     
    506536                break;
    507537        default:
    508                 panic("Unsupported visual.");
    509         }
    510        
    511         xres = props->x;
    512         yres = props->y;
    513         scanline = props->scan;
    514        
    515         cols = X2COL(xres);
    516         rows = Y2ROW(yres);
    517        
    518         if (yres > ylogo) {
    519                 ylogo = LOGO_HEIGHT;
    520                 rowtrim = rows - Y2ROW(ylogo);
    521                 if (ylogo % FONT_SCANLINES > 0)
    522                         rowtrim--;
    523                 ytrim = ROW2Y(rowtrim);
     538                LOG("Unsupported visual.");
     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);
    524572        } else {
    525                 ylogo = 0;
    526                 ytrim = yres;
    527                 rowtrim = rows;
    528         }
    529        
    530         glyphscanline = FONT_WIDTH * pixelbytes;
    531         glyphbytes = ROW2Y(glyphscanline);
    532         bgscanbytes = xres * pixelbytes;
    533        
    534         size_t fbsize = scanline * yres;
    535         size_t bbsize = cols * rows * sizeof(uint16_t);
    536         size_t glyphsize = FONT_GLYPHS * glyphbytes;
    537        
    538         backbuf = (uint16_t *) malloc(bbsize, 0);
    539         if (!backbuf)
    540                 panic("Unable to allocate backbuffer.");
    541        
    542         glyphs = (uint8_t *) malloc(glyphsize, 0);
    543         if (!glyphs)
    544                 panic("Unable to allocate glyphs.");
    545        
    546         bgscan = malloc(bgscanbytes, 0);
    547         if (!bgscan)
    548                 panic("Unable to allocate background pixel.");
    549        
    550         memsetw(backbuf, cols * rows, 0);
    551        
    552         glyphs_render();
    553        
    554         fb_addr = (uint8_t *) hw_map((uintptr_t) props->addr, fbsize);
    555        
    556         sysinfo_set_item_val("fb", NULL, true);
    557         sysinfo_set_item_val("fb.kind", NULL, 1);
    558         sysinfo_set_item_val("fb.width", NULL, xres);
    559         sysinfo_set_item_val("fb.height", NULL, yres);
    560         sysinfo_set_item_val("fb.scanline", NULL, scanline);
    561         sysinfo_set_item_val("fb.visual", NULL, props->visual);
    562         sysinfo_set_item_val("fb.address.physical", NULL, props->addr);
    563        
    564         fb_redraw();
    565        
    566         outdev_initialize("fb", &fb_console, &fb_ops);
    567         stdout = &fb_console;
     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) {
     588                LOG("Unable to map framebuffer.");
     589                free(instance);
     590                free(fbdev);
     591                return NULL;
     592        }
     593       
     594        instance->backbuf = (uint16_t *) malloc(bbsize, 0);
     595        if (!instance->backbuf) {
     596                LOG("Unable to allocate backbuffer.");
     597                free(instance);
     598                free(fbdev);
     599                return NULL;
     600        }
     601       
     602        instance->glyphs = (uint8_t *) malloc(glyphsize, 0);
     603        if (!instance->glyphs) {
     604                LOG("Unable to allocate glyphs.");
     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) {
     613                LOG("Unable to allocate background pixel.");
     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;
    568642}
    569643
Note: See TracChangeset for help on using the changeset viewer.