Annotation of qemu/roms/openbios/packages/video.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *   Creation Date: <2002/10/23 20:26:40 samuel>
                      3:  *   Time-stamp: <2004/01/07 19:39:15 samuel>
                      4:  *
                      5:  *     <video.c>
                      6:  *
                      7:  *     Mac-on-Linux display node
                      8:  *
                      9:  *   Copyright (C) 2002, 2003, 2004 Samuel Rydh ([email protected])
                     10:  *
                     11:  *   This program is free software; you can redistribute it and/or
                     12:  *   modify it under the terms of the GNU General Public License
                     13:  *   as published by the Free Software Foundation
                     14:  *
                     15:  */
                     16: 
                     17: #include "config.h"
                     18: #include "libopenbios/bindings.h"
                     19: #include "libc/diskio.h"
                     20: #include "libopenbios/ofmem.h"
                     21: #include "drivers/drivers.h"
                     22: #include "packages/video.h"
                     23: #include "libopenbios/console.h"
                     24: #include "drivers/vga.h"
                     25: 
                     26: typedef struct osi_fb_info {
                     27:     unsigned long mphys;
                     28:     int rb, w, h, depth;
                     29: } osi_fb_info_t;
                     30: 
                     31: static struct {
                     32:        int             has_video;
                     33:        osi_fb_info_t   fb;
                     34:        unsigned long           *pal;           /* 256 elements */
                     35: } video;
                     36: 
                     37: 
                     38: int
                     39: video_get_res( int *w, int *h )
                     40: {
                     41:        if( !video.has_video ) {
                     42:                *w = *h = 0;
                     43:                return -1;
                     44:        }
                     45:        *w = video.fb.w;
                     46:        *h = video.fb.h;
                     47:        return 0;
                     48: }
                     49: 
                     50: static void
                     51: startup_splash( void )
                     52: {
                     53: #ifdef CONFIG_MOL
                     54:        int fd, s, i, y, x, dx, dy;
                     55:        int width, height;
                     56:        char *pp, *p;
                     57:        char buf[64];
                     58: #endif
                     59: 
                     60:        /* only draw logo in 24-bit mode (for now) */
                     61:        if( video.fb.depth < 15 )
                     62:                return;
                     63: #ifdef CONFIG_MOL
                     64:        for( i=0; i<2; i++ ) {
                     65:                if( !BootHGetStrResInd("bootlogo", buf, sizeof(buf), 0, i) )
                     66:                        return;
                     67:                *(!i ? &width : &height) = atol(buf);
                     68:        }
                     69: 
                     70:        if( (s=width * height * 3) > 0x20000 )
                     71:                return;
                     72: 
                     73:        if( (fd=open_io("pseudo:,bootlogo")) >= 0 ) {
                     74:                p = malloc( s );
                     75:                if( read_io(fd, p, s) != s )
                     76:                        printk("bootlogo size error\n");
                     77:                close_io( fd );
                     78: 
                     79:                dx = (video.fb.w - width)/2;
                     80:                dy = (video.fb.h - height)/3;
                     81: 
                     82:                pp = (char*)video.fb.mphys + dy * video.fb.rb + dx * (video.fb.depth >= 24 ? 4 : 2);
                     83: 
                     84:                for( y=0 ; y<height; y++, pp += video.fb.rb ) {
                     85:                        if( video.fb.depth >= 24 ) {
                     86:                                unsigned long *d = (unsigned long*)pp;
                     87:                                for( x=0; x<width; x++, p+=3, d++ )
                     88:                                        *d = ((int)p[0] << 16) | ((int)p[1] << 8) | p[2];
                     89:                        } else if( video.fb.depth == 15 ) {
                     90:                                unsigned short *d = (unsigned short*)pp;
                     91:                                for( x=0; x<width; x++, p+=3, d++ ) {
                     92:                                        int col = ((int)p[0] << 16) | ((int)p[1] << 8) | p[2];
                     93:                                        *d = ((col>>9) & 0x7c00) | ((col>>6) & 0x03e0) | ((col>>3) & 0x1f);
                     94:                                }
                     95:                        }
                     96:                }
                     97:                free( p );
                     98:        }
                     99: #else
                    100:        /* No bootlogo support yet on other platforms */
                    101:        return;
                    102: #endif
                    103: }
                    104: 
                    105: static unsigned long
                    106: get_color( int col_ind )
                    107: {
                    108:        unsigned long col;
                    109:        if( !video.has_video || col_ind < 0 || col_ind > 255 )
                    110:                return 0;
                    111:        if( video.fb.depth == 8 )
                    112:                return col_ind;
                    113:        col = video.pal[col_ind];
                    114:        if( video.fb.depth == 24 || video.fb.depth == 32 )
                    115:                return col;
                    116:        if( video.fb.depth == 15 )
                    117:                return ((col>>9) & 0x7c00) | ((col>>6) & 0x03e0) | ((col>>3) & 0x1f);
                    118:        return 0;
                    119: }
                    120: 
                    121: void
                    122: draw_pixel( int x, int y, int colind )
                    123: {
                    124:        char *p = (char*)video.fb.mphys + video.fb.rb * y;
                    125:        int color, d = video.fb.depth;
                    126: 
                    127:        if( x < 0 || y < 0 || x >= video.fb.w || y >=video.fb.h )
                    128:                return;
                    129:        color = get_color( colind );
                    130: 
                    131:        if( d >= 24 )
                    132:                *((unsigned long*)p + x) = color;
                    133:        else if( d >= 15 )
                    134:                *((short*)p + x) = color;
                    135:        else
                    136:                *(p + x) = color;
                    137: }
                    138: 
                    139: static void
                    140: fill_rect( int col_ind, int x, int y, int w, int h )
                    141: {
                    142:        char *pp;
                    143:        unsigned long col = get_color(col_ind);
                    144: 
                    145:         if (!video.has_video || x < 0 || y < 0 || w <= 0 || h <= 0 ||
                    146:             x + w > video.fb.w || y + h > video.fb.h)
                    147:                return;
                    148: 
                    149:        pp = (char*)video.fb.mphys + video.fb.rb * y;
                    150:        for( ; h--; pp += video.fb.rb ) {
                    151:                int ww = w;
                    152:                if( video.fb.depth == 24 || video.fb.depth == 32 ) {
                    153:                        unsigned long *p = (unsigned long*)pp + x;
                    154:                        while( ww-- )
                    155:                                *p++ = col;
                    156:                } else if( video.fb.depth == 16 || video.fb.depth == 15 ) {
                    157:                        unsigned short *p = (unsigned short*)pp + x;
                    158:                        while( ww-- )
                    159:                                *p++ = col;
                    160:                } else {
                    161:                         char *p = (char *)((unsigned short*)pp + x);
                    162: 
                    163:                        while( ww-- )
                    164:                                *p++ = col;
                    165:                }
                    166:        }
                    167: }
                    168: 
                    169: static void
                    170: refresh_palette( void )
                    171: {
                    172: #ifdef CONFIG_MOL
                    173:        if( video.fb.depth == 8 )
                    174:                OSI_RefreshPalette();
                    175: #endif
                    176: }
                    177: 
                    178: void
                    179: set_color( int ind, unsigned long color )
                    180: {
                    181:        if( !video.has_video || ind < 0 || ind > 255 )
                    182:                return;
                    183:        video.pal[ind] = color;
                    184: 
                    185: #ifdef CONFIG_MOL
                    186:        if( video.fb.depth == 8 )
                    187:                OSI_SetColor( ind, color );
                    188: #elif defined(CONFIG_SPARC32)
                    189:        if( video.fb.depth == 8 ) {
                    190:             dac[0] = ind << 24;
                    191:             dac[1] = ((color >> 16) & 0xff) << 24; // Red
                    192:             dac[1] = ((color >> 8) & 0xff) << 24; // Green
                    193:             dac[1] = (color & 0xff) << 24; // Blue
                    194:         }
                    195: #else
                    196:        vga_set_color(ind, ((color >> 16) & 0xff),
                    197:                           ((color >> 8) & 0xff),
                    198:                           (color & 0xff));
                    199: #endif
                    200: }
                    201: 
                    202: void
                    203: video_scroll( int height )
                    204: {
                    205:        int i, offs, size, *dest, *src;
                    206: 
                    207:         if (height <= 0 || height >= video.fb.h) {
                    208:                 return;
                    209:         }
                    210:        offs = video.fb.rb * height;
                    211:        size = (video.fb.h * video.fb.rb - offs)/16;
                    212:        dest = (int*)video.fb.mphys;
                    213:        src = (int*)(video.fb.mphys + offs);
                    214: 
                    215:        for( i=0; i<size; i++ ) {
                    216:                dest[0] = src[0];
                    217:                dest[1] = src[1];
                    218:                dest[2] = src[2];
                    219:                dest[3] = src[3];
                    220:                dest += 4;
                    221:                src += 4;
                    222:        }
                    223: }
                    224: 
                    225: /************************************************************************/
                    226: /*     OF methods                                                      */
                    227: /************************************************************************/
                    228: 
                    229: DECLARE_NODE( video, INSTALL_OPEN, 0, "Tdisplay" );
                    230: 
                    231: /* ( -- width height ) (?) */
                    232: static void
                    233: video_dimensions( void )
                    234: {
                    235:        int w, h;
                    236:        (void) video_get_res( &w, &h );
                    237:        PUSH( w );
                    238:        PUSH( h );
                    239: }
                    240: 
                    241: /* ( table start count -- ) (?) */
                    242: static void
                    243: video_set_colors( void )
                    244: {
                    245:        int count = POP();
                    246:        int start = POP();
                    247:        unsigned char *p = (unsigned char*)cell2pointer(POP());
                    248:        int i;
                    249: 
                    250:        for( i=0; i<count; i++, p+=3 ) {
                    251:                unsigned long col = (p[0] << 16) | (p[1] << 8) | p[2];
                    252:                set_color( i + start, col );
                    253:        }
                    254:        refresh_palette();
                    255: }
                    256: 
                    257: /* ( r g b index -- ) */
                    258: static void
                    259: video_color_bang( void )
                    260: {
                    261:        int index = POP();
                    262:        int b = POP();
                    263:        int g = POP();
                    264:        int r = POP();
                    265:        unsigned long col = ((r << 16) & 0xff0000) | ((g << 8) & 0x00ff00) | (b & 0xff);
                    266:        /* printk("color!: %08lx %08lx %08lx %08lx\n", r, g, b, index ); */
                    267:        set_color( index, col );
                    268:        refresh_palette();
                    269: }
                    270: 
                    271: /* ( color_ind x y width height -- ) (?) */
                    272: static void
                    273: video_fill_rect( void )
                    274: {
                    275:        int h = POP();
                    276:        int w = POP();
                    277:        int y = POP();
                    278:        int x = POP();
                    279:        int color_ind = POP();
                    280: 
                    281:        fill_rect( color_ind, x, y, w, h );
                    282: }
                    283: 
                    284: /* ( addr len -- actual ) */
                    285: static void
                    286: video_write(void)
                    287: {
                    288:     char *addr;
                    289:     int len;
                    290: 
                    291:     len = POP();
                    292:     addr = (char *)cell2pointer(POP());
                    293: 
                    294:     console_draw_fstr(addr, len);
                    295:     PUSH(len);
                    296: }
                    297: 
                    298: NODE_METHODS( video ) = {
                    299:        {"dimensions",          video_dimensions        },
                    300:        {"set-colors",          video_set_colors        },
                    301:        {"fill-rectangle",      video_fill_rect         },
                    302:        {"color!",              video_color_bang        },
                    303:        {"write",               video_write             },
                    304: };
                    305: 
                    306: 
                    307: /************************************************************************/
                    308: /*     init                                                            */
                    309: /************************************************************************/
                    310: 
                    311: void
                    312: init_video( unsigned long fb,  int width, int height, int depth, int rb )
                    313: {
                    314:         int i;
                    315: #ifdef CONFIG_PPC
                    316:         int s, size;
                    317: #endif
                    318:        phandle_t ph=0;
                    319: 
                    320:        video.fb.mphys = fb;
                    321:        video.fb.w = width;
                    322:        video.fb.h = height;
                    323:        video.fb.depth = depth;
                    324:        video.fb.rb = rb;
                    325:        while( (ph=dt_iterate_type(ph, "display")) ) {
                    326:                set_int_property( ph, "width", video.fb.w );
                    327:                set_int_property( ph, "height", video.fb.h );
                    328:                set_int_property( ph, "depth", video.fb.depth );
                    329:                set_int_property( ph, "linebytes", video.fb.rb );
                    330:                set_int_property( ph, "address", video.fb.mphys );
                    331:        }
                    332:        video.has_video = 1;
                    333:        video.pal = malloc( 256 * sizeof(unsigned long) );
                    334: 
                    335: #ifdef CONFIG_PPC
                    336:         s = (video.fb.mphys & 0xfff);
                    337:         size = ((video.fb.h * video.fb.rb + s) + 0xfff) & ~0xfff;
                    338: 
                    339:        ofmem_claim_phys( video.fb.mphys, size, 0 );
                    340:        ofmem_claim_virt( video.fb.mphys, size, 0 );
                    341:        ofmem_map( video.fb.mphys, video.fb.mphys, size, -1 );
                    342: #endif
                    343: 
                    344:        for( i=0; i<256; i++ )
                    345:                set_color( i, i * 0x010101 );
                    346: 
                    347:        set_color( 254, 0xffffcc );
                    348:        fill_rect( 254, 0, 0, video.fb.w, video.fb.h );
                    349: 
                    350:        refresh_palette();
                    351:        startup_splash();
                    352: 
                    353:        REGISTER_NODE( video );
                    354: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.