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

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

unix.superglobalmegacorp.com

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