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

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: 
1.1.1.2 ! root      497: static void Expand4Or8ToN( ConsolePtr console, int x, int y, int width, int height,
        !           498:                         unsigned char * dataPtr, unsigned char * map16)
1.1       root      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) {
1.1.1.2 ! root      507:            if( map16) {
        !           508:                if( bit)
        !           509:                     data8 = *dataPtr++;
        !           510:                 data = map16[ (data8 >> bit) & 15];
        !           511:             } else {
        !           512:                 data = data8 = *dataPtr++;
        !           513:             }
1.1       root      514:             switch (console->display.bitsPerPixel) {
                    515:                 case IO_8BitsPerPixel:
                    516:                     if (console->display.colorSpace != IO_OneIsWhiteColorSpace)
                    517:                         *(dst + col) = data;
                    518:                    else {
                    519:                         data *= 3;
                    520:                         *(dst + col) = ((19595 * appleClut8[data] +
                    521:                                          38470 * appleClut8[data + 1] +
                    522:                                          7471  * appleClut8[data + 2] ) / 65536);
                    523: 
                    524:                    }
                    525:                     break;
                    526:                 case IO_24BitsPerPixel:
                    527:                     data *= 3;
                    528:                     *(((unsigned int *)dst) + col) = (appleClut8[data] << 16)
                    529:                                                     | (appleClut8[data + 1] << 8)
                    530:                                                     |  appleClut8[data + 2];
                    531:                     break;
                    532:                 case IO_15BitsPerPixel:
                    533:                     data *= 3;
                    534:                     *(((unsigned short *)dst) + col) = ( (0xf8 & (appleClut8[data])) << 7)
                    535:                                                             | ( (0xf8 & (appleClut8[data + 1])) << 2)
                    536:                                                             | ( (0xf8 & (appleClut8[data + 2])) >> 3);
                    537:                     break;
                    538:                 default:
                    539:                     break;
                    540:             }
                    541:         }
                    542:         dst = (unsigned char *) ((int)dst + console->display.rowBytes);
                    543:     }
                    544: }
                    545: 
1.1.1.2 ! root      546: static void Expand4ToN( ConsolePtr console, int x, int y, int width, int height,
        !           547:                         unsigned char * dataPtr, unsigned char * map16)
        !           548: {
        !           549:     Expand4Or8ToN(console, x, y, width, height, dataPtr, map16);
        !           550: }
1.1       root      551: 
1.1.1.2 ! root      552: static void Expand8ToN( ConsolePtr console, int x, int y, int width, int height,
        !           553:                         unsigned char * dataPtr)
        !           554: {
        !           555:     Expand4Or8ToN(console, x, y, width, height, dataPtr, 0);
        !           556: }
1.1       root      557: 
                    558: static void DrawColorRect( ConsolePtr console, int x, int y, int width, int height, unsigned char * dataPtr)
                    559: {
                    560:     unsigned char *dst8;
                    561:     int line,col;
                    562:     unsigned int data;
                    563: 
                    564:     dst8 = (unsigned char *) PixelAddress(console, x, y);
                    565:     for( line = 0; line < height; line++) {
                    566:        for( col = 0; col < width; col++) {
                    567: 
                    568:            data = *dataPtr++;
                    569:            if( data != 0x01) {
                    570:                switch (console->display.bitsPerPixel) {
                    571:                    case IO_8BitsPerPixel:
                    572:                         if (console->display.colorSpace == IO_OneIsWhiteColorSpace) {
                    573:                             data *= 3;
                    574:                             *(dst8 + col) = ((19595 * appleClut8[data] +
                    575:                                               38470 * appleClut8[data + 1] +
                    576:                                               7471  * appleClut8[data + 2] ) / 65536);
                    577:                         } else {
                    578:                             *(dst8 + col) = data;
                    579:                        }
                    580:                         break;
                    581:                    case IO_24BitsPerPixel:
                    582:                        data *= 3;
                    583:                        *(((unsigned int *)dst8) + col) = (appleClut8[data] << 16)
                    584:                                                        | (appleClut8[data + 1] << 8)
                    585:                                                        |  appleClut8[data + 2];
                    586:                        break;
                    587:                    case IO_15BitsPerPixel:
                    588:                        data *= 3;
                    589:                        *(((unsigned short *)dst8) + col) = ( (0xf8 & (appleClut8[data])) << 7)
                    590:                                                          | ( (0xf8 & (appleClut8[data + 1])) << 2)
                    591:                                                          | ( (0xf8 & (appleClut8[data + 2])) >> 3);
                    592:                        break;
                    593:                    default:
                    594:                        break;
                    595:                }
                    596:            }
                    597:        }
                    598:        dst8 = (unsigned char *) ((int)dst8 + console->display.rowBytes);
                    599:     }
                    600: }
                    601: 
                    602: static void DrawIcon( ConsolePtr console)
                    603: {
                    604: 
                    605: #define ICON_WIDTH 11
                    606: #define ICON_HEIGHT 14
                    607: 
                    608:     static unsigned char iconData[ICON_WIDTH*ICON_HEIGHT] = {
                    609:        0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xE3,0xE5,0x01,0x01,
                    610:        0x01,0x01,0x01,0x01,0x01,0x01,0xE3,0xE5,0xE8,0x01,0x01,
                    611:        0x01,0x01,0x01,0x01,0x01,0x01,0xE5,0xE8,0x01,0x01,0x01,
                    612:        0x01,0x01,0xE3,0xE3,0xE5,0x01,0x01,0xE3,0xE3,0xE8,0x01,
                    613:        0x01,0xE5,0x6F,0x26,0xE3,0xE3,0xE3,0xE3,0xE5,0xE6,0xE8,
                    614:        0x10,0x05,0x01,0x05,0x05,0x0A,0x11,0x10,0x17,0x5E,0x01,
                    615:        0x10,0x00,0x05,0x05,0x0B,0x0A,0x11,0x10,0x5F,0x01,0x01,
                    616:        0x3B,0x00,0x08,0x11,0x11,0x17,0x3B,0x3B,0x65,0x01,0x01,
                    617:        0x3B,0x00,0x08,0x11,0x17,0x17,0x17,0x3B,0x65,0x65,0x01,
                    618:        0xD8,0x07,0x14,0xD8,0xD8,0xD8,0xD8,0xD9,0xD9,0xDB,0x8F,
                    619:        0x14,0x3E,0x06,0x14,0x20,0x20,0x20,0x3E,0x3E,0x62,0x8D,
                    620:        0x01,0x3E,0x3E,0x14,0x20,0x20,0x3E,0x3E,0x62,0x8D,0x8D,
                    621:        0x01,0x01,0xEE,0xA3,0xA3,0xEF,0xCE,0xA3,0xCE,0xEF,0x01,
                    622:        0x01,0x01,0x01,0xEF,0xEF,0x01,0x01,0xEF,0xEF,0x01,0x01
                    623:     };
                    624:     int x,y;                   // location of upper left corner of glyph
                    625: 
                    626:     x = console->window_origin_x + console->curr_column * CHAR_W - ICON_WIDTH - 7; // left: BG_MARGIN + FG_MARGIN + 2;
                    627:     y = console->window_origin_y + console->curr_row * CHAR_H - 4;
                    628: 
                    629:     DrawColorRect( console, x, y, ICON_WIDTH, ICON_HEIGHT, &iconData[0]);
                    630: }
                    631: 
                    632: /*
                    633:  * Expand a 1-bit PS bitmap, origin is lower left corner.
                    634:  */
                    635: #import "kmFontPriv.h"
                    636: 
                    637: void
                    638: BltPSBitmap(IOConsoleInfo *cso, int xpos, int ypos, bitmap_t *bmp,
                    639:        const unsigned char *bits, int grayValue)
                    640: {
                    641:         ConsolePtr console = (ConsolePtr)cso->priv;
                    642:         int x, y;
                    643:        int bitoffset;
                    644:         unsigned char *pixAddr;
                    645:        int fg;
                    646: 
                    647:         pixAddr = PixelAddress(console, (console->display.width / 2) + xpos + bmp->bbx.xoff,
                    648:                     ((console->display.height - 480) / 2) + ypos - bmp->bbx.yoff - bmp->bbx.height + 1);
                    649:         fg = console->grayTable[ grayValue & 3 ];
                    650: 
                    651:         /*
                    652:          * x and y are in fb coordinate system
                    653:          * xoff and yoff are in ps coordinate system
                    654:          */
                    655:         for (y = 0; y < bmp->bbx.height; y++)
                    656:         {
                    657:             for (x = 0; x < bmp->bbx.width; x++)
                    658:             {
                    659:                 bitoffset = bmp->bitx + y * bmp->bbx.width + x;
                    660:                 if( bits[bitoffset >> 3] & (0x80 >> (bitoffset & 0x7)))
                    661: 
                    662:                     switch (console->display.bitsPerPixel)
                    663:                    {
                    664:                         case IO_8BitsPerPixel:
                    665:                             ((unsigned char *)pixAddr)[ x ] = fg;
                    666:                             break;
                    667:                         case IO_12BitsPerPixel:
                    668:                         case IO_15BitsPerPixel:
                    669:                             ((unsigned short *)pixAddr)[ x ] = fg;
                    670:                             break;
                    671: 
                    672:                         case IO_24BitsPerPixel:
                    673:                             ((unsigned int *)pixAddr)[ x ] = fg;
                    674:                             break;
                    675:                     }
                    676:             }
                    677:             pixAddr += console->display.rowBytes;
                    678:         }
                    679: }
                    680: 
                    681: static void BltChar(ConsolePtr console, const char c)
                    682: // Description: Paint one character at (curr_column, curr_row).
                    683: {
                    684:     unsigned char *glyphbase;  // the glyph we're rendering
                    685:     unsigned char byte;
                    686:     unsigned char *pixAddr;
                    687:     int x,y;                   // location of upper left corner of glyph
                    688:     int source_y, bold;
                    689:     unsigned char *dst8, fg8;
                    690:     unsigned short *dst16, fg16;
                    691:     unsigned int *dst32, fg32;
                    692: 
                    693: 
                    694:     // Erase current contents of {curr_row, curr_column}.
                    695:     Erase(console);
                    696:     
                    697:     // Skip non-printing characters.
                    698:     if (c < ENCODEBASE) {
                    699:        return;
                    700:     }
                    701:     bold = console->bolding;
                    702:     x = console->window_origin_x + console->curr_column * CHAR_W;
                    703:     y = console->window_origin_y + console->curr_row * CHAR_H;
                    704: 
                    705:     do {
                    706:        glyphbase = ohlfs12[c - ENCODEBASE];
                    707:        pixAddr = PixelAddress(console, x + bold, y);
                    708:        switch (console->display.bitsPerPixel) {
                    709:        case IO_8BitsPerPixel:
                    710:            fg8 = (unsigned char) console->foreground;
                    711:                dst8 = (unsigned char *) pixAddr;
                    712:            for (source_y = CHAR_H; source_y != 0; source_y--) {
                    713:                byte = *glyphbase++;
                    714:                if (byte & 0x80) dst8[0] = fg8;
                    715:                if (byte & 0x40) dst8[1] = fg8;
                    716:                if (byte & 0x20) dst8[2] = fg8;
                    717:                if (byte & 0x10) dst8[3] = fg8;
                    718:                if (byte & 0x08) dst8[4] = fg8;
                    719:                if (byte & 0x04) dst8[5] = fg8;
                    720:                if (byte & 0x02) dst8[6] = fg8;
                    721:                if (byte & 0x01) dst8[7] = fg8;
                    722:                dst8 = (unsigned char *)
                    723:                                ((int)dst8 + console->display.rowBytes);
                    724:            }
                    725:            break;
                    726:        case IO_12BitsPerPixel:
                    727:        case IO_15BitsPerPixel:
                    728:            fg16 = (unsigned short) console->foreground;
                    729:                dst16 = (unsigned short *) pixAddr;
                    730:            for (source_y = CHAR_H; source_y != 0; source_y--) {
                    731:                byte = *glyphbase++;
                    732:                if (byte & 0x80) dst16[0] = fg16;
                    733:                if (byte & 0x40) dst16[1] = fg16;
                    734:                if (byte & 0x20) dst16[2] = fg16;
                    735:                if (byte & 0x10) dst16[3] = fg16;
                    736:                if (byte & 0x08) dst16[4] = fg16;
                    737:                if (byte & 0x04) dst16[5] = fg16;
                    738:                if (byte & 0x02) dst16[6] = fg16;
                    739:                if (byte & 0x01) dst16[7] = fg16;
                    740:                dst16 = (unsigned short *)
                    741:                                ((int)dst16 + console->display.rowBytes);
                    742:            }
                    743:            break;
                    744:        case IO_24BitsPerPixel:
                    745:            fg32 = (unsigned int) console->foreground;
                    746:                dst32 = (unsigned int *) pixAddr;
                    747:            for (source_y = CHAR_H; source_y != 0; source_y--) {
                    748:                byte = *glyphbase++;
                    749:                if (byte & 0x80) dst32[0] = fg32;
                    750:                if (byte & 0x40) dst32[1] = fg32;
                    751:                if (byte & 0x20) dst32[2] = fg32;
                    752:                if (byte & 0x10) dst32[3] = fg32;
                    753:                if (byte & 0x08) dst32[4] = fg32;
                    754:                if (byte & 0x04) dst32[5] = fg32;
                    755:                if (byte & 0x02) dst32[6] = fg32;
                    756:                if (byte & 0x01) dst32[7] = fg32;
                    757:                dst32 = (unsigned int *)
                    758:                                ((int)dst32 + console->display.rowBytes);
                    759:            }
                    760:            break;
                    761:        }
                    762:     } while( bold--);
                    763:     console->curr_column++;
                    764:     return;
                    765: }
                    766: 
                    767: extern void video_scroll_up(unsigned char * start, unsigned char * end, unsigned char * dest);
                    768: 
                    769: static void FBPutC(ConsolePtr console, char c)
                    770: // Write one character to screen. Cursor is 'on' on entry and exit.
                    771: {
                    772: int    repeat;
                    773: int    i;
                    774: 
                    775:        /*
                    776:         * First deal with ANSI escape sequences.
                    777:         * This is a very bizarre implementation, copied from the m68k
                    778:         * version. 
                    779:         */
                    780:        switch(console->ansi_state) {
                    781:            case AS_NORMAL:
                    782:                if(c == esc) {
                    783:                        console->ansi_state = AS_ESCAPE;
                    784:                        return;
                    785:                }
                    786:                else {
                    787:                        break;                          // continue
                    788:                }
                    789:                
                    790:            case AS_ESCAPE:
                    791:                switch(c) {
                    792:                    case '[':
                    793:                        console->ansi_state = AS_BRACKET;
                    794:                        return;
                    795:                    default:
                    796:                        console->ansi_state = AS_NORMAL;
                    797:                        break;                          // continue
                    798:                }
                    799:        
                    800:            case AS_BRACKET:
                    801:                if(c >= '0' && c <= '9') {
                    802:                        *console->ansi_stack_p = 
                    803:                                *console->ansi_stack_p * 10 + (c - '0');
                    804:                        return;
                    805:                } 
                    806:                else if (c == ';') {
                    807:                        if(console->ansi_stack_p < 
                    808:                            &console->ansi_stack[ANSI_STACK_SIZE]) {
                    809:                                console->ansi_stack_p++;
                    810:                        }
                    811:                        return;
                    812:                } 
                    813:                else {
                    814:                        for(i=0; i<ANSI_STACK_SIZE; i++) {
                    815:                                if (console->ansi_stack[i] == 0) {
                    816:                                        console->ansi_stack[i] = 1; 
                    817:                                }
                    818:                        }
                    819:                        repeat = *console->ansi_stack_p;
                    820:                        FlipCursor(console);            // cursor off
                    821:                        switch (c) {
                    822: 
                    823:                            case 'A':
                    824:                                while (repeat--) {
                    825:                                        if(console->curr_row) {
                    826:                                                console->curr_row--;
                    827:                                        }
                    828:                                }
                    829:                                break;
                    830: 
                    831:                            case 'B':
                    832:                                while (repeat--) {
                    833:                                        console->curr_row++;
                    834:                                }
                    835:                                break;
                    836: 
                    837:                            case 'C':           // non destructive space
                    838:                                while (repeat--) {
                    839:                                        console->curr_column++;
                    840:                                }
                    841:                                break;
                    842: 
                    843:                            case 'D':           // not in termcap
                    844:                                while (repeat--) {
                    845:                                        if(console->curr_column) {
                    846:                                                console->curr_column--;
                    847:                                        }
                    848:                                }
                    849:                                break;
                    850: 
                    851:                            case 'E':           // not in termcap
                    852:                                console->curr_column = 0;
                    853:                                while (repeat--) {
                    854:                                        console->curr_row++;
                    855:                                }
                    856:                                break;
                    857: 
                    858:                            case 'H':           // should be home
                    859:                            case 'f':           // not in termcap
                    860:                                console->curr_column = 
                    861:                                        *console->ansi_stack_p - 1;
                    862:                                console->ansi_stack_p--;
                    863:                                console->curr_row = 
                    864:                                        *console->ansi_stack_p - 1;
                    865:                                console->ansi_stack_p--;
                    866:                                break;
                    867: 
                    868:                            case 'K':
                    869:                                ClearToEOL(console);
                    870:                                break;
                    871:                                
                    872:                            case 'm': /* FIXME */
                    873:                                console->ansi_stack_p--;
                    874:                                console->ansi_stack_p--;
                    875:                                break;
                    876:                        }
                    877:                }
                    878:                console->ansi_stack_p = &console->ansi_stack[1];
                    879:                for(i=0; i<ANSI_STACK_SIZE; i++)
                    880:                        console->ansi_stack[i] = 0;
                    881:                console->ansi_state = AS_NORMAL;
                    882:                goto proceed;
                    883:        }
                    884: 
                    885:     FlipCursor(console);               // cursor off
                    886:     switch(c) {
                    887:        case '\r':                      // Carriage return
                    888:            console->curr_column = 0;
                    889:            break;      
                    890:            
                    891:        case '\n':                      // line feed
                    892:            console->curr_column = 0;
                    893:            console->curr_row++;
                    894:            break;
                    895:            
                    896:        case '\b':                      // backspace
                    897:            if (console->curr_column == 0)
                    898:                    break;
                    899:            console->curr_column--;
                    900:            break;
                    901:            
                    902:        case '\t':
                    903:            // tab. Erase all characters up to and including the 
                    904:            // next tab stop.
                    905:            {
                    906:            int col, num_cols;
                    907:            
                    908:            num_cols = TAB_SIZE - (console->curr_column % TAB_SIZE);
                    909:            FlipCursor(console);                        // cursor on
                    910:            for (col = 0; col<num_cols; col++) {
                    911:                FBPutC(console, ' ');                   // cursor on at return
                    912:            }
                    913:            FlipCursor(console);                        // cursor off
                    914:            break;
                    915:            }
                    916:            
                    917:        case np:                                // aka ff, form feed
                    918:            console->curr_row = console->curr_column = 0;
                    919:            ClearWindow(console);
                    920:            break;
                    921: 
                    922:        case del:
                    923:            console->curr_column++;
                    924:            break;
                    925:            
                    926:        default:
                    927:            // Normal case.
                    928:            BltChar(console, c);
                    929:            break;
                    930:     }
                    931:     
                    932:     // Cursor is off.
                    933: proceed:       
                    934:     if (console->curr_column >= console->chars_per_row) {
                    935:        // End-of-line wrap. 
                    936:        console->curr_column = 0;
                    937:        console->curr_row++;
                    938:     }
                    939:     
                    940:     if (console->curr_row >= console->chars_per_column) {
                    941:        //
                    942:        // Screen scroll. Copy the whole window down in memory 
                    943:        // (pixels_per_row * CHAR_H) pixels, starting at 
                    944:        // the first character in row 1.
                    945:        //
                    946:        unsigned char *src;     
                    947:        unsigned char *dst;
                    948:        int source_y;
                    949:        unsigned windowRowBytes;
                    950:        
                    951:        console->curr_row = console->chars_per_column - 1;
                    952:        switch (console->display.bitsPerPixel) {
                    953:            case IO_8BitsPerPixel:
                    954:                windowRowBytes = console->pixels_per_row;
                    955:                break;
                    956:            case IO_12BitsPerPixel:
                    957:            case IO_15BitsPerPixel:
                    958:                windowRowBytes = 2*console->pixels_per_row;
                    959:                break;
                    960:            case IO_24BitsPerPixel:
                    961:                windowRowBytes = 4*console->pixels_per_row;
                    962:                break;
                    963:            default:
                    964:                panic("FBConsole/FBPutC: bogus bitsPerPixel");  
                    965:        }
                    966: 
                    967:        // Copy one row at a time, moving each one up
                    968:        // CHAR_H rows. Within the loop, just increment
                    969:        // pixel pointers by one row's worth of pixels.
                    970:        // Source starts at the left top of row 1; destination 
                    971:        // starts at left top of row 0.
                    972:        //
                    973:        src = PixelAddress(console, 
                    974:            console->window_origin_x,
                    975:            console->window_origin_y + CHAR_H);
                    976:        dst  = PixelAddress(console,
                    977:                console->window_origin_x,
                    978:                console->window_origin_y);
                    979:        for (source_y = CHAR_H;         // top, row 1
                    980:            source_y < console->pixels_per_column;      // bottom
                    981:            source_y++) {
                    982: #ifndef        notDefUseFPU
                    983:            video_scroll_up( src, src + windowRowBytes, dst);
                    984: #else
                    985:            videoMemMove(dst, src, windowRowBytes);
                    986: #endif
                    987:            src += console->display.rowBytes;
                    988:            dst += console->display.rowBytes;
                    989:        }
                    990: 
                    991:        console->curr_column = 0;
                    992:        ClearToEOL(console);
                    993: }
                    994:     
                    995:     // Cursor back on.
                    996:     FlipCursor(console);
                    997: }
                    998: 
                    999: static void SetTitle(ConsolePtr console, const char *title)
                   1000: // Description:        Draw title bar if none exists, write specified title into it.
                   1001: //             Drawing a title bar involves snarfing up row 0 of the window
                   1002: //             and decreasing the usable size of the window by one row.
                   1003: // Preconditions:
                   1004: // *   Cursor is 'on' on entry and will remain so on exit.
                   1005: {
                   1006:     int saved_curr_row = console->curr_row;
                   1007:     int saved_curr_column = console->curr_column;
                   1008:     int saved_origin_y;
                   1009:     int title_len = strlen(title);
                   1010:     int pixel_num;
                   1011:     
                   1012:     if ((title_len == 0) || (title_len > console->chars_per_row)) {
                   1013:            IOLog("console: Illegal title length (%d)\n", title_len);
                   1014:            return;
                   1015:     }
                   1016:     FlipCursor(console);                       // old cursor off
                   1017:     if (console->has_title) {
                   1018:        // First grow window by two rows - this absorbs the existing 
                   1019:        // title bar.
                   1020:        console->window_origin_y -= CHAR_H * 2;
                   1021:        console->chars_per_column += 2;
                   1022:        console->pixels_per_column += CHAR_H * 2;
                   1023:        saved_curr_row += 2;
                   1024:     }
                   1025: 
                   1026:     // Clear row 0, center new title in it.
                   1027:     console->curr_row = 0;
                   1028:     Rect(console,
                   1029:        console->window_origin_x - (BG_MARGIN - TS_MARGIN),
                   1030:        console->window_origin_y - (BG_MARGIN - TS_MARGIN),
                   1031:        CHAR_W * console->chars_per_row + 2 * (BG_MARGIN - TS_MARGIN),
                   1032:        CHAR_H * 2 - TS_MARGIN,
                   1033:        console->light_grey);
                   1034:     saved_origin_y = console->window_origin_y;
                   1035:     console->window_origin_y += CHAR_H / 2;
                   1036:     console->curr_column = (console->chars_per_row - title_len) / 2;
                   1037:     DrawIcon(console);
                   1038: //     SwapForegroundAndBackground(console);
                   1039:     console->bolding = 1;
                   1040:     console->background = console->light_grey;
                   1041:     FlipCursor(console);                               // new cursor on        
                   1042:     while (*title) {
                   1043:        FBPutC(console, *title++);
                   1044:     }
                   1045:     FlipCursor(console);                       // new cursor off       
                   1046:     console->background = console->grayTable[0];
                   1047:     console->bolding = 0;
                   1048: //    SwapForegroundAndBackground(console);
                   1049:     console->window_origin_y = saved_origin_y;
                   1050:     
                   1051:     // Draw grey lines one pixel away from border of title bar.
                   1052:     // Origin is currently at first pixel in top line of title bar.
                   1053: 
                   1054:     Rect(console,                              // inside top
                   1055:        console->window_origin_x - BG_MARGIN,
                   1056:        console->window_origin_y - BG_MARGIN,
                   1057:        console->pixels_per_row + (BG_MARGIN * 2),
                   1058:        TS_MARGIN,
                   1059:        console->background);
                   1060:     Rect(console,                              // inside bottom
                   1061:        console->window_origin_x - BG_MARGIN,
                   1062:        console->window_origin_y + CHAR_H * 2 - TOTAL_MARGIN - TS_MARGIN,
                   1063:        console->pixels_per_row + BG_MARGIN * 2,
                   1064:        TS_MARGIN,
                   1065:        console->dark_grey);
                   1066:     for (pixel_num = 0; pixel_num < TS_MARGIN; pixel_num++) {
                   1067:         Rect(console,                          // left
                   1068:            console->window_origin_x - BG_MARGIN + pixel_num,
                   1069:            console->window_origin_y - BG_MARGIN + pixel_num,
                   1070:            1,
                   1071:            CHAR_H * 2 - 1 - (pixel_num * 2),
                   1072:            console->background);
                   1073:     }
                   1074:     for (pixel_num = 1 + BG_MARGIN - TS_MARGIN; pixel_num <= BG_MARGIN; pixel_num++) {
                   1075:         Rect(console,                          // right
                   1076:            console->window_origin_x + console->pixels_per_row + pixel_num - 1,
                   1077:            console->window_origin_y - pixel_num,
                   1078:            1,
                   1079:            CHAR_H * 2 - 1 - (BG_MARGIN - pixel_num) * 2,
                   1080:            console->dark_grey);
                   1081:     }
                   1082:     Rect(console,                              // outside bottom
                   1083:        console->window_origin_x - TOTAL_MARGIN,
                   1084:        console->window_origin_y + CHAR_H * 2 - FG_MARGIN - BG_MARGIN,
                   1085:        console->pixels_per_row + TOTAL_MARGIN * 2,
                   1086:        FG_MARGIN,
                   1087:        console->foreground);
                   1088:            
                   1089:     // Diminish window size by two rows.
                   1090:     console->window_origin_y += CHAR_H * 2;
                   1091:     console->chars_per_column -= 2;
                   1092:     console->pixels_per_column -= CHAR_H * 2;
                   1093:     
                   1094: 
                   1095:     // Restore old cursor. Careful, the y axis just changed...
                   1096:     console->curr_column = saved_curr_column;
                   1097:     if (saved_curr_row > 0) {
                   1098:        console->curr_row = saved_curr_row - 2;
                   1099:     } 
                   1100:     else {
                   1101:        // New row 0 - clear it.
                   1102:        ClearToEOL(console);
                   1103:     }
                   1104:     FlipCursor(console);                       // old cursor on
                   1105:     console->has_title = TRUE; 
                   1106: }
                   1107: 
                   1108: 
                   1109: static void UpdateWindowChars(ConsolePtr console)
                   1110: // Description:        Calculate window size in characters. Used when either window
                   1111: //             size or font changes.
                   1112: {
                   1113:     console->chars_per_row = console->pixels_per_row / CHAR_W;
                   1114:     console->chars_per_column =
                   1115:         console->pixels_per_column / CHAR_H;
                   1116: }
                   1117: 
                   1118: 
                   1119: 
                   1120: static void InitWindow(ConsolePtr console,
                   1121:        int             width,
                   1122:        int             height,
                   1123:        const char      *title,
                   1124:        boolean_t       initWindow,
                   1125:        boolean_t       saveUnder)
                   1126: // Description:        Initialize window parameters. If initWindow is TRUE, an empty
                   1127: //             window is drawn in the screen, else we assume that a window
                   1128: //             already  exists. Screen and font parameters must be valid on
                   1129: //             entry.
                   1130: {
                   1131:     // Truncate specified size to integral mutliple of character size
                   1132:     // in both dimensions.
                   1133:     width  /= CHAR_W;          // now in chars
                   1134:     height /= CHAR_H;
                   1135:     width  *= CHAR_W;          // now in pixels
                   1136:     height *= CHAR_H;
                   1137:     
                   1138:     // Ensure there's enough room for a border.
                   1139:     if (width > (console->display.width - HORIZ_BORDER - TOTAL_MARGIN * 2 - DROP_SHADOW))
                   1140:        width = console->display.width - HORIZ_BORDER - TOTAL_MARGIN * 2 - DROP_SHADOW;
                   1141:     if (height > (console->display.height - VERT_BORDER - TOTAL_MARGIN * 2 - DROP_SHADOW))
                   1142:        height = console->display.height - VERT_BORDER - TOTAL_MARGIN * 2 - DROP_SHADOW;
                   1143:     width &= 0xfffffffe;
                   1144:            
                   1145:     //
                   1146:     // Init console window variables. The window is centered in the 
                   1147:     // ! screen, minus a pixel or two to guarantee double word alignment
                   1148:     // ! for the first pixel of a row (until further developments...when 
                   1149:     // ! we do alert panels, we can enumerate some cases here...).
                   1150:     //
                   1151:     console->window_origin_x   = (console->display.width - width) / 2;
                   1152:     console->window_origin_y   = (console->display.height - height) / 2;
                   1153:     console->pixels_per_row    = width;
                   1154:     console->pixels_per_column = height;
                   1155:     (unsigned)console->window_origin_x &= 0xfffffffe;
                   1156: 
                   1157:     UpdateWindowChars(console);
                   1158:     
                   1159:     console->curr_column = 0;
                   1160:     console->has_title = FALSE;
                   1161:     
                   1162:     if (initWindow) {
                   1163:        // Before we start drawing anything, save under if needed
                   1164:        if (saveUnder) {
                   1165:            int i, bytesPerPixel = 0;
                   1166:            unsigned char *save, *sp;
                   1167: 
                   1168:            // Compute size of save under region in bytes and allocate
                   1169:            switch (console->display.bitsPerPixel) {
                   1170:                case IO_8BitsPerPixel:  bytesPerPixel = 1; break;
                   1171:                case IO_12BitsPerPixel:
                   1172:                case IO_15BitsPerPixel: bytesPerPixel = 2; break;
                   1173:                case IO_24BitsPerPixel: bytesPerPixel = 4; break;
                   1174:            }
                   1175:            console->saveHeight = height + TOTAL_MARGIN * 2 + DROP_SHADOW;
                   1176:            console->saveRowBytes = (width + TOTAL_MARGIN * 2 + DROP_SHADOW)*bytesPerPixel;
                   1177:            console->saveBytes = console->saveHeight*console->saveRowBytes;
                   1178:            save = console->saveBits = (unsigned char *)
                   1179:                                         kalloc_noblock(console->saveBytes);
                   1180:            sp = console->saveLocation = 
                   1181:                PixelAddress(console, console->window_origin_x - TOTAL_MARGIN, 
                   1182:                              console->window_origin_y - TOTAL_MARGIN);
                   1183: 
                   1184:            // Copy the window contents into the save under
                   1185:            if( save)
                   1186:                 for (i = console->saveHeight; i != 0; i--) {
                   1187:                     videoMemMove(save, sp, console->saveRowBytes);
                   1188:                     sp += console->display.rowBytes;
                   1189:                     save += console->saveRowBytes;
                   1190:                 }
                   1191:        }
                   1192:     
                   1193:        // New window - cursor at origin.
                   1194:        console->curr_row = 0;
                   1195:        console->has_title = FALSE;
                   1196:        
                   1197:        // Draw the border. The border goes outside of the specified
                   1198:        // window. Outside lines are black; inside lines are 
                   1199:        // half-tone.
                   1200:        Rect(console,                           // outside top
                   1201:            console->window_origin_x - TOTAL_MARGIN,
                   1202:            console->window_origin_y - TOTAL_MARGIN,
                   1203:            width + TOTAL_MARGIN * 2,
                   1204:            FG_MARGIN,
                   1205:            console->foreground);
                   1206:        Rect(console,                           // inside top
                   1207:            console->window_origin_x - BG_MARGIN,
                   1208:            console->window_origin_y - BG_MARGIN,
                   1209:            width + BG_MARGIN * 2,
                   1210:            BG_MARGIN,
                   1211:            console->background);
                   1212:        Rect(console,                           // inside bottom
                   1213:            console->window_origin_x - BG_MARGIN,
                   1214:            console->window_origin_y + height,
                   1215:            width + BG_MARGIN * 2,
                   1216:            BG_MARGIN,
                   1217:            console->background);
                   1218:        Rect(console,                           // outside bottom
                   1219:            console->window_origin_x - TOTAL_MARGIN,
                   1220:            console->window_origin_y + height + BG_MARGIN,
                   1221:            width + TOTAL_MARGIN * 2,
                   1222:            FG_MARGIN,
                   1223:            console->foreground);
                   1224:        if( DROP_SHADOW) Rect(console,                          // outside bottom shadow
                   1225:            console->window_origin_x - TOTAL_MARGIN + DROP_SHADOW,
                   1226:            console->window_origin_y + height + BG_MARGIN + DROP_SHADOW,
                   1227:            width + TOTAL_MARGIN * 2,
                   1228:            DROP_SHADOW,
                   1229:            console->dark_grey);
                   1230:        Rect(console,                           // outside left
                   1231:            console->window_origin_x - TOTAL_MARGIN,
                   1232:            console->window_origin_y - TOTAL_MARGIN,
                   1233:            FG_MARGIN,
                   1234:            height + TOTAL_MARGIN * 2,
                   1235:            console->foreground);
                   1236:        Rect(console,                           // inside left
                   1237:            console->window_origin_x - BG_MARGIN,
                   1238:            console->window_origin_y - BG_MARGIN,
                   1239:            BG_MARGIN,
                   1240:            height + BG_MARGIN * 2,
                   1241:            console->background);
                   1242:        Rect(console,                           // inside right
                   1243:            console->window_origin_x + width,
                   1244:            console->window_origin_y - BG_MARGIN,
                   1245:            BG_MARGIN,
                   1246:            height + BG_MARGIN * 2,
                   1247:            console->background);
                   1248:        Rect(console,                           // outside right
                   1249:            console->window_origin_x + width + BG_MARGIN,
                   1250:            console->window_origin_y - TOTAL_MARGIN,
                   1251:            FG_MARGIN,
                   1252:            height + TOTAL_MARGIN * 2,
                   1253:            console->foreground);
                   1254:        if( DROP_SHADOW) Rect(console,                          // outside right shadow
                   1255:            console->window_origin_x + width + BG_MARGIN + DROP_SHADOW,
                   1256:            console->window_origin_y - TOTAL_MARGIN + DROP_SHADOW,
                   1257:            DROP_SHADOW,
                   1258:            height + TOTAL_MARGIN * 2,
                   1259:            console->dark_grey);
                   1260:                
                   1261:        // Clear the contents of the window and draw a cursor.
                   1262:        ClearWindow(console);
                   1263:        FlipCursor(console);                    // cursor on
                   1264:        SetTitle(console, title);
                   1265:     }
                   1266:     else {
                   1267:            /* Leave current window contents, just updating title. 
                   1268:             * We'll do a newline to make sure we have room for 
                   1269:             * our font and proceed.Initial cursor will be at 
                   1270:             * lower left corner.
                   1271:             */
                   1272:            console->curr_row = console->chars_per_column - 1;
                   1273:            SetTitle(console, title);
                   1274:            FBPutC(console, '\n');
                   1275:     }
                   1276:     return;
                   1277: }
                   1278: 
                   1279: //
                   1280: // END:                Private utility routines
                   1281: //
                   1282: 
                   1283: //
                   1284: // BEGIN:      Implementation of IOConsoleInfo functions
                   1285: //
                   1286: static void Free(IOConsoleInfo *cso)
                   1287: // Description: Free a FB Console object
                   1288: {
                   1289:     IOFree(cso->priv, sizeof(ConsoleRep));
                   1290:     IOFree(cso, sizeof(IOConsoleInfo));
                   1291: }
                   1292: 
                   1293: static void Init(
                   1294:     IOConsoleInfo *cso,
                   1295:     ScreenMode mode,
                   1296:     boolean_t initScreenOrSaveUnder,
                   1297:     boolean_t initWindow,
                   1298:     const char *title)
                   1299: {
                   1300:     ConsolePtr console = (ConsolePtr)cso->priv;
                   1301:     int i;
                   1302:        
                   1303:     switch (console->display.bitsPerPixel) {
                   1304:         case IO_8BitsPerPixel:
                   1305:            if (console->display.colorSpace == IO_OneIsWhiteColorSpace) {
                   1306:                console->baseground = (TRUE || (mode == SCM_GRAPHIC)) ? 107 : 0x55;
                   1307:                console->background = 0xff;
                   1308:                console->foreground = 0x00;
                   1309:                console->dark_grey  = 85;
                   1310:                console->light_grey = 187;
                   1311:            } else {
                   1312:                console->baseground = (TRUE || (mode == SCM_GRAPHIC)) ? 0x80 : 0x7e;
                   1313:                console->background = 0x00;
                   1314:                console->foreground = 0xff;
                   1315:                console->dark_grey  = 0xfb;
                   1316:                console->light_grey = 0xf7;
                   1317:            }
                   1318:            break;
                   1319:        case IO_15BitsPerPixel:
                   1320:            console->baseground = (TRUE || (mode == SCM_GRAPHIC)) ? 0x3193 : 0x295f;
                   1321:            console->background = 0x7fff;
                   1322:            console->foreground = 0x0000;
                   1323:            console->dark_grey  = 0x294a;
                   1324:            console->light_grey = 0x5ef7;
                   1325:            break;
                   1326:        case IO_24BitsPerPixel:
                   1327:            console->baseground = (TRUE || (mode == SCM_GRAPHIC)) ? 0xff666699 : 0xff5555ff;
                   1328:            console->background = 0xffffffff;
                   1329:            console->foreground = 0xff000000;
                   1330:            console->dark_grey  = 0xff555555;
                   1331:            console->light_grey = 0xffbbbbbb;
                   1332:            break;
                   1333:     }
                   1334: 
                   1335:     console->grayTable[0] = console->background;
                   1336:     console->grayTable[1] = console->light_grey;
                   1337:     console->grayTable[2] = console->dark_grey;
                   1338:     console->grayTable[3] = console->foreground;
                   1339: 
                   1340:     console->ansi_state = AS_NORMAL;
                   1341:     for(i=0; i<ANSI_STACK_SIZE; i++) {
                   1342:                console->ansi_stack[i] = 0;
                   1343:        }
                   1344:     console->ansi_stack_p = &console->ansi_stack[1];   // FIXME - why not 0?
                   1345: 
                   1346:     // Initialize the screen, if appropriate.
                   1347:     if (initScreenOrSaveUnder && (mode != SCM_ALERT)) {
                   1348:        WipeScreen(console, console->baseground);
                   1349:     }
                   1350: 
                   1351:     console->window_type = mode;
                   1352:     switch(console->window_type) {
                   1353:        case SCM_TEXT:
                   1354:            InitWindow(console, TEXT_WIN_WIDTH, TEXT_WIN_HEIGHT,
                   1355:                title, initWindow, 0 /* Don't save under */);
                   1356:            break;
                   1357:        case SCM_ALERT:
                   1358:            InitWindow(console, ALERT_WIN_WIDTH, ALERT_WIN_HEIGHT,
                   1359:                title, initWindow, initScreenOrSaveUnder );
                   1360:            break;
                   1361:        case SCM_GRAPHIC:
                   1362:            if( initScreenOrSaveUnder) {
                   1363:                int cx, cy;
                   1364: 
                   1365:                 cx = console->display.width / 2;
                   1366:                 cy = console->display.height / 2;
1.1.1.2 ! root     1367: #if 0
1.1       root     1368:                 Expand4ToN( console, cx + RIGHT_DX, cy + RIGHT_DY,
                   1369:                        RIGHT_WIDTH, RIGHT_HEIGHT, rightData, rightBotColors );
                   1370:                 Expand4ToN( console, cx + CENTER_DX, cy + CENTER_DY,
                   1371:                        CENTER_WIDTH, CENTER_HEIGHT, centerData, centerColors );
                   1372:                 Expand4ToN( console, cx + BOTTOM_DX, cy + BOTTOM_DY,
                   1373:                        BOTTOM_WIDTH, BOTTOM_HEIGHT, bottomData, rightBotColors );
1.1.1.2 ! root     1374: #else
        !          1375:                 Expand8ToN( console, cx + CENTER_DX, cy + CENTER_DY,
        !          1376:                        CENTER_WIDTH, CENTER_HEIGHT, centerData );
        !          1377: #endif
1.1       root     1378:            }
                   1379:            break;
                   1380: 
                   1381:        default:
                   1382:            panic("FBConsole/FBInitConsole: can't init");
                   1383:            break;
                   1384:     }
                   1385:     return;
                   1386: }
                   1387: 
                   1388: static int Restore(IOConsoleInfo *cso)
                   1389: {
                   1390:     ConsolePtr console = (ConsolePtr)cso->priv;
                   1391:     unsigned char *save, *dp;
                   1392:     int i;
                   1393: 
                   1394:     if (console->window_type != SCM_ALERT) {
                   1395:        IOLog("frameBuffer: bogus restore, mode %d\n", console->window_type);
                   1396:        return -1;
                   1397:     }
                   1398: 
                   1399:     // Copy save under bits back onto screen
                   1400:     save = console->saveBits;
                   1401:     dp = console->saveLocation;
                   1402:     if( save) {
                   1403:         for (i = console->saveHeight; i != 0; i--) {
                   1404:             videoMemMove(dp, save, console->saveRowBytes);
                   1405:             dp += console->display.rowBytes;
                   1406:             save += console->saveRowBytes;
                   1407:         }
                   1408: 
                   1409:         // Free bits
                   1410:         kfree(console->saveBits, console->saveBytes);
                   1411:        console->saveBits = 0;
                   1412:     }
                   1413:     return 0;
                   1414: }
                   1415: 
                   1416: #define        VIDEO_W 640
                   1417: #define        VIDEO_H 480
                   1418: 
                   1419: static int DrawRect(IOConsoleInfo *cso,  const struct km_drawrect *km_rect)
                   1420: // Description:        Given a 2 bit raster, convert it to the format appropriate for
                   1421: //             the display. The co-ordinates passed in by these ioctls assume
                   1422: //             an (VIDEO_W x VIDEO_H) screen. All screen sizes are
                   1423: //             assumed to share a common center point. We scale the X and Y
                   1424: //             values to maintain a constant offset from the center point,
                   1425: //             so that boot animations, popup windows, and related goodies
                   1426: //             don't break with screens larger or smaller than the 'default'
                   1427: //             screen.
                   1428: // Preconditions:
                   1429: // * The rectangle that we are to draw must start on a 4 pixel boundary
                   1430: //   and should be a multiple of 4 pixels in width.
                   1431: {
                   1432:     ConsolePtr console = (ConsolePtr)cso->priv;
                   1433:     int pixel;         /* Starting pixel in screen */
                   1434:     int i, x, y;
                   1435:     unsigned char *data;
                   1436:     unsigned char value;
                   1437:     unsigned int * table;
                   1438:     struct km_drawrect *rect = (struct km_drawrect *) km_rect;
                   1439:     int bgX, bgY, bgH;
                   1440:     unsigned char * bg;
                   1441: 
                   1442:     table = console->grayTable;
                   1443: 
                   1444:     /* copyin is done in km */
                   1445:     data = rect->data.bits;
                   1446: 
                   1447:     x = (rect->x & 0x1ffc) + (console->display.width - VIDEO_W)/2;
                   1448:     y = rect->y + (console->display.height - VIDEO_H)/2;
                   1449: 
                   1450:     /* Correct the x and y values for screen size */
                   1451:     if( (rect->x & 3) == 3) {
                   1452:        DrawColorRect( console, x, y, rect->width, rect->height, data);
                   1453:        return 0;
                   1454:     }
                   1455: 
                   1456: #if TEXTURE_BACKGND
                   1457:     bgX = console->display.width / 2 + CENTER_DX;
                   1458:     bgY = console->display.height / 2 + CENTER_DY;
                   1459: 
                   1460:     bgH = (y - bgY) & -2;
                   1461:     if( bgH > 0) {
                   1462:         bgY += bgH;
1.1.1.2 ! root     1463:         bg = centerData + (bgH * CENTER_WIDTH);
1.1       root     1464:         bgH = CENTER_HEIGHT - bgH;
                   1465:     } else
                   1466:        bg = (unsigned char *)0;
                   1467: #endif
                   1468: 
                   1469:     rect->x &= 0x1ffc;
                   1470: 
                   1471:     /* Sanity check */
                   1472:     if ((x + rect->width > console->display.width)
                   1473:     || (y + rect->height) > console->display.height)
                   1474:        return( -1 );
                   1475: 
                   1476: 
                   1477:     pixel = x + (y * console->display.totalWidth);
                   1478: 
                   1479:     switch ( console->display.bitsPerPixel )
                   1480:     {
                   1481:        case IO_2BitsPerPixel:  /* 2 bit pixels */
                   1482:        {
                   1483:            unsigned char *dst = (unsigned char *)console->display.frameBuffer;
                   1484:            unsigned char *fb;
                   1485:            unsigned char final_value;
                   1486:            
                   1487:            dst += pixel >> 2;
                   1488:            for ( y = 0; y < rect->height; ++y ) {
                   1489:                fb = dst;
                   1490:                for ( x = 0; x < rect->width; x += 4) {
                   1491:                        value = *data++;
                   1492:                        final_value = 0;
                   1493:                        for ( i = 0; i < 8; i += 2 ) {
                   1494:                            final_value |= ((table[(value>>i)&3] & 3) << i);
                   1495:                        }
                   1496:                        *fb++ = final_value;
                   1497:                }
                   1498:                dst += console->display.rowBytes;
                   1499:            }
                   1500:            break;
                   1501:        }
                   1502:        case IO_8BitsPerPixel:  /* 8 bit pixels */
                   1503:        {
                   1504:            unsigned char *dst = (unsigned char *)console->display.frameBuffer;
                   1505:            unsigned char *fb;
                   1506: 
                   1507:            dst += pixel;
                   1508:            for ( y = 0; y < rect->height; ++y ) {
                   1509:                fb = dst;
                   1510: #if TEXTURE_BACKGND
1.1.1.2 ! root     1511:                Expand8ToN( console, bgX, bgY,
        !          1512:                        CENTER_WIDTH, 1, bg );
        !          1513:                bgY += 1;
        !          1514:                bg += CENTER_WIDTH;
1.1       root     1515: #endif
                   1516:                for ( x = 0; x < rect->width; x += 4) {
                   1517:                     value = *data++;
                   1518:                     if( value) {
                   1519:                     int pix;
                   1520:                         pix = (value >> 6) & 3;
                   1521:                         if( pix)
                   1522:                             fb[0] = table[pix];
                   1523:                         pix = (value >> 4) & 3;
                   1524:                         if( pix)
                   1525:                             fb[1] = table[pix];
                   1526:                         pix = (value >> 2) & 3;
                   1527:                         if( pix)
                   1528:                             fb[2] = table[pix];
                   1529:                         pix = value & 3;
                   1530:                         if( pix)
                   1531:                             fb[3] = table[pix];
                   1532:                     }
                   1533:                     fb += 4;
                   1534:                }
                   1535:                dst += console->display.rowBytes;
                   1536:            }           
                   1537:            break;
                   1538:        }
                   1539:        case IO_12BitsPerPixel: /* 16 bit pixels */
                   1540:        case IO_15BitsPerPixel: /* 16 bit pixels */
                   1541:        {
                   1542: 
                   1543:            unsigned short *dst = (unsigned short *)console->display.frameBuffer;
                   1544:            unsigned short *fb;
                   1545:            dst += pixel;
                   1546: 
                   1547:            for ( y = 0; y < rect->height; ++y ) {
                   1548:                fb = dst;
                   1549: #if TEXTURE_BACKGND
1.1.1.2 ! root     1550:                Expand8ToN( console, bgX, bgY,
        !          1551:                        CENTER_WIDTH, 1, bg );
        !          1552:                bgY += 1;
        !          1553:                bg += CENTER_WIDTH;
1.1       root     1554: #endif
                   1555:                for ( x = 0; x < rect->width; x += 4) {
                   1556:                     value = *data++;
                   1557:                     if( value) {
                   1558:                     int pix;
                   1559:                         pix = (value >> 6) & 3;
                   1560:                         if( pix)
                   1561:                             fb[0] = table[pix];
                   1562:                         pix = (value >> 4) & 3;
                   1563:                         if( pix)
                   1564:                             fb[1] = table[pix];
                   1565:                         pix = (value >> 2) & 3;
                   1566:                         if( pix)
                   1567:                             fb[2] = table[pix];
                   1568:                         pix = value & 3;
                   1569:                         if( pix)
                   1570:                             fb[3] = table[pix];
                   1571:                     }
                   1572:                     fb += 4;
                   1573:                }
                   1574:                dst = (unsigned short *)(((char*)dst) +
                   1575:                    console->display.rowBytes);
                   1576:            }           
                   1577:            break;
                   1578:        }
                   1579:        case IO_24BitsPerPixel: /* 32 bit pixels */
                   1580:        {
                   1581:            unsigned int *dst = (unsigned int *) console->display.frameBuffer;
                   1582:            unsigned int *fb;
                   1583: 
                   1584:            dst += pixel;
                   1585:            for ( y = 0; y < rect->height; ++y ) {
                   1586:                fb = dst;
                   1587: #if TEXTURE_BACKGND
1.1.1.2 ! root     1588:                Expand8ToN( console, bgX, bgY,
        !          1589:                        CENTER_WIDTH, 1, bg );
        !          1590:                bgY += 1;
        !          1591:                bg += CENTER_WIDTH;
1.1       root     1592: #endif
                   1593:                for ( x = 0; x < rect->width; x += 4) {
                   1594:                     value = *data++;
                   1595:                     if( value) {
                   1596:                     int pix;
                   1597:                         pix = (value >> 6) & 3;
                   1598:                         if( pix)
                   1599:                             fb[0] = table[pix];
                   1600:                         pix = (value >> 4) & 3;
                   1601:                         if( pix)
                   1602:                             fb[1] = table[pix];
                   1603:                         pix = (value >> 2) & 3;
                   1604:                         if( pix)
                   1605:                             fb[2] = table[pix];
                   1606:                         pix = value & 3;
                   1607:                         if( pix)
                   1608:                             fb[3] = table[pix];
                   1609:                     }
                   1610:                     fb += 4;
                   1611:                }
                   1612:                dst = (unsigned int *)(((char*)dst) +
                   1613:                    console->display.rowBytes);
                   1614:            }           
                   1615:            break;
                   1616:        }
                   1617:     }
                   1618:     return 0;
                   1619: }
                   1620: 
                   1621: static int EraseRect(IOConsoleInfo *cso,  const struct km_drawrect *km_rect)
                   1622: // Description:        Erase the specified rectangle to the color specified
                   1623: //             in the km_rect structure.
                   1624: // Preconditions:
                   1625: // * The rectangle that we are to erase must start on a 4 pixel boundary
                   1626: //   and should be a multiple of 4 pixels in width.
                   1627: {
                   1628:     ConsolePtr console = (ConsolePtr)cso->priv;
                   1629:     int pixel;         // Starting pixel in screen
                   1630:     int x, y, w, h;
                   1631:     unsigned int value;
                   1632:     struct km_drawrect *rect = (struct km_drawrect *) km_rect;
                   1633:     int bgX, bgY, bgH;
                   1634:     unsigned char * bg;
                   1635: 
                   1636:     value = console->grayTable[ rect->data.fill & 3 ];
                   1637: 
                   1638:     /* Correct the x and y values for screen size */
                   1639:     x = rect->x + (console->display.width - VIDEO_W)/2;
                   1640:     y = rect->y + (console->display.height - VIDEO_H)/2;
                   1641: 
                   1642:     x &= ~3;                           // Trunc to 4 pixel boundary
                   1643:     w = (rect->width) & ~3;            // Round dn to 4 pixel boundary
                   1644:     h = rect->height;
                   1645: 
                   1646:     /* Sanity check */
                   1647:     /* Sanity check */
                   1648:     if (((x + w) > console->display.width)
                   1649:     ||  ((y + h) > console->display.height) )
                   1650:        return( -1 );
                   1651: 
                   1652: 
                   1653: #if TEXTURE_BACKGND
                   1654:     bgX = console->display.width / 2 + CENTER_DX;
                   1655:     bgY = console->display.height / 2 + CENTER_DY;
                   1656: 
                   1657:     bgH = (y - bgY) & -2;
                   1658:     if( bgH > 0) {
                   1659:         bgY += bgH;
1.1.1.2 ! root     1660:         bg = centerData + (bgH * CENTER_WIDTH);
1.1       root     1661:         bgH = CENTER_HEIGHT - bgH;
                   1662:         Expand4ToN( console, bgX, bgY,
                   1663:                 CENTER_WIDTH, bgH, bg, centerColors );
                   1664:     }
                   1665: 
                   1666: #else
                   1667:     Rect( console, x, y, w, h, value);
                   1668: #endif
                   1669: 
                   1670:     return 0;
                   1671: }
                   1672: 
                   1673: //extern void czputc( char c);
                   1674: 
                   1675: static void PutC(IOConsoleInfo *cso, char c)
                   1676: // Write one character to screen. Cursor is 'on' on entry and exit.
                   1677: {
                   1678:     FBPutC((ConsolePtr)cso->priv, c);
                   1679: //    czputc(c);
                   1680: }
                   1681: 
                   1682: static void GetSize(IOConsoleInfo *cso, struct ConsoleSize *s)
                   1683: // Return the size of the screen in pixels
                   1684: {
                   1685:     ConsolePtr console = (ConsolePtr)cso->priv;
                   1686:     s->cols = console->chars_per_row;
                   1687:     s->rows = console->chars_per_column;
                   1688:     s->pixel_width = console->display.width;
                   1689:     s->pixel_height = console->display.height;
                   1690: }
                   1691: 
                   1692: //
                   1693: // END:                Implementation of IOConsoleInfo functions
                   1694: //
                   1695: 
                   1696: static IOConsoleInfo staticConsoleInfo;
                   1697: static ConsoleRep staticConsoleRep;
                   1698: 
                   1699: static void InitializeConsole( IOConsoleInfo *cso, IODisplayInfo *display )
                   1700: {
                   1701:     cso->Init = Init;
                   1702:     cso->Restore = Restore;
                   1703:     cso->DrawRect = DrawRect;
                   1704:     cso->EraseRect = EraseRect;
                   1705:     cso->PutC = PutC;
                   1706:     cso->GetSize = GetSize;
                   1707:     ((ConsolePtr)cso->priv)->display = *display;
                   1708:     ((ConsolePtr)cso->priv)->window_type = SCM_UNINIT;
                   1709:     return;
                   1710: }
                   1711: 
                   1712: //
                   1713: // BEGIN:      Exported routines
                   1714: //
                   1715: 
                   1716: static void DoNothing(IOConsoleInfo *cso)
                   1717: {
                   1718: }
                   1719: 
                   1720: IOConsoleInfo *BasicAllocateConsole(IODisplayInfo *display)
                   1721: {
                   1722: // No memory allocation. Assume non backed window.
                   1723:     IOConsoleInfo *cso = &staticConsoleInfo;
                   1724:     cso->priv = (void *)&staticConsoleRep;
                   1725:     InitializeConsole(cso, display);
                   1726:     cso->Free = DoNothing;
                   1727: #if 0
                   1728:     printf("base:%x rowBytes:%x width:%x height:%x\n",display->frameBuffer,
                   1729:                display->rowBytes, display->width, display->height);
                   1730: #endif
                   1731:     return cso;
                   1732: }
                   1733: 
                   1734: 
                   1735: IOConsoleInfo *FBAllocateConsole(IODisplayInfo *display)
                   1736: {
                   1737:    IOConsoleInfo *cso = (IOConsoleInfo *)IOMalloc(sizeof(IOConsoleInfo));
                   1738:     
                   1739:     if (cso == NIL)
                   1740:         return NIL;
                   1741:     cso->priv = (void *)IOMalloc(sizeof(ConsoleRep));
                   1742:     if (cso->priv == NIL)
                   1743:     {
                   1744:         IOFree(cso, sizeof(IOConsoleInfo));
                   1745:        return NIL;
                   1746:     }
                   1747:     InitializeConsole(cso, display);
                   1748:     cso->Free = Free;
                   1749:    return cso;
                   1750: }
                   1751: 
                   1752: 
                   1753: //
                   1754: // END:                Exported routines
                   1755: //

unix.superglobalmegacorp.com

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