Annotation of kernel/bsd/dev/ppc/FBConsole.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /*     Copyright (c) 1992 NeXT Computer, Inc.  All rights reserved. 
                     26:  *
                     27:  * FBConsole.c - FrameBuffer based console implementation.
                     28:  *
                     29:  *
                     30:  * HISTORY
                     31:  * 01 Sep 92   Joe Pasqua
                     32:  *      Created. 
                     33:  * 25 Mar 97    Simon Douglas
                     34:  *      Rhapsodized.
                     35:  */
                     36: 
                     37: // TO DO:
                     38: // * Implement other cases of FlipCursor, HorizLine, VertLine, ClearWindow.
                     39: //   Erase
                     40: // * Find the #defines for np and del are, then get rid of our #defines.
                     41: //
                     42: // Notes:
                     43: // * This module implements the console functionality required by the
                     44: //   ConsoleSupport protocol. If you have a device which is a framebuffer
                     45: //   with a depth supported by this module, then you can use this code. 
                     46: // * To find things that need to be fixed, search for FIX, to find questions
                     47: //   to be resolved, search for ASK, to find stuff that still needs to be
                     48: //   done, search for TO DO.
                     49: 
                     50: #define BRINGUP 1
                     51: 
                     52: #import <sys/syslog.h>
                     53: #import        <bsd/dev/ppc/FBConsole.h>
                     54: #import        <bsd/dev/ppc/FBConsPriv.h>
                     55: #import <architecture/ascii_codes.h>
                     56: #import "BootImages.h"
                     57: 
                     58: #if defined(NOTINKERNEL)
                     59: #define panic(str)
                     60: #define copyin(src, dst, size) bcopy(src, dst, size)
                     61: #define kalloc(size) malloc(size)
                     62: #define kfree(ptr, size) free(ptr)
                     63: #endif
                     64: 
                     65: #ifdef DRIVERKIT
                     66: #else
                     67: #define IOMalloc(size) kalloc(size)
                     68: #define IOFree(ptr,size) kfree(ptr,size)
                     69: #define IOLog(s,a) printf(s,a)
                     70: #endif // DRIVERKIT
                     71: 
                     72: #define        TEXTURE_BACKGND 1
                     73: 
                     74: /*
                     75:  * Standard font.
                     76:  */
                     77: extern char ohlfs12[][];
                     78: 
                     79: #import "ohlfs12.h"
                     80: 
                     81: #define        NIL     (0)
                     82: 
                     83: /* Window margins */
                     84: #define BG_MARGIN      2       // pixels of background to leave as margin
                     85: #define FG_MARGIN      1       // pixels of foreground to leave as margin
                     86: #define TOTAL_MARGIN   (BG_MARGIN + FG_MARGIN)
                     87: #define DROP_SHADOW    1       // pixels of dark_grey, bottom & right
                     88: #define TS_MARGIN      1       // 
                     89: 
                     90: #define HORIZ_BORDER   32      // 40 on VGA
                     91: #define VERT_BORDER    22      // 30 on VGA
                     92: 
                     93: /*
                     94:  * Ansi sequence state.
                     95:  */
                     96: typedef enum {
                     97:        AS_NORMAL,
                     98:        AS_ESCAPE,
                     99:        AS_BRACKET,
                    100:        AS_R
                    101: } ansi_state_t;
                    102: 
                    103: #define ANSI_STACK_SIZE        3
                    104: 
                    105: typedef struct _t_Console {
                    106:     ScreenMode         window_type;
                    107: 
                    108:     IODisplayInfo      display;
                    109: 
                    110:     //
                    111:     // The remaining fields are window parameters. These are only 
                    112:     // meaningful for text-type windows (window_type == SCM_TEXT or 
                    113:     // SCM_ALERT).
                    114:     //
                    115:        
                    116:     //
                    117:     // Current window origin in pixels, relative to origin of screen.
                    118:     //
                    119:     int                        window_origin_x;
                    120:     int                        window_origin_y;
                    121: 
                    122:     //
                    123:     // Window size information, in pixels and in characters.
                    124:     //
                    125:     int                        chars_per_row;  
                    126:     int                        pixels_per_row; 
                    127:     int                        chars_per_column;
                    128:     int                pixels_per_column;
                    129: 
                    130:     //
                    131:     // Cursor location, in characters. Origin is top 
                    132:     // left corner of window = {0,0}. 
                    133:     //
                    134:     int                        curr_row;               // in characters
                    135:     int                curr_column;            // in characters
                    136:     
                    137:     //
                    138:     // Misc. video parameters. The background and foreground fields
                    139:     // are slightly dependent on the hardware implementation; they'll
                    140:     // work as long as bits per pixel <= 32.
                    141:     //
                    142: 
                    143:     unsigned int       background;             // bits for background pixel
                    144:     unsigned int       light_grey;             // bits for light grey
                    145:     unsigned int       dark_grey;              // bits for dark grey
                    146:     unsigned int       foreground;             // bits for foreground pixel
                    147:     unsigned int       baseground;             // bits for base color
                    148:     unsigned int       grayTable[4];           // bits for drawing bitmaps
                    149: 
                    150:     boolean_t          has_title;
                    151:     boolean_t          prettyPanelUp;
                    152:     unsigned int       bolding;                // bold text pixel count
                    153: 
                    154:     //
                    155:     // Storage for saved region under an alert panel.
                    156:     //
                    157:     unsigned char *saveBits;
                    158:     int saveHeight;
                    159:     int saveRowBytes;
                    160:     int saveBytes;
                    161:     unsigned char *saveLocation;
                    162:     ansi_state_t ansi_state;   /* track ansi escape sequence state */
                    163:     u_char ansi_stack[ANSI_STACK_SIZE];
                    164:     u_char *ansi_stack_p;
                    165: 
                    166: } ConsoleRep, *ConsolePtr;
                    167: 
                    168: //
                    169: // BEGIN:      Private utility routines
                    170: //
                    171: 
                    172: static void videoMemMove( char * dst, char * src, unsigned int len )
                    173: {
                    174: #if 1
                    175:     bcopy_nc( src, dst, len );
                    176: #else
                    177:     memmove( dst, src, len );
                    178: #endif
                    179: }
                    180: 
                    181: static unsigned int BPPToPPW(int bpp)
                    182: {
                    183:   if (bpp == IO_2BitsPerPixel) return(16);
                    184:   if (bpp == IO_8BitsPerPixel) return(4);
                    185:   if (bpp == IO_12BitsPerPixel) return(2);
                    186:   if (bpp == IO_15BitsPerPixel) return(2);
                    187:   if (bpp == IO_24BitsPerPixel) return(1);
                    188:   else return(-1);
                    189: }
                    190: 
                    191: static unsigned char *PixelAddress(ConsolePtr console, int xPix, int yPix)
                    192: {
                    193:     switch (console->display.bitsPerPixel) {
                    194:         case IO_8BitsPerPixel:
                    195:            return ((unsigned char *)console->display.frameBuffer) +
                    196:                    yPix * console->display.rowBytes + xPix;
                    197:         case IO_12BitsPerPixel:
                    198:        case IO_15BitsPerPixel:
                    199:            return ((unsigned char *)console->display.frameBuffer) +
                    200:                    yPix * console->display.rowBytes + xPix * 2;
                    201:        case IO_24BitsPerPixel:
                    202:            return ((unsigned char *)console->display.frameBuffer) +
                    203:                    yPix * console->display.rowBytes + xPix * 4;
                    204:        default:
                    205:            panic("FBConsole/PixelAddress: bogus bitsPerPixel");
                    206:     }
                    207: }
                    208: 
                    209: static void Fill(ConsolePtr console,
                    210:     unsigned char *dst,                // Where to start filling
                    211:     unsigned pixel,            // pattern to fill
                    212:     unsigned len)              // in pixels
                    213: // Descritpion:        Fill the framebuffer with 'pixel' starting at dst
                    214: //             and for 'len' pixels.
                    215: {
                    216:     switch (console->display.bitsPerPixel) {
                    217:         case IO_8BitsPerPixel:
                    218:            {
                    219:            unsigned char *dst8 = (unsigned char *)dst;
                    220:            for (; len--; dst8++)
                    221:                *dst8 = pixel;
                    222:            break;
                    223:            }
                    224:         case IO_12BitsPerPixel:
                    225:        case IO_15BitsPerPixel:
                    226:            {
                    227:            unsigned short *dst16 = (unsigned short *)dst;
                    228:            for (; len--; dst16++)
                    229:                *dst16 = pixel;
                    230:            break;
                    231:            }
                    232:        case IO_24BitsPerPixel:
                    233:            {
                    234:            unsigned int *dst32 = (unsigned int *)dst;
                    235:            for (; len--; dst32++)
                    236:                *dst32 = pixel;
                    237:            break;
                    238:            }
                    239:        default:
                    240:            panic("FBConsole/Fill: bogus bitsPerPixel");
                    241:     }
                    242: }
                    243: 
                    244: static void FlipCursor(ConsolePtr console)
                    245: // Description: Turn cursor on/off. This just inverts every pixel at the
                    246: // character at (curr_rown, curr_column).
                    247: {
                    248:     int y;
                    249:     unsigned char *dst8;
                    250:     unsigned short *dst16;
                    251:     unsigned int *dst32;
                    252:     unsigned pixel_num;
                    253:     
                    254:     // Screen-relative pixel coordinates of bounds of current  character.
                    255:     int start_y = console->window_origin_y +
                    256:         console->curr_row * CHAR_H;
                    257:     int end_y   = start_y + CHAR_H;
                    258:     int start_x = console->window_origin_x +
                    259:         console->curr_column * CHAR_W;
                    260:     
                    261:     for (y=start_y; y < end_y; y++) {
                    262:        switch (console->display.bitsPerPixel) {
                    263:            case IO_8BitsPerPixel:
                    264:                dst8 = (unsigned char *)PixelAddress(console, start_x, y);
                    265:                for (pixel_num = 0; pixel_num < CHAR_W; pixel_num++) {
                    266:                        if ((*dst8 & PIXEL_MASK_16) ==
                    267:                            (console->background & PIXEL_MASK_16)) {
                    268:                                *dst8 = console->foreground;
                    269:                        }
                    270:                        else {
                    271:                                *dst8 = console->background;
                    272:                        }
                    273:                        dst8++;
                    274:                }
                    275:                break;
                    276:            case IO_12BitsPerPixel:
                    277:            case IO_15BitsPerPixel:
                    278:                dst16 = (unsigned short *)PixelAddress(console, start_x, y);
                    279:                for (pixel_num = 0; pixel_num < CHAR_W; pixel_num++) {
                    280:                        if ((*dst16 & PIXEL_MASK_16) ==
                    281:                            (console->background & PIXEL_MASK_16)) {
                    282:                                *dst16 = console->foreground;
                    283:                        }
                    284:                        else {
                    285:                                *dst16 = console->background;
                    286:                        }
                    287:                        dst16++;
                    288:                }
                    289:                break;
                    290:            case IO_24BitsPerPixel:
                    291:                dst32 = (unsigned int *)PixelAddress(console, start_x, y);
                    292:                for (pixel_num = 0; pixel_num < CHAR_W; pixel_num++) {
                    293:                        if ((*dst32 & PIXEL_MASK_32) ==
                    294:                            (console->background & PIXEL_MASK_32)) {
                    295:                                *dst32 = console->foreground;
                    296:                        }
                    297:                        else {
                    298:                                *dst32 = console->background;
                    299:                        }
                    300:                        dst32++;
                    301:                }
                    302:                break;
                    303:                
                    304:            default:
                    305:                panic("FBConsole/FlipCursor: bogus bits per pixel");
                    306:        }       
                    307:     }
                    308: }
                    309: 
                    310: static void SwapForegroundAndBackground(ConsolePtr console)
                    311: {
                    312:     int temp_color;
                    313:     
                    314:     temp_color = console->foreground;
                    315:     console->foreground = console->background;
                    316:     console->background = temp_color;
                    317: }
                    318: 
                    319: static void Rect(
                    320:     ConsolePtr console,
                    321:     int origin_x, int origin_y,
                    322:     int width, int height,
                    323:     unsigned pixel)
                    324: // Description:        Draws a single pixel wide horizontal line
                    325: {
                    326:     while (height--)
                    327:        Fill(console,
                    328:            PixelAddress(console, origin_x, origin_y++),
                    329:            pixel, width);
                    330: }
                    331: 
                    332: #ifdef notdef
                    333: static void HorizLine(
                    334:     ConsolePtr console,
                    335:     int origin_x, int origin_y, int length,
                    336:     unsigned pixel)
                    337: // Description:        Draws a single pixel wide horizontal line
                    338: {
                    339:     Fill(console, PixelAddress(console, origin_x, origin_y), pixel, length);
                    340: }
                    341: 
                    342: static void VertLine(
                    343:     ConsolePtr console,
                    344:     int origin_x, int origin_y, int length,
                    345:     unsigned pixel)
                    346: // Description:        Draws a single pixel wide vertical line
                    347: {
                    348:     unsigned char *dstPixel = PixelAddress(console, origin_x, origin_y);
                    349: 
                    350:     switch(console->display.bitsPerPixel) {
                    351:        case IO_8BitsPerPixel:
                    352:            {
                    353:                unsigned char *dst = (unsigned char *)dstPixel;
                    354:                while (length--) {
                    355:                    *dst = pixel;
                    356:                    dst += console->display.totalWidth;
                    357:                }
                    358:            }
                    359:            break;
                    360:        case IO_12BitsPerPixel:
                    361:        case IO_15BitsPerPixel:
                    362:            {
                    363:                unsigned short *dst = (unsigned short *)dstPixel;
                    364:                while (length--) {
                    365:                    *dst = pixel;
                    366:                    dst += console->display.totalWidth;
                    367:                }
                    368:            }
                    369:            break;
                    370:        case IO_24BitsPerPixel:
                    371:            {
                    372:                unsigned long *dst = (unsigned long *)dstPixel;
                    373:                while (length--) {
                    374:                    *dst = pixel;
                    375:                    dst += console->display.totalWidth;
                    376:                }
                    377:            }
                    378:            break;
                    379:            
                    380:        default:
                    381:            panic("FBConsole/VertLine: bogus bits per pixel");
                    382:     }
                    383: }
                    384: #endif
                    385: 
                    386: static void ClearWindow(ConsolePtr console)
                    387: // Description:         Set contents of entire current window to background.
                    388: // Preconditions:
                    389: // *   Cursor is off on entry and will remain so on exit.
                    390: {
                    391:     int line;
                    392:     unsigned char *dstPixel = PixelAddress(
                    393:         console, console->window_origin_x, console->window_origin_y);
                    394: 
                    395:     for (line=0; line < console->pixels_per_column; line++) {
                    396:        // One loop per scan line in the window.
                    397:        Fill(console, dstPixel, console->background,
                    398:             console->pixels_per_row);
                    399:        dstPixel += console->display.rowBytes;
                    400:     }
                    401: }
                    402: 
                    403: static void WipeScreen(ConsolePtr console, const unsigned pixel)
                    404: // Description:        Fill the screen with specific pixel value.  
                    405: {
                    406:     static int horstArray[5] = { 5,3,2,1,1 };
                    407:     int i,horst;
                    408: 
                    409:     Rect( console, 0, 0, console->display.width, console->display.height, pixel );
                    410: 
                    411:     // Round rect
                    412:     for( i=0; i < 5; i++) {
                    413:        horst = horstArray[i];
                    414:        // top left
                    415:        Fill(console, PixelAddress(console, 0, i), console->foreground, horst);
                    416:        // bottom left
                    417:        Fill(console, PixelAddress(console, 0, console->display.height - i - 1), console->foreground, horst);
                    418:        // top right
                    419:        Fill(console, PixelAddress(console, console->display.width - horst, i), console->foreground, horst);
                    420:        // bottom right
                    421:        Fill(console, PixelAddress(console, console->display.width - horst, console->display.height - i - 1),
                    422:                console->foreground, horst);
                    423:     }
                    424: }
                    425: 
                    426: static void ClearToEOL(ConsolePtr console)
                    427: // Description:        Clear to end of line (within window), including current pos.
                    428: // Preconditions:
                    429: // *   Cursor is 'off' on entry and will remain so on exit.
                    430: {
                    431:     unsigned pixel_count;
                    432:     int starting_x;                    // window-relative 'x' coordinate
                    433:     int y;
                    434:     int line;  
                    435: 
                    436:     starting_x = console->window_origin_x + 
                    437:        (console->curr_column * CHAR_W);
                    438:     y = console->window_origin_y + (console->curr_row * CHAR_H);
                    439: 
                    440:     pixel_count = console->pixels_per_row -
                    441:         (starting_x - console->window_origin_x);
                    442: 
                    443:     for (line=0; line < CHAR_H; line++) {
                    444:        // One loop per scan line in the row.
                    445:        Fill(
                    446:            console, PixelAddress(console, starting_x, y++),
                    447:            console->background, pixel_count);
                    448:     }
                    449: }
                    450: 
                    451: static void Erase(ConsolePtr console)
                    452: // Description: Erase current cursor location.
                    453: {
                    454:     int y;
                    455:     unsigned char *dst8;
                    456:     unsigned short *dst16;
                    457:     unsigned int *dst32;
                    458:     int x;
                    459:     // Screen-relative pixel coordinates of bounds of current character.
                    460:     int start_y = console->window_origin_y +
                    461:         console->curr_row * CHAR_H;
                    462:     int end_y   = start_y + CHAR_H;
                    463:     int start_x = console->window_origin_x +
                    464:         console->curr_column * CHAR_W;
                    465:     
                    466:     for (y=start_y; y<end_y; y++) {
                    467:        // I think it's quicker not to use Fill() here...
                    468:        switch (console->display.bitsPerPixel) {
                    469:            case IO_8BitsPerPixel:
                    470:                dst8 = (unsigned char *)PixelAddress(console, start_x, y);
                    471:                for (x=0; x < CHAR_W; x++) {
                    472:                    *dst8++ = console->background;
                    473:                }
                    474:                break;
                    475:            case IO_12BitsPerPixel:
                    476:            case IO_15BitsPerPixel:
                    477:                dst16 = (unsigned short *)PixelAddress(console, start_x, y);
                    478:                for (x=0; x < CHAR_W; x++) {
                    479:                    *dst16++ = console->background;
                    480:                }
                    481:                break;
                    482:            case IO_24BitsPerPixel:
                    483:                dst32 = (unsigned int *)PixelAddress(console, start_x, y);
                    484:                for (x=0; x < CHAR_W; x++) {
                    485:                    *dst32++ = console->background;
                    486:                }
                    487:                break;
                    488:                
                    489:            default:
                    490:                panic("FBConsole/Erase: bogus bits per pixel"); 
                    491:        }       
                    492:     }
                    493: }
                    494: 
                    495: extern unsigned char appleClut8[ 768 ];
                    496: 
                    497: static void Expand4ToN( ConsolePtr console, int x, int y, int width, int height,
                    498:                         unsigned char * dataPtr, unsigned char colors[ 16 ])
                    499: {
                    500:     unsigned char *dst;
                    501:     int line, col, bit = 4;
                    502:     unsigned int data, data8;
                    503: 
                    504:     dst = (unsigned char *) PixelAddress(console, x, y);
                    505:     for( line = 0; line < height; line++) {
                    506:         for( col = 0; col < width; col++, bit ^= 4) {
                    507:            if( bit)
                    508:                 data8 = *dataPtr++;
                    509:             data = colors[ (data8 >> bit) & 15];
                    510: 
                    511:             switch (console->display.bitsPerPixel) {
                    512:                 case IO_8BitsPerPixel:
                    513:                     if (console->display.colorSpace != IO_OneIsWhiteColorSpace)
                    514:                         *(dst + col) = data;
                    515:                    else {
                    516:                         data *= 3;
                    517:                         *(dst + col) = ((19595 * appleClut8[data] +
                    518:                                          38470 * appleClut8[data + 1] +
                    519:                                          7471  * appleClut8[data + 2] ) / 65536);
                    520: 
                    521:                    }
                    522:                     break;
                    523:                 case IO_24BitsPerPixel:
                    524:                     data *= 3;
                    525:                     *(((unsigned int *)dst) + col) = (appleClut8[data] << 16)
                    526:                                                     | (appleClut8[data + 1] << 8)
                    527:                                                     |  appleClut8[data + 2];
                    528:                     break;
                    529:                 case IO_15BitsPerPixel:
                    530:                     data *= 3;
                    531:                     *(((unsigned short *)dst) + col) = ( (0xf8 & (appleClut8[data])) << 7)
                    532:                                                             | ( (0xf8 & (appleClut8[data + 1])) << 2)
                    533:                                                             | ( (0xf8 & (appleClut8[data + 2])) >> 3);
                    534:                     break;
                    535:                 default:
                    536:                     break;
                    537:             }
                    538:         }
                    539:         dst = (unsigned char *) ((int)dst + console->display.rowBytes);
                    540:     }
                    541: }
                    542: 
                    543: 
                    544: 
                    545: 
                    546: static void DrawColorRect( ConsolePtr console, int x, int y, int width, int height, unsigned char * dataPtr)
                    547: {
                    548:     unsigned char *dst8;
                    549:     int line,col;
                    550:     unsigned int data;
                    551: 
                    552:     dst8 = (unsigned char *) PixelAddress(console, x, y);
                    553:     for( line = 0; line < height; line++) {
                    554:        for( col = 0; col < width; col++) {
                    555: 
                    556:            data = *dataPtr++;
                    557:            if( data != 0x01) {
                    558:                switch (console->display.bitsPerPixel) {
                    559:                    case IO_8BitsPerPixel:
                    560:                         if (console->display.colorSpace == IO_OneIsWhiteColorSpace) {
                    561:                             data *= 3;
                    562:                             *(dst8 + col) = ((19595 * appleClut8[data] +
                    563:                                               38470 * appleClut8[data + 1] +
                    564:                                               7471  * appleClut8[data + 2] ) / 65536);
                    565:                         } else {
                    566:                             *(dst8 + col) = data;
                    567:                        }
                    568:                         break;
                    569:                    case IO_24BitsPerPixel:
                    570:                        data *= 3;
                    571:                        *(((unsigned int *)dst8) + col) = (appleClut8[data] << 16)
                    572:                                                        | (appleClut8[data + 1] << 8)
                    573:                                                        |  appleClut8[data + 2];
                    574:                        break;
                    575:                    case IO_15BitsPerPixel:
                    576:                        data *= 3;
                    577:                        *(((unsigned short *)dst8) + col) = ( (0xf8 & (appleClut8[data])) << 7)
                    578:                                                          | ( (0xf8 & (appleClut8[data + 1])) << 2)
                    579:                                                          | ( (0xf8 & (appleClut8[data + 2])) >> 3);
                    580:                        break;
                    581:                    default:
                    582:                        break;
                    583:                }
                    584:            }
                    585:        }
                    586:        dst8 = (unsigned char *) ((int)dst8 + console->display.rowBytes);
                    587:     }
                    588: }
                    589: 
                    590: static void DrawIcon( ConsolePtr console)
                    591: {
                    592: 
                    593: #define ICON_WIDTH 11
                    594: #define ICON_HEIGHT 14
                    595: 
                    596:     static unsigned char iconData[ICON_WIDTH*ICON_HEIGHT] = {
                    597:        0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xE3,0xE5,0x01,0x01,
                    598:        0x01,0x01,0x01,0x01,0x01,0x01,0xE3,0xE5,0xE8,0x01,0x01,
                    599:        0x01,0x01,0x01,0x01,0x01,0x01,0xE5,0xE8,0x01,0x01,0x01,
                    600:        0x01,0x01,0xE3,0xE3,0xE5,0x01,0x01,0xE3,0xE3,0xE8,0x01,
                    601:        0x01,0xE5,0x6F,0x26,0xE3,0xE3,0xE3,0xE3,0xE5,0xE6,0xE8,
                    602:        0x10,0x05,0x01,0x05,0x05,0x0A,0x11,0x10,0x17,0x5E,0x01,
                    603:        0x10,0x00,0x05,0x05,0x0B,0x0A,0x11,0x10,0x5F,0x01,0x01,
                    604:        0x3B,0x00,0x08,0x11,0x11,0x17,0x3B,0x3B,0x65,0x01,0x01,
                    605:        0x3B,0x00,0x08,0x11,0x17,0x17,0x17,0x3B,0x65,0x65,0x01,
                    606:        0xD8,0x07,0x14,0xD8,0xD8,0xD8,0xD8,0xD9,0xD9,0xDB,0x8F,
                    607:        0x14,0x3E,0x06,0x14,0x20,0x20,0x20,0x3E,0x3E,0x62,0x8D,
                    608:        0x01,0x3E,0x3E,0x14,0x20,0x20,0x3E,0x3E,0x62,0x8D,0x8D,
                    609:        0x01,0x01,0xEE,0xA3,0xA3,0xEF,0xCE,0xA3,0xCE,0xEF,0x01,
                    610:        0x01,0x01,0x01,0xEF,0xEF,0x01,0x01,0xEF,0xEF,0x01,0x01
                    611:     };
                    612:     int x,y;                   // location of upper left corner of glyph
                    613: 
                    614:     x = console->window_origin_x + console->curr_column * CHAR_W - ICON_WIDTH - 7; // left: BG_MARGIN + FG_MARGIN + 2;
                    615:     y = console->window_origin_y + console->curr_row * CHAR_H - 4;
                    616: 
                    617:     DrawColorRect( console, x, y, ICON_WIDTH, ICON_HEIGHT, &iconData[0]);
                    618: }
                    619: 
                    620: /*
                    621:  * Expand a 1-bit PS bitmap, origin is lower left corner.
                    622:  */
                    623: #import "kmFontPriv.h"
                    624: 
                    625: void
                    626: BltPSBitmap(IOConsoleInfo *cso, int xpos, int ypos, bitmap_t *bmp,
                    627:        const unsigned char *bits, int grayValue)
                    628: {
                    629:         ConsolePtr console = (ConsolePtr)cso->priv;
                    630:         int x, y;
                    631:        int bitoffset;
                    632:         unsigned char *pixAddr;
                    633:        int fg;
                    634: 
                    635:         pixAddr = PixelAddress(console, (console->display.width / 2) + xpos + bmp->bbx.xoff,
                    636:                     ((console->display.height - 480) / 2) + ypos - bmp->bbx.yoff - bmp->bbx.height + 1);
                    637:         fg = console->grayTable[ grayValue & 3 ];
                    638: 
                    639:         /*
                    640:          * x and y are in fb coordinate system
                    641:          * xoff and yoff are in ps coordinate system
                    642:          */
                    643:         for (y = 0; y < bmp->bbx.height; y++)
                    644:         {
                    645:             for (x = 0; x < bmp->bbx.width; x++)
                    646:             {
                    647:                 bitoffset = bmp->bitx + y * bmp->bbx.width + x;
                    648:                 if( bits[bitoffset >> 3] & (0x80 >> (bitoffset & 0x7)))
                    649: 
                    650:                     switch (console->display.bitsPerPixel)
                    651:                    {
                    652:                         case IO_8BitsPerPixel:
                    653:                             ((unsigned char *)pixAddr)[ x ] = fg;
                    654:                             break;
                    655:                         case IO_12BitsPerPixel:
                    656:                         case IO_15BitsPerPixel:
                    657:                             ((unsigned short *)pixAddr)[ x ] = fg;
                    658:                             break;
                    659: 
                    660:                         case IO_24BitsPerPixel:
                    661:                             ((unsigned int *)pixAddr)[ x ] = fg;
                    662:                             break;
                    663:                     }
                    664:             }
                    665:             pixAddr += console->display.rowBytes;
                    666:         }
                    667: }
                    668: 
                    669: static void BltChar(ConsolePtr console, const char c)
                    670: // Description: Paint one character at (curr_column, curr_row).
                    671: {
                    672:     unsigned char *glyphbase;  // the glyph we're rendering
                    673:     unsigned char byte;
                    674:     unsigned char *pixAddr;
                    675:     int x,y;                   // location of upper left corner of glyph
                    676:     int source_y, bold;
                    677:     unsigned char *dst8, fg8;
                    678:     unsigned short *dst16, fg16;
                    679:     unsigned int *dst32, fg32;
                    680: 
                    681: 
                    682:     // Erase current contents of {curr_row, curr_column}.
                    683:     Erase(console);
                    684:     
                    685:     // Skip non-printing characters.
                    686:     if (c < ENCODEBASE) {
                    687:        return;
                    688:     }
                    689:     bold = console->bolding;
                    690:     x = console->window_origin_x + console->curr_column * CHAR_W;
                    691:     y = console->window_origin_y + console->curr_row * CHAR_H;
                    692: 
                    693:     do {
                    694:        glyphbase = ohlfs12[c - ENCODEBASE];
                    695:        pixAddr = PixelAddress(console, x + bold, y);
                    696:        switch (console->display.bitsPerPixel) {
                    697:        case IO_8BitsPerPixel:
                    698:            fg8 = (unsigned char) console->foreground;
                    699:                dst8 = (unsigned char *) pixAddr;
                    700:            for (source_y = CHAR_H; source_y != 0; source_y--) {
                    701:                byte = *glyphbase++;
                    702:                if (byte & 0x80) dst8[0] = fg8;
                    703:                if (byte & 0x40) dst8[1] = fg8;
                    704:                if (byte & 0x20) dst8[2] = fg8;
                    705:                if (byte & 0x10) dst8[3] = fg8;
                    706:                if (byte & 0x08) dst8[4] = fg8;
                    707:                if (byte & 0x04) dst8[5] = fg8;
                    708:                if (byte & 0x02) dst8[6] = fg8;
                    709:                if (byte & 0x01) dst8[7] = fg8;
                    710:                dst8 = (unsigned char *)
                    711:                                ((int)dst8 + console->display.rowBytes);
                    712:            }
                    713:            break;
                    714:        case IO_12BitsPerPixel:
                    715:        case IO_15BitsPerPixel:
                    716:            fg16 = (unsigned short) console->foreground;
                    717:                dst16 = (unsigned short *) pixAddr;
                    718:            for (source_y = CHAR_H; source_y != 0; source_y--) {
                    719:                byte = *glyphbase++;
                    720:                if (byte & 0x80) dst16[0] = fg16;
                    721:                if (byte & 0x40) dst16[1] = fg16;
                    722:                if (byte & 0x20) dst16[2] = fg16;
                    723:                if (byte & 0x10) dst16[3] = fg16;
                    724:                if (byte & 0x08) dst16[4] = fg16;
                    725:                if (byte & 0x04) dst16[5] = fg16;
                    726:                if (byte & 0x02) dst16[6] = fg16;
                    727:                if (byte & 0x01) dst16[7] = fg16;
                    728:                dst16 = (unsigned short *)
                    729:                                ((int)dst16 + console->display.rowBytes);
                    730:            }
                    731:            break;
                    732:        case IO_24BitsPerPixel:
                    733:            fg32 = (unsigned int) console->foreground;
                    734:                dst32 = (unsigned int *) pixAddr;
                    735:            for (source_y = CHAR_H; source_y != 0; source_y--) {
                    736:                byte = *glyphbase++;
                    737:                if (byte & 0x80) dst32[0] = fg32;
                    738:                if (byte & 0x40) dst32[1] = fg32;
                    739:                if (byte & 0x20) dst32[2] = fg32;
                    740:                if (byte & 0x10) dst32[3] = fg32;
                    741:                if (byte & 0x08) dst32[4] = fg32;
                    742:                if (byte & 0x04) dst32[5] = fg32;
                    743:                if (byte & 0x02) dst32[6] = fg32;
                    744:                if (byte & 0x01) dst32[7] = fg32;
                    745:                dst32 = (unsigned int *)
                    746:                                ((int)dst32 + console->display.rowBytes);
                    747:            }
                    748:            break;
                    749:        }
                    750:     } while( bold--);
                    751:     console->curr_column++;
                    752:     return;
                    753: }
                    754: 
                    755: extern void video_scroll_up(unsigned char * start, unsigned char * end, unsigned char * dest);
                    756: 
                    757: static void FBPutC(ConsolePtr console, char c)
                    758: // Write one character to screen. Cursor is 'on' on entry and exit.
                    759: {
                    760: int    repeat;
                    761: int    i;
                    762: 
                    763:        /*
                    764:         * First deal with ANSI escape sequences.
                    765:         * This is a very bizarre implementation, copied from the m68k
                    766:         * version. 
                    767:         */
                    768:        switch(console->ansi_state) {
                    769:            case AS_NORMAL:
                    770:                if(c == esc) {
                    771:                        console->ansi_state = AS_ESCAPE;
                    772:                        return;
                    773:                }
                    774:                else {
                    775:                        break;                          // continue
                    776:                }
                    777:                
                    778:            case AS_ESCAPE:
                    779:                switch(c) {
                    780:                    case '[':
                    781:                        console->ansi_state = AS_BRACKET;
                    782:                        return;
                    783:                    default:
                    784:                        console->ansi_state = AS_NORMAL;
                    785:                        break;                          // continue
                    786:                }
                    787:        
                    788:            case AS_BRACKET:
                    789:                if(c >= '0' && c <= '9') {
                    790:                        *console->ansi_stack_p = 
                    791:                                *console->ansi_stack_p * 10 + (c - '0');
                    792:                        return;
                    793:                } 
                    794:                else if (c == ';') {
                    795:                        if(console->ansi_stack_p < 
                    796:                            &console->ansi_stack[ANSI_STACK_SIZE]) {
                    797:                                console->ansi_stack_p++;
                    798:                        }
                    799:                        return;
                    800:                } 
                    801:                else {
                    802:                        for(i=0; i<ANSI_STACK_SIZE; i++) {
                    803:                                if (console->ansi_stack[i] == 0) {
                    804:                                        console->ansi_stack[i] = 1; 
                    805:                                }
                    806:                        }
                    807:                        repeat = *console->ansi_stack_p;
                    808:                        FlipCursor(console);            // cursor off
                    809:                        switch (c) {
                    810: 
                    811:                            case 'A':
                    812:                                while (repeat--) {
                    813:                                        if(console->curr_row) {
                    814:                                                console->curr_row--;
                    815:                                        }
                    816:                                }
                    817:                                break;
                    818: 
                    819:                            case 'B':
                    820:                                while (repeat--) {
                    821:                                        console->curr_row++;
                    822:                                }
                    823:                                break;
                    824: 
                    825:                            case 'C':           // non destructive space
                    826:                                while (repeat--) {
                    827:                                        console->curr_column++;
                    828:                                }
                    829:                                break;
                    830: 
                    831:                            case 'D':           // not in termcap
                    832:                                while (repeat--) {
                    833:                                        if(console->curr_column) {
                    834:                                                console->curr_column--;
                    835:                                        }
                    836:                                }
                    837:                                break;
                    838: 
                    839:                            case 'E':           // not in termcap
                    840:                                console->curr_column = 0;
                    841:                                while (repeat--) {
                    842:                                        console->curr_row++;
                    843:                                }
                    844:                                break;
                    845: 
                    846:                            case 'H':           // should be home
                    847:                            case 'f':           // not in termcap
                    848:                                console->curr_column = 
                    849:                                        *console->ansi_stack_p - 1;
                    850:                                console->ansi_stack_p--;
                    851:                                console->curr_row = 
                    852:                                        *console->ansi_stack_p - 1;
                    853:                                console->ansi_stack_p--;
                    854:                                break;
                    855: 
                    856:                            case 'K':
                    857:                                ClearToEOL(console);
                    858:                                break;
                    859:                                
                    860:                            case 'm': /* FIXME */
                    861:                                console->ansi_stack_p--;
                    862:                                console->ansi_stack_p--;
                    863:                                break;
                    864:                        }
                    865:                }
                    866:                console->ansi_stack_p = &console->ansi_stack[1];
                    867:                for(i=0; i<ANSI_STACK_SIZE; i++)
                    868:                        console->ansi_stack[i] = 0;
                    869:                console->ansi_state = AS_NORMAL;
                    870:                goto proceed;
                    871:        }
                    872: 
                    873:     FlipCursor(console);               // cursor off
                    874:     switch(c) {
                    875:        case '\r':                      // Carriage return
                    876:            console->curr_column = 0;
                    877:            break;      
                    878:            
                    879:        case '\n':                      // line feed
                    880:            console->curr_column = 0;
                    881:            console->curr_row++;
                    882:            break;
                    883:            
                    884:        case '\b':                      // backspace
                    885:            if (console->curr_column == 0)
                    886:                    break;
                    887:            console->curr_column--;
                    888:            break;
                    889:            
                    890:        case '\t':
                    891:            // tab. Erase all characters up to and including the 
                    892:            // next tab stop.
                    893:            {
                    894:            int col, num_cols;
                    895:            
                    896:            num_cols = TAB_SIZE - (console->curr_column % TAB_SIZE);
                    897:            FlipCursor(console);                        // cursor on
                    898:            for (col = 0; col<num_cols; col++) {
                    899:                FBPutC(console, ' ');                   // cursor on at return
                    900:            }
                    901:            FlipCursor(console);                        // cursor off
                    902:            break;
                    903:            }
                    904:            
                    905:        case np:                                // aka ff, form feed
                    906:            console->curr_row = console->curr_column = 0;
                    907:            ClearWindow(console);
                    908:            break;
                    909: 
                    910:        case del:
                    911:            console->curr_column++;
                    912:            break;
                    913:            
                    914:        default:
                    915:            // Normal case.
                    916:            BltChar(console, c);
                    917:            break;
                    918:     }
                    919:     
                    920:     // Cursor is off.
                    921: proceed:       
                    922:     if (console->curr_column >= console->chars_per_row) {
                    923:        // End-of-line wrap. 
                    924:        console->curr_column = 0;
                    925:        console->curr_row++;
                    926:     }
                    927:     
                    928:     if (console->curr_row >= console->chars_per_column) {
                    929:        //
                    930:        // Screen scroll. Copy the whole window down in memory 
                    931:        // (pixels_per_row * CHAR_H) pixels, starting at 
                    932:        // the first character in row 1.
                    933:        //
                    934:        unsigned char *src;     
                    935:        unsigned char *dst;
                    936:        int source_y;
                    937:        unsigned windowRowBytes;
                    938:        
                    939:        console->curr_row = console->chars_per_column - 1;
                    940:        switch (console->display.bitsPerPixel) {
                    941:            case IO_8BitsPerPixel:
                    942:                windowRowBytes = console->pixels_per_row;
                    943:                break;
                    944:            case IO_12BitsPerPixel:
                    945:            case IO_15BitsPerPixel:
                    946:                windowRowBytes = 2*console->pixels_per_row;
                    947:                break;
                    948:            case IO_24BitsPerPixel:
                    949:                windowRowBytes = 4*console->pixels_per_row;
                    950:                break;
                    951:            default:
                    952:                panic("FBConsole/FBPutC: bogus bitsPerPixel");  
                    953:        }
                    954: 
                    955:        // Copy one row at a time, moving each one up
                    956:        // CHAR_H rows. Within the loop, just increment
                    957:        // pixel pointers by one row's worth of pixels.
                    958:        // Source starts at the left top of row 1; destination 
                    959:        // starts at left top of row 0.
                    960:        //
                    961:        src = PixelAddress(console, 
                    962:            console->window_origin_x,
                    963:            console->window_origin_y + CHAR_H);
                    964:        dst  = PixelAddress(console,
                    965:                console->window_origin_x,
                    966:                console->window_origin_y);
                    967:        for (source_y = CHAR_H;         // top, row 1
                    968:            source_y < console->pixels_per_column;      // bottom
                    969:            source_y++) {
                    970: #ifndef        notDefUseFPU
                    971:            video_scroll_up( src, src + windowRowBytes, dst);
                    972: #else
                    973:            videoMemMove(dst, src, windowRowBytes);
                    974: #endif
                    975:            src += console->display.rowBytes;
                    976:            dst += console->display.rowBytes;
                    977:        }
                    978: 
                    979:        console->curr_column = 0;
                    980:        ClearToEOL(console);
                    981: }
                    982:     
                    983:     // Cursor back on.
                    984:     FlipCursor(console);
                    985: }
                    986: 
                    987: static void SetTitle(ConsolePtr console, const char *title)
                    988: // Description:        Draw title bar if none exists, write specified title into it.
                    989: //             Drawing a title bar involves snarfing up row 0 of the window
                    990: //             and decreasing the usable size of the window by one row.
                    991: // Preconditions:
                    992: // *   Cursor is 'on' on entry and will remain so on exit.
                    993: {
                    994:     int saved_curr_row = console->curr_row;
                    995:     int saved_curr_column = console->curr_column;
                    996:     int saved_origin_y;
                    997:     int title_len = strlen(title);
                    998:     int pixel_num;
                    999:     
                   1000:     if ((title_len == 0) || (title_len > console->chars_per_row)) {
                   1001:            IOLog("console: Illegal title length (%d)\n", title_len);
                   1002:            return;
                   1003:     }
                   1004:     FlipCursor(console);                       // old cursor off
                   1005:     if (console->has_title) {
                   1006:        // First grow window by two rows - this absorbs the existing 
                   1007:        // title bar.
                   1008:        console->window_origin_y -= CHAR_H * 2;
                   1009:        console->chars_per_column += 2;
                   1010:        console->pixels_per_column += CHAR_H * 2;
                   1011:        saved_curr_row += 2;
                   1012:     }
                   1013: 
                   1014:     // Clear row 0, center new title in it.
                   1015:     console->curr_row = 0;
                   1016:     Rect(console,
                   1017:        console->window_origin_x - (BG_MARGIN - TS_MARGIN),
                   1018:        console->window_origin_y - (BG_MARGIN - TS_MARGIN),
                   1019:        CHAR_W * console->chars_per_row + 2 * (BG_MARGIN - TS_MARGIN),
                   1020:        CHAR_H * 2 - TS_MARGIN,
                   1021:        console->light_grey);
                   1022:     saved_origin_y = console->window_origin_y;
                   1023:     console->window_origin_y += CHAR_H / 2;
                   1024:     console->curr_column = (console->chars_per_row - title_len) / 2;
                   1025:     DrawIcon(console);
                   1026: //     SwapForegroundAndBackground(console);
                   1027:     console->bolding = 1;
                   1028:     console->background = console->light_grey;
                   1029:     FlipCursor(console);                               // new cursor on        
                   1030:     while (*title) {
                   1031:        FBPutC(console, *title++);
                   1032:     }
                   1033:     FlipCursor(console);                       // new cursor off       
                   1034:     console->background = console->grayTable[0];
                   1035:     console->bolding = 0;
                   1036: //    SwapForegroundAndBackground(console);
                   1037:     console->window_origin_y = saved_origin_y;
                   1038:     
                   1039:     // Draw grey lines one pixel away from border of title bar.
                   1040:     // Origin is currently at first pixel in top line of title bar.
                   1041: 
                   1042:     Rect(console,                              // inside top
                   1043:        console->window_origin_x - BG_MARGIN,
                   1044:        console->window_origin_y - BG_MARGIN,
                   1045:        console->pixels_per_row + (BG_MARGIN * 2),
                   1046:        TS_MARGIN,
                   1047:        console->background);
                   1048:     Rect(console,                              // inside bottom
                   1049:        console->window_origin_x - BG_MARGIN,
                   1050:        console->window_origin_y + CHAR_H * 2 - TOTAL_MARGIN - TS_MARGIN,
                   1051:        console->pixels_per_row + BG_MARGIN * 2,
                   1052:        TS_MARGIN,
                   1053:        console->dark_grey);
                   1054:     for (pixel_num = 0; pixel_num < TS_MARGIN; pixel_num++) {
                   1055:         Rect(console,                          // left
                   1056:            console->window_origin_x - BG_MARGIN + pixel_num,
                   1057:            console->window_origin_y - BG_MARGIN + pixel_num,
                   1058:            1,
                   1059:            CHAR_H * 2 - 1 - (pixel_num * 2),
                   1060:            console->background);
                   1061:     }
                   1062:     for (pixel_num = 1 + BG_MARGIN - TS_MARGIN; pixel_num <= BG_MARGIN; pixel_num++) {
                   1063:         Rect(console,                          // right
                   1064:            console->window_origin_x + console->pixels_per_row + pixel_num - 1,
                   1065:            console->window_origin_y - pixel_num,
                   1066:            1,
                   1067:            CHAR_H * 2 - 1 - (BG_MARGIN - pixel_num) * 2,
                   1068:            console->dark_grey);
                   1069:     }
                   1070:     Rect(console,                              // outside bottom
                   1071:        console->window_origin_x - TOTAL_MARGIN,
                   1072:        console->window_origin_y + CHAR_H * 2 - FG_MARGIN - BG_MARGIN,
                   1073:        console->pixels_per_row + TOTAL_MARGIN * 2,
                   1074:        FG_MARGIN,
                   1075:        console->foreground);
                   1076:            
                   1077:     // Diminish window size by two rows.
                   1078:     console->window_origin_y += CHAR_H * 2;
                   1079:     console->chars_per_column -= 2;
                   1080:     console->pixels_per_column -= CHAR_H * 2;
                   1081:     
                   1082: 
                   1083:     // Restore old cursor. Careful, the y axis just changed...
                   1084:     console->curr_column = saved_curr_column;
                   1085:     if (saved_curr_row > 0) {
                   1086:        console->curr_row = saved_curr_row - 2;
                   1087:     } 
                   1088:     else {
                   1089:        // New row 0 - clear it.
                   1090:        ClearToEOL(console);
                   1091:     }
                   1092:     FlipCursor(console);                       // old cursor on
                   1093:     console->has_title = TRUE; 
                   1094: }
                   1095: 
                   1096: 
                   1097: static void UpdateWindowChars(ConsolePtr console)
                   1098: // Description:        Calculate window size in characters. Used when either window
                   1099: //             size or font changes.
                   1100: {
                   1101:     console->chars_per_row = console->pixels_per_row / CHAR_W;
                   1102:     console->chars_per_column =
                   1103:         console->pixels_per_column / CHAR_H;
                   1104: }
                   1105: 
                   1106: 
                   1107: 
                   1108: static void InitWindow(ConsolePtr console,
                   1109:        int             width,
                   1110:        int             height,
                   1111:        const char      *title,
                   1112:        boolean_t       initWindow,
                   1113:        boolean_t       saveUnder)
                   1114: // Description:        Initialize window parameters. If initWindow is TRUE, an empty
                   1115: //             window is drawn in the screen, else we assume that a window
                   1116: //             already  exists. Screen and font parameters must be valid on
                   1117: //             entry.
                   1118: {
                   1119:     // Truncate specified size to integral mutliple of character size
                   1120:     // in both dimensions.
                   1121:     width  /= CHAR_W;          // now in chars
                   1122:     height /= CHAR_H;
                   1123:     width  *= CHAR_W;          // now in pixels
                   1124:     height *= CHAR_H;
                   1125:     
                   1126:     // Ensure there's enough room for a border.
                   1127:     if (width > (console->display.width - HORIZ_BORDER - TOTAL_MARGIN * 2 - DROP_SHADOW))
                   1128:        width = console->display.width - HORIZ_BORDER - TOTAL_MARGIN * 2 - DROP_SHADOW;
                   1129:     if (height > (console->display.height - VERT_BORDER - TOTAL_MARGIN * 2 - DROP_SHADOW))
                   1130:        height = console->display.height - VERT_BORDER - TOTAL_MARGIN * 2 - DROP_SHADOW;
                   1131:     width &= 0xfffffffe;
                   1132:            
                   1133:     //
                   1134:     // Init console window variables. The window is centered in the 
                   1135:     // ! screen, minus a pixel or two to guarantee double word alignment
                   1136:     // ! for the first pixel of a row (until further developments...when 
                   1137:     // ! we do alert panels, we can enumerate some cases here...).
                   1138:     //
                   1139:     console->window_origin_x   = (console->display.width - width) / 2;
                   1140:     console->window_origin_y   = (console->display.height - height) / 2;
                   1141:     console->pixels_per_row    = width;
                   1142:     console->pixels_per_column = height;
                   1143:     (unsigned)console->window_origin_x &= 0xfffffffe;
                   1144: 
                   1145:     UpdateWindowChars(console);
                   1146:     
                   1147:     console->curr_column = 0;
                   1148:     console->has_title = FALSE;
                   1149:     
                   1150:     if (initWindow) {
                   1151:        // Before we start drawing anything, save under if needed
                   1152:        if (saveUnder) {
                   1153:            int i, bytesPerPixel = 0;
                   1154:            unsigned char *save, *sp;
                   1155: 
                   1156:            // Compute size of save under region in bytes and allocate
                   1157:            switch (console->display.bitsPerPixel) {
                   1158:                case IO_8BitsPerPixel:  bytesPerPixel = 1; break;
                   1159:                case IO_12BitsPerPixel:
                   1160:                case IO_15BitsPerPixel: bytesPerPixel = 2; break;
                   1161:                case IO_24BitsPerPixel: bytesPerPixel = 4; break;
                   1162:            }
                   1163:            console->saveHeight = height + TOTAL_MARGIN * 2 + DROP_SHADOW;
                   1164:            console->saveRowBytes = (width + TOTAL_MARGIN * 2 + DROP_SHADOW)*bytesPerPixel;
                   1165:            console->saveBytes = console->saveHeight*console->saveRowBytes;
                   1166:            save = console->saveBits = (unsigned char *)
                   1167:                                         kalloc_noblock(console->saveBytes);
                   1168:            sp = console->saveLocation = 
                   1169:                PixelAddress(console, console->window_origin_x - TOTAL_MARGIN, 
                   1170:                              console->window_origin_y - TOTAL_MARGIN);
                   1171: 
                   1172:            // Copy the window contents into the save under
                   1173:            if( save)
                   1174:                 for (i = console->saveHeight; i != 0; i--) {
                   1175:                     videoMemMove(save, sp, console->saveRowBytes);
                   1176:                     sp += console->display.rowBytes;
                   1177:                     save += console->saveRowBytes;
                   1178:                 }
                   1179:        }
                   1180:     
                   1181:        // New window - cursor at origin.
                   1182:        console->curr_row = 0;
                   1183:        console->has_title = FALSE;
                   1184:        
                   1185:        // Draw the border. The border goes outside of the specified
                   1186:        // window. Outside lines are black; inside lines are 
                   1187:        // half-tone.
                   1188:        Rect(console,                           // outside top
                   1189:            console->window_origin_x - TOTAL_MARGIN,
                   1190:            console->window_origin_y - TOTAL_MARGIN,
                   1191:            width + TOTAL_MARGIN * 2,
                   1192:            FG_MARGIN,
                   1193:            console->foreground);
                   1194:        Rect(console,                           // inside top
                   1195:            console->window_origin_x - BG_MARGIN,
                   1196:            console->window_origin_y - BG_MARGIN,
                   1197:            width + BG_MARGIN * 2,
                   1198:            BG_MARGIN,
                   1199:            console->background);
                   1200:        Rect(console,                           // inside bottom
                   1201:            console->window_origin_x - BG_MARGIN,
                   1202:            console->window_origin_y + height,
                   1203:            width + BG_MARGIN * 2,
                   1204:            BG_MARGIN,
                   1205:            console->background);
                   1206:        Rect(console,                           // outside bottom
                   1207:            console->window_origin_x - TOTAL_MARGIN,
                   1208:            console->window_origin_y + height + BG_MARGIN,
                   1209:            width + TOTAL_MARGIN * 2,
                   1210:            FG_MARGIN,
                   1211:            console->foreground);
                   1212:        if( DROP_SHADOW) Rect(console,                          // outside bottom shadow
                   1213:            console->window_origin_x - TOTAL_MARGIN + DROP_SHADOW,
                   1214:            console->window_origin_y + height + BG_MARGIN + DROP_SHADOW,
                   1215:            width + TOTAL_MARGIN * 2,
                   1216:            DROP_SHADOW,
                   1217:            console->dark_grey);
                   1218:        Rect(console,                           // outside left
                   1219:            console->window_origin_x - TOTAL_MARGIN,
                   1220:            console->window_origin_y - TOTAL_MARGIN,
                   1221:            FG_MARGIN,
                   1222:            height + TOTAL_MARGIN * 2,
                   1223:            console->foreground);
                   1224:        Rect(console,                           // inside left
                   1225:            console->window_origin_x - BG_MARGIN,
                   1226:            console->window_origin_y - BG_MARGIN,
                   1227:            BG_MARGIN,
                   1228:            height + BG_MARGIN * 2,
                   1229:            console->background);
                   1230:        Rect(console,                           // inside right
                   1231:            console->window_origin_x + width,
                   1232:            console->window_origin_y - BG_MARGIN,
                   1233:            BG_MARGIN,
                   1234:            height + BG_MARGIN * 2,
                   1235:            console->background);
                   1236:        Rect(console,                           // outside right
                   1237:            console->window_origin_x + width + BG_MARGIN,
                   1238:            console->window_origin_y - TOTAL_MARGIN,
                   1239:            FG_MARGIN,
                   1240:            height + TOTAL_MARGIN * 2,
                   1241:            console->foreground);
                   1242:        if( DROP_SHADOW) Rect(console,                          // outside right shadow
                   1243:            console->window_origin_x + width + BG_MARGIN + DROP_SHADOW,
                   1244:            console->window_origin_y - TOTAL_MARGIN + DROP_SHADOW,
                   1245:            DROP_SHADOW,
                   1246:            height + TOTAL_MARGIN * 2,
                   1247:            console->dark_grey);
                   1248:                
                   1249:        // Clear the contents of the window and draw a cursor.
                   1250:        ClearWindow(console);
                   1251:        FlipCursor(console);                    // cursor on
                   1252:        SetTitle(console, title);
                   1253:     }
                   1254:     else {
                   1255:            /* Leave current window contents, just updating title. 
                   1256:             * We'll do a newline to make sure we have room for 
                   1257:             * our font and proceed.Initial cursor will be at 
                   1258:             * lower left corner.
                   1259:             */
                   1260:            console->curr_row = console->chars_per_column - 1;
                   1261:            SetTitle(console, title);
                   1262:            FBPutC(console, '\n');
                   1263:     }
                   1264:     return;
                   1265: }
                   1266: 
                   1267: //
                   1268: // END:                Private utility routines
                   1269: //
                   1270: 
                   1271: //
                   1272: // BEGIN:      Implementation of IOConsoleInfo functions
                   1273: //
                   1274: static void Free(IOConsoleInfo *cso)
                   1275: // Description: Free a FB Console object
                   1276: {
                   1277:     IOFree(cso->priv, sizeof(ConsoleRep));
                   1278:     IOFree(cso, sizeof(IOConsoleInfo));
                   1279: }
                   1280: 
                   1281: static void Init(
                   1282:     IOConsoleInfo *cso,
                   1283:     ScreenMode mode,
                   1284:     boolean_t initScreenOrSaveUnder,
                   1285:     boolean_t initWindow,
                   1286:     const char *title)
                   1287: {
                   1288:     ConsolePtr console = (ConsolePtr)cso->priv;
                   1289:     int i;
                   1290:        
                   1291:     switch (console->display.bitsPerPixel) {
                   1292:         case IO_8BitsPerPixel:
                   1293:            if (console->display.colorSpace == IO_OneIsWhiteColorSpace) {
                   1294:                console->baseground = (TRUE || (mode == SCM_GRAPHIC)) ? 107 : 0x55;
                   1295:                console->background = 0xff;
                   1296:                console->foreground = 0x00;
                   1297:                console->dark_grey  = 85;
                   1298:                console->light_grey = 187;
                   1299:            } else {
                   1300:                console->baseground = (TRUE || (mode == SCM_GRAPHIC)) ? 0x80 : 0x7e;
                   1301:                console->background = 0x00;
                   1302:                console->foreground = 0xff;
                   1303:                console->dark_grey  = 0xfb;
                   1304:                console->light_grey = 0xf7;
                   1305:            }
                   1306:            break;
                   1307:        case IO_15BitsPerPixel:
                   1308:            console->baseground = (TRUE || (mode == SCM_GRAPHIC)) ? 0x3193 : 0x295f;
                   1309:            console->background = 0x7fff;
                   1310:            console->foreground = 0x0000;
                   1311:            console->dark_grey  = 0x294a;
                   1312:            console->light_grey = 0x5ef7;
                   1313:            break;
                   1314:        case IO_24BitsPerPixel:
                   1315:            console->baseground = (TRUE || (mode == SCM_GRAPHIC)) ? 0xff666699 : 0xff5555ff;
                   1316:            console->background = 0xffffffff;
                   1317:            console->foreground = 0xff000000;
                   1318:            console->dark_grey  = 0xff555555;
                   1319:            console->light_grey = 0xffbbbbbb;
                   1320:            break;
                   1321:     }
                   1322: 
                   1323:     console->grayTable[0] = console->background;
                   1324:     console->grayTable[1] = console->light_grey;
                   1325:     console->grayTable[2] = console->dark_grey;
                   1326:     console->grayTable[3] = console->foreground;
                   1327: 
                   1328:     console->ansi_state = AS_NORMAL;
                   1329:     for(i=0; i<ANSI_STACK_SIZE; i++) {
                   1330:                console->ansi_stack[i] = 0;
                   1331:        }
                   1332:     console->ansi_stack_p = &console->ansi_stack[1];   // FIXME - why not 0?
                   1333: 
                   1334:     // Initialize the screen, if appropriate.
                   1335:     if (initScreenOrSaveUnder && (mode != SCM_ALERT)) {
                   1336:        WipeScreen(console, console->baseground);
                   1337:     }
                   1338: 
                   1339:     console->window_type = mode;
                   1340:     switch(console->window_type) {
                   1341:        case SCM_TEXT:
                   1342:            InitWindow(console, TEXT_WIN_WIDTH, TEXT_WIN_HEIGHT,
                   1343:                title, initWindow, 0 /* Don't save under */);
                   1344:            break;
                   1345:        case SCM_ALERT:
                   1346:            InitWindow(console, ALERT_WIN_WIDTH, ALERT_WIN_HEIGHT,
                   1347:                title, initWindow, initScreenOrSaveUnder );
                   1348:            break;
                   1349:        case SCM_GRAPHIC:
                   1350:            if( initScreenOrSaveUnder) {
                   1351:                int cx, cy;
                   1352: 
                   1353:                 cx = console->display.width / 2;
                   1354:                 cy = console->display.height / 2;
                   1355:                 Expand4ToN( console, cx + RIGHT_DX, cy + RIGHT_DY,
                   1356:                        RIGHT_WIDTH, RIGHT_HEIGHT, rightData, rightBotColors );
                   1357:                 Expand4ToN( console, cx + CENTER_DX, cy + CENTER_DY,
                   1358:                        CENTER_WIDTH, CENTER_HEIGHT, centerData, centerColors );
                   1359:                 Expand4ToN( console, cx + BOTTOM_DX, cy + BOTTOM_DY,
                   1360:                        BOTTOM_WIDTH, BOTTOM_HEIGHT, bottomData, rightBotColors );
                   1361:            }
                   1362:            break;
                   1363: 
                   1364:        default:
                   1365:            panic("FBConsole/FBInitConsole: can't init");
                   1366:            break;
                   1367:     }
                   1368:     return;
                   1369: }
                   1370: 
                   1371: static int Restore(IOConsoleInfo *cso)
                   1372: {
                   1373:     ConsolePtr console = (ConsolePtr)cso->priv;
                   1374:     unsigned char *save, *dp;
                   1375:     int i;
                   1376: 
                   1377:     if (console->window_type != SCM_ALERT) {
                   1378:        IOLog("frameBuffer: bogus restore, mode %d\n", console->window_type);
                   1379:        return -1;
                   1380:     }
                   1381: 
                   1382:     // Copy save under bits back onto screen
                   1383:     save = console->saveBits;
                   1384:     dp = console->saveLocation;
                   1385:     if( save) {
                   1386:         for (i = console->saveHeight; i != 0; i--) {
                   1387:             videoMemMove(dp, save, console->saveRowBytes);
                   1388:             dp += console->display.rowBytes;
                   1389:             save += console->saveRowBytes;
                   1390:         }
                   1391: 
                   1392:         // Free bits
                   1393:         kfree(console->saveBits, console->saveBytes);
                   1394:        console->saveBits = 0;
                   1395:     }
                   1396:     return 0;
                   1397: }
                   1398: 
                   1399: #define        VIDEO_W 640
                   1400: #define        VIDEO_H 480
                   1401: 
                   1402: static int DrawRect(IOConsoleInfo *cso,  const struct km_drawrect *km_rect)
                   1403: // Description:        Given a 2 bit raster, convert it to the format appropriate for
                   1404: //             the display. The co-ordinates passed in by these ioctls assume
                   1405: //             an (VIDEO_W x VIDEO_H) screen. All screen sizes are
                   1406: //             assumed to share a common center point. We scale the X and Y
                   1407: //             values to maintain a constant offset from the center point,
                   1408: //             so that boot animations, popup windows, and related goodies
                   1409: //             don't break with screens larger or smaller than the 'default'
                   1410: //             screen.
                   1411: // Preconditions:
                   1412: // * The rectangle that we are to draw must start on a 4 pixel boundary
                   1413: //   and should be a multiple of 4 pixels in width.
                   1414: {
                   1415:     ConsolePtr console = (ConsolePtr)cso->priv;
                   1416:     int pixel;         /* Starting pixel in screen */
                   1417:     int i, x, y;
                   1418:     unsigned char *data;
                   1419:     unsigned char value;
                   1420:     unsigned int * table;
                   1421:     struct km_drawrect *rect = (struct km_drawrect *) km_rect;
                   1422:     int bgX, bgY, bgH;
                   1423:     unsigned char * bg;
                   1424: 
                   1425:     table = console->grayTable;
                   1426: 
                   1427:     /* copyin is done in km */
                   1428:     data = rect->data.bits;
                   1429: 
                   1430:     x = (rect->x & 0x1ffc) + (console->display.width - VIDEO_W)/2;
                   1431:     y = rect->y + (console->display.height - VIDEO_H)/2;
                   1432: 
                   1433:     /* Correct the x and y values for screen size */
                   1434:     if( (rect->x & 3) == 3) {
                   1435:        DrawColorRect( console, x, y, rect->width, rect->height, data);
                   1436:        return 0;
                   1437:     }
                   1438: 
                   1439: #if TEXTURE_BACKGND
                   1440:     bgX = console->display.width / 2 + CENTER_DX;
                   1441:     bgY = console->display.height / 2 + CENTER_DY;
                   1442: 
                   1443:     bgH = (y - bgY) & -2;
                   1444:     if( bgH > 0) {
                   1445:         bgY += bgH;
                   1446:         bg = centerData + (bgH * CENTER_WIDTH) / 2;
                   1447:         bgH = CENTER_HEIGHT - bgH;
                   1448:     } else
                   1449:        bg = (unsigned char *)0;
                   1450: #endif
                   1451: 
                   1452:     rect->x &= 0x1ffc;
                   1453: 
                   1454:     /* Sanity check */
                   1455:     if ((x + rect->width > console->display.width)
                   1456:     || (y + rect->height) > console->display.height)
                   1457:        return( -1 );
                   1458: 
                   1459: 
                   1460:     pixel = x + (y * console->display.totalWidth);
                   1461: 
                   1462:     switch ( console->display.bitsPerPixel )
                   1463:     {
                   1464:        case IO_2BitsPerPixel:  /* 2 bit pixels */
                   1465:        {
                   1466:            unsigned char *dst = (unsigned char *)console->display.frameBuffer;
                   1467:            unsigned char *fb;
                   1468:            unsigned char final_value;
                   1469:            
                   1470:            dst += pixel >> 2;
                   1471:            for ( y = 0; y < rect->height; ++y ) {
                   1472:                fb = dst;
                   1473:                for ( x = 0; x < rect->width; x += 4) {
                   1474:                        value = *data++;
                   1475:                        final_value = 0;
                   1476:                        for ( i = 0; i < 8; i += 2 ) {
                   1477:                            final_value |= ((table[(value>>i)&3] & 3) << i);
                   1478:                        }
                   1479:                        *fb++ = final_value;
                   1480:                }
                   1481:                dst += console->display.rowBytes;
                   1482:            }
                   1483:            break;
                   1484:        }
                   1485:        case IO_8BitsPerPixel:  /* 8 bit pixels */
                   1486:        {
                   1487:            unsigned char *dst = (unsigned char *)console->display.frameBuffer;
                   1488:            unsigned char *fb;
                   1489: 
                   1490:            dst += pixel;
                   1491:            for ( y = 0; y < rect->height; ++y ) {
                   1492:                fb = dst;
                   1493: #if TEXTURE_BACKGND
                   1494:                if( ((y & 1) == 0) && bg) {
                   1495:                     Expand4ToN( console, bgX, bgY,
                   1496:                             CENTER_WIDTH, 2, bg, centerColors );
                   1497:                     bgY += 2;
                   1498:                     bg += CENTER_WIDTH;
                   1499:                }
                   1500: #endif
                   1501:                for ( x = 0; x < rect->width; x += 4) {
                   1502:                     value = *data++;
                   1503:                     if( value) {
                   1504:                     int pix;
                   1505:                         pix = (value >> 6) & 3;
                   1506:                         if( pix)
                   1507:                             fb[0] = table[pix];
                   1508:                         pix = (value >> 4) & 3;
                   1509:                         if( pix)
                   1510:                             fb[1] = table[pix];
                   1511:                         pix = (value >> 2) & 3;
                   1512:                         if( pix)
                   1513:                             fb[2] = table[pix];
                   1514:                         pix = value & 3;
                   1515:                         if( pix)
                   1516:                             fb[3] = table[pix];
                   1517:                     }
                   1518:                     fb += 4;
                   1519:                }
                   1520:                dst += console->display.rowBytes;
                   1521:            }           
                   1522:            break;
                   1523:        }
                   1524:        case IO_12BitsPerPixel: /* 16 bit pixels */
                   1525:        case IO_15BitsPerPixel: /* 16 bit pixels */
                   1526:        {
                   1527: 
                   1528:            unsigned short *dst = (unsigned short *)console->display.frameBuffer;
                   1529:            unsigned short *fb;
                   1530:            dst += pixel;
                   1531: 
                   1532:            for ( y = 0; y < rect->height; ++y ) {
                   1533:                fb = dst;
                   1534: #if TEXTURE_BACKGND
                   1535:                if( ((y & 1) == 0) && bg) {
                   1536:                     Expand4ToN( console, bgX, bgY,
                   1537:                             CENTER_WIDTH, 2, bg, centerColors );
                   1538:                     bgY += 2;
                   1539:                     bg += CENTER_WIDTH;
                   1540:                }
                   1541: #endif
                   1542:                for ( x = 0; x < rect->width; x += 4) {
                   1543:                     value = *data++;
                   1544:                     if( value) {
                   1545:                     int pix;
                   1546:                         pix = (value >> 6) & 3;
                   1547:                         if( pix)
                   1548:                             fb[0] = table[pix];
                   1549:                         pix = (value >> 4) & 3;
                   1550:                         if( pix)
                   1551:                             fb[1] = table[pix];
                   1552:                         pix = (value >> 2) & 3;
                   1553:                         if( pix)
                   1554:                             fb[2] = table[pix];
                   1555:                         pix = value & 3;
                   1556:                         if( pix)
                   1557:                             fb[3] = table[pix];
                   1558:                     }
                   1559:                     fb += 4;
                   1560:                }
                   1561:                dst = (unsigned short *)(((char*)dst) +
                   1562:                    console->display.rowBytes);
                   1563:            }           
                   1564:            break;
                   1565:        }
                   1566:        case IO_24BitsPerPixel: /* 32 bit pixels */
                   1567:        {
                   1568:            unsigned int *dst = (unsigned int *) console->display.frameBuffer;
                   1569:            unsigned int *fb;
                   1570: 
                   1571:            dst += pixel;
                   1572:            for ( y = 0; y < rect->height; ++y ) {
                   1573:                fb = dst;
                   1574: #if TEXTURE_BACKGND
                   1575:                if( ((y & 1) == 0) && bg) {
                   1576:                     Expand4ToN( console, bgX, bgY,
                   1577:                             CENTER_WIDTH, 2, bg, centerColors );
                   1578:                     bgY += 2;
                   1579:                     bg += CENTER_WIDTH;
                   1580:                }
                   1581: #endif
                   1582:                for ( x = 0; x < rect->width; x += 4) {
                   1583:                     value = *data++;
                   1584:                     if( value) {
                   1585:                     int pix;
                   1586:                         pix = (value >> 6) & 3;
                   1587:                         if( pix)
                   1588:                             fb[0] = table[pix];
                   1589:                         pix = (value >> 4) & 3;
                   1590:                         if( pix)
                   1591:                             fb[1] = table[pix];
                   1592:                         pix = (value >> 2) & 3;
                   1593:                         if( pix)
                   1594:                             fb[2] = table[pix];
                   1595:                         pix = value & 3;
                   1596:                         if( pix)
                   1597:                             fb[3] = table[pix];
                   1598:                     }
                   1599:                     fb += 4;
                   1600:                }
                   1601:                dst = (unsigned int *)(((char*)dst) +
                   1602:                    console->display.rowBytes);
                   1603:            }           
                   1604:            break;
                   1605:        }
                   1606:     }
                   1607:     return 0;
                   1608: }
                   1609: 
                   1610: static int EraseRect(IOConsoleInfo *cso,  const struct km_drawrect *km_rect)
                   1611: // Description:        Erase the specified rectangle to the color specified
                   1612: //             in the km_rect structure.
                   1613: // Preconditions:
                   1614: // * The rectangle that we are to erase must start on a 4 pixel boundary
                   1615: //   and should be a multiple of 4 pixels in width.
                   1616: {
                   1617:     ConsolePtr console = (ConsolePtr)cso->priv;
                   1618:     int pixel;         // Starting pixel in screen
                   1619:     int x, y, w, h;
                   1620:     unsigned int value;
                   1621:     struct km_drawrect *rect = (struct km_drawrect *) km_rect;
                   1622:     int bgX, bgY, bgH;
                   1623:     unsigned char * bg;
                   1624: 
                   1625:     value = console->grayTable[ rect->data.fill & 3 ];
                   1626: 
                   1627:     /* Correct the x and y values for screen size */
                   1628:     x = rect->x + (console->display.width - VIDEO_W)/2;
                   1629:     y = rect->y + (console->display.height - VIDEO_H)/2;
                   1630: 
                   1631:     x &= ~3;                           // Trunc to 4 pixel boundary
                   1632:     w = (rect->width) & ~3;            // Round dn to 4 pixel boundary
                   1633:     h = rect->height;
                   1634: 
                   1635:     /* Sanity check */
                   1636:     /* Sanity check */
                   1637:     if (((x + w) > console->display.width)
                   1638:     ||  ((y + h) > console->display.height) )
                   1639:        return( -1 );
                   1640: 
                   1641: 
                   1642: #if TEXTURE_BACKGND
                   1643:     bgX = console->display.width / 2 + CENTER_DX;
                   1644:     bgY = console->display.height / 2 + CENTER_DY;
                   1645: 
                   1646:     bgH = (y - bgY) & -2;
                   1647:     if( bgH > 0) {
                   1648:         bgY += bgH;
                   1649:         bg = centerData + (bgH * CENTER_WIDTH) / 2;
                   1650:         bgH = CENTER_HEIGHT - bgH;
                   1651:         Expand4ToN( console, bgX, bgY,
                   1652:                 CENTER_WIDTH, bgH, bg, centerColors );
                   1653:     }
                   1654: 
                   1655: #else
                   1656:     Rect( console, x, y, w, h, value);
                   1657: #endif
                   1658: 
                   1659:     return 0;
                   1660: }
                   1661: 
                   1662: //extern void czputc( char c);
                   1663: 
                   1664: static void PutC(IOConsoleInfo *cso, char c)
                   1665: // Write one character to screen. Cursor is 'on' on entry and exit.
                   1666: {
                   1667:     FBPutC((ConsolePtr)cso->priv, c);
                   1668: //    czputc(c);
                   1669: }
                   1670: 
                   1671: static void GetSize(IOConsoleInfo *cso, struct ConsoleSize *s)
                   1672: // Return the size of the screen in pixels
                   1673: {
                   1674:     ConsolePtr console = (ConsolePtr)cso->priv;
                   1675:     s->cols = console->chars_per_row;
                   1676:     s->rows = console->chars_per_column;
                   1677:     s->pixel_width = console->display.width;
                   1678:     s->pixel_height = console->display.height;
                   1679: }
                   1680: 
                   1681: //
                   1682: // END:                Implementation of IOConsoleInfo functions
                   1683: //
                   1684: 
                   1685: static IOConsoleInfo staticConsoleInfo;
                   1686: static ConsoleRep staticConsoleRep;
                   1687: 
                   1688: static void InitializeConsole( IOConsoleInfo *cso, IODisplayInfo *display )
                   1689: {
                   1690:     cso->Init = Init;
                   1691:     cso->Restore = Restore;
                   1692:     cso->DrawRect = DrawRect;
                   1693:     cso->EraseRect = EraseRect;
                   1694:     cso->PutC = PutC;
                   1695:     cso->GetSize = GetSize;
                   1696:     ((ConsolePtr)cso->priv)->display = *display;
                   1697:     ((ConsolePtr)cso->priv)->window_type = SCM_UNINIT;
                   1698:     return;
                   1699: }
                   1700: 
                   1701: //
                   1702: // BEGIN:      Exported routines
                   1703: //
                   1704: 
                   1705: static void DoNothing(IOConsoleInfo *cso)
                   1706: {
                   1707: }
                   1708: 
                   1709: IOConsoleInfo *BasicAllocateConsole(IODisplayInfo *display)
                   1710: {
                   1711: // No memory allocation. Assume non backed window.
                   1712:     IOConsoleInfo *cso = &staticConsoleInfo;
                   1713:     cso->priv = (void *)&staticConsoleRep;
                   1714:     InitializeConsole(cso, display);
                   1715:     cso->Free = DoNothing;
                   1716: #if 0
                   1717:     printf("base:%x rowBytes:%x width:%x height:%x\n",display->frameBuffer,
                   1718:                display->rowBytes, display->width, display->height);
                   1719: #endif
                   1720:     return cso;
                   1721: }
                   1722: 
                   1723: 
                   1724: IOConsoleInfo *FBAllocateConsole(IODisplayInfo *display)
                   1725: {
                   1726:    IOConsoleInfo *cso = (IOConsoleInfo *)IOMalloc(sizeof(IOConsoleInfo));
                   1727:     
                   1728:     if (cso == NIL)
                   1729:         return NIL;
                   1730:     cso->priv = (void *)IOMalloc(sizeof(ConsoleRep));
                   1731:     if (cso->priv == NIL)
                   1732:     {
                   1733:         IOFree(cso, sizeof(IOConsoleInfo));
                   1734:        return NIL;
                   1735:     }
                   1736:     InitializeConsole(cso, display);
                   1737:     cso->Free = Free;
                   1738:    return cso;
                   1739: }
                   1740: 
                   1741: 
                   1742: //
                   1743: // END:                Exported routines
                   1744: //

unix.superglobalmegacorp.com

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