Annotation of driverkit/libDriver/ppc/IOFramebuffer.m, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: /*     Copyright (c) 1992-96 NeXT Software, Inc.  All rights reserved. 
                     25:  *
                     26:  * IOFramebuffer.m - Implements common methods for "standard" frame
                     27:  *                             buffers.
                     28:  *
                     29:  *
                     30:  * HISTORY
                     31:  * 26 Oct 95   Dean Reece
                     32:  *     Moved strtol() out of this class into its own file (strtol.c)
                     33:  * 24 Oct 95   Rakesh Dubey
                     34:  *      Added mode change feature. 
                     35:  * 01 Sep 92   Joe Pasqua
                     36:  *      Created. 
                     37:  */
                     38: 
                     39: #define KERNEL_PRIVATE 1
                     40: #define DRIVER_PRIVATE 1
                     41: 
                     42: /* Notes:
                     43:  *   The definition of a standard frame buffer is anything with direct
                     44:  *   32 bit access to a 2 & 8 bit gray, 8 & 16 & 32 bit color. For 16 bit
                     45:  *   displays we support both 4/4/4 and 5/5/5 samples per channel. 
                     46:  *
                     47:  *   This class implements the evScreen protocol for all StdFBDisplays. Well,
                     48:  *   almost. The setBrightness method doesn't do anything. Subclasses must
                     49:  *   override this and implement it as appropriate for the device.
                     50:  *
                     51:  *   To find things that need to be fixed, search for FIX, to find questions
                     52:  *   to be resolved, search for ASK, to find stuff that still needs to be
                     53:  *   done, search for TO DO.
                     54:  */
                     55: 
                     56: #import <string.h>
                     57: #import <stdlib.h>
                     58: #ifdef i386
                     59: #import <bsd/dev/i386/FBConsole.h>
                     60: #endif
                     61: 
                     62: #ifdef ppc
                     63: #import <bsd/dev/ppc/FBConsole.h>
                     64: #import <driverkit/ppc/IOSmartDisplay.h>
                     65: #import        <driverkit/ppc/IOFramebuffer.h>
                     66: #import        <driverkit/ppc/IOTreeDevice.h>          // for IOApertureInfo
                     67: #endif
                     68: 
                     69: #import        <driverkit/EventDriver.h>
                     70: #import        <bsd/dev/evio.h>
                     71: 
                     72: #ifdef i386
                     73: #import        <bsd/dev/i386/kmDevice.h>
                     74: #endif
                     75: #ifdef ppc
                     76: #import        <bsd/dev/ppc/kmDevice.h>
                     77: #endif
                     78: 
                     79: #import <driverkit/KernBus.h>
                     80: #import <driverkit/KernBusMemory.h>
                     81: #import <driverkit/IODisplayPrivate.h>
                     82: #import        <driverkit/IOFrameBufferShared.h>
                     83: #import <driverkit/IODirectDevicePrivate.h>
                     84: #import <driverkit/displayDefs.h>
                     85: #ifdef i386
                     86: #import <driverkit/i386/directDevice.h>
                     87: #import <driverkit/i386/driverTypes.h>
                     88: #endif
                     89: #ifdef ppc
                     90: #import <driverkit/ppc/directDevice.h>
                     91: #import <driverkit/ppc/driverTypes.h>
                     92: #endif
                     93: 
                     94: #define CLEARSEMA(shmem)       ev_unlock(&shmem->cursorSema)
                     95: #define SETSEMA(shmem)         \
                     96:        if (!ev_try_lock(&shmem->cursorSema)) return self;
                     97: #define TOUCHBOUNDS(one, two) \
                     98:        (((one.minx < two.maxx) && (two.minx < one.maxx)) && \
                     99:        ((one.miny < two.maxy) && (two.miny < one.maxy)))
                    100: 
                    101: #define RBMASK 0xF0F0          /* Short, or 16 bit format */
                    102: #define GAMASK 0x0F0F          /* Short, or 16 bit format */
                    103: #define AMASK  0x000F          /* Short, or 16 bit format */
                    104: 
                    105: #define        GetShmem(instance)      ((StdFBShmem_t *)(instance->priv))
                    106: 
                    107: extern long int strtol(const char *nptr, char **endptr, int base);
                    108: 
                    109: #ifndef IO_DISPLAY_MODE_SAFE
                    110: #define IO_DISPLAY_MODE_SAFE           0x00000001
                    111: #endif
                    112: #ifndef IO_DISPLAY_MODE_DEFAULT
                    113: #define IO_DISPLAY_MODE_DEFAULT                0x00000002
                    114: #endif
                    115: 
                    116: static BOOL    wsStartup;
                    117: static Class   gSmartDisplayClass;
                    118: 
                    119: @implementation IOFramebuffer
                    120: 
                    121: 
                    122: //
                    123: // BEGIN:      Generic utility routines and methods
                    124: //
                    125: - (IOReturn)_registerWithED
                    126: // Description:        Register this display device with the event driver.
                    127: {
                    128:     int token;
                    129:     int shmem_size;
                    130:     Bounds bounds;
                    131:     StdFBShmem_t *shmem;
                    132:     
                    133:     token = [[EventDriver instance] registerScreen:self
                    134:        bounds:&bounds
                    135:        shmem:&(self->priv)
                    136:        size:&shmem_size];
                    137:     shmem = GetShmem(self);
                    138:     if ( token == -1 )
                    139:        return IO_R_INVALID_ARG;
                    140:     // We allow the shmem_size to be less than sizeof(StdFBShmem_t)
                    141:     // so that we need not consume the extra space that some of the
                    142:     // larger cursor variants require if we are really a lower bitdepth.
                    143:     if ( shmem_size > sizeof(StdFBShmem_t) )
                    144:     {
                    145:        IOLog("%s: shmem_size > sizeof (StdFBShmem_t)(%d<>%d)\n",
                    146:            [self name], shmem_size, sizeof (StdFBShmem_t));
                    147:        [[EventDriver instance] unregisterScreen:token];
                    148:        return IO_R_INVALID_ARG;
                    149:     }
                    150:     // Init shared memory area
                    151:     memset((char *)shmem, 0, shmem_size);
                    152:     shmem->cursorShow = 1;
                    153:     shmem->screenBounds = bounds;
                    154:     [self setToken:token];
                    155:     cursorShmemBitsPerPixel = [self displayInfo]->bitsPerPixel;
                    156:     cursorBitsPerPixel = cursorShmemBitsPerPixel;
                    157:     return IO_R_SUCCESS;
                    158: }
                    159: 
                    160: #define short34to35WithGamma(x) \
                    161:        (  (_bm34To35SampleTable[((x) & 0x00F0) >> 4])          \
                    162:         | (_bm34To35SampleTable[((x) & 0x0F00) >> 8] << 5)     \
                    163:         | (_bm34To35SampleTable[(x) >> 12] << 10) )
                    164: 
                    165: #define short35to34WithGamma(x) \
                    166:        (  0x000F                                               \
                    167:         | (_bm35To34SampleTable[x & 0x001F] << 4)              \
                    168:         | (_bm35To34SampleTable[(x & 0x03E0) >> 5] << 8)       \
                    169:         | (_bm35To34SampleTable[(x & 0x7C00) >> 10] << 12) )
                    170: 
                    171: static void StdFBDisplayCursor16(IOFramebuffer *inst)
                    172: // Description: Displays the cursor on the framebuffer by first saving
                    173: //             what's underneath the cursor, then drawing the cursor there.
                    174: //             NOTE:The topleft of the cursorRect passed in is not
                    175: //             necessarily the cursor location.The cursorRect is adjusted to
                    176: //             compensate for the cursor hotspot.If the frame buffer is
                    177: //             cacheable, flush at the end of the drawing operation. A
                    178: //             saveRect is stored which defines the actual area of the screen
                    179: //             that is saved.This is used by RemoveCursor in restoring the
                    180: //             screen data later.
                    181: {
                    182:     IODisplayInfo *dpy;
                    183:     StdFBShmem_t *shmem;
                    184:     vm_offset_t startPtr;              /* Starting screen data pointer */
                    185:     unsigned int vramRow;
                    186:     Bounds saveRect;
                    187:     short i, j, width, cursRow;
                    188:     unsigned short *vramPtr;   /* screen data pointer */
                    189:     volatile unsigned short *savePtr;  /* saved screen data pointer */
                    190:     unsigned short s, d, f;
                    191:     volatile unsigned short *cursPtr;
                    192:     unsigned char *_bm34To35SampleTable;
                    193:     unsigned char *_bm35To34SampleTable;
                    194: 
                    195:     dpy = [inst displayInfo];
                    196:     shmem = GetShmem(inst);
                    197:     saveRect = shmem->cursorRect;
                    198:     /* Clip saveRect vertical within screen bounds */
                    199:     if (saveRect.miny < shmem->screenBounds.miny)
                    200:        saveRect.miny = shmem->screenBounds.miny;
                    201:     if (saveRect.maxy > shmem->screenBounds.maxy)
                    202:        saveRect.maxy = shmem->screenBounds.maxy;
                    203:     if (saveRect.minx < shmem->screenBounds.minx)
                    204:        saveRect.minx = shmem->screenBounds.minx;
                    205:     if (saveRect.maxx > shmem->screenBounds.maxx)
                    206:        saveRect.maxx = shmem->screenBounds.maxx;
                    207:     shmem->saveRect = saveRect; /* Remember save rect for RemoveCursor */
                    208: 
                    209:     vramRow = dpy->totalWidth; /* Scanline width in pixels */
                    210:     vramPtr = (unsigned short *)dpy->frameBuffer + 
                    211:         (vramRow * (saveRect.miny - shmem->screenBounds.miny)) +
                    212:        (saveRect.minx - shmem->screenBounds.minx);
                    213:     startPtr = (vm_offset_t) vramPtr;
                    214:     width = saveRect.maxx - saveRect.minx;
                    215:     vramRow -= width;
                    216:     
                    217:     cursRow = CURSORWIDTH - width;
                    218:     savePtr = shmem->cursor.rgb.save;
                    219:     cursPtr = shmem->cursor.rgb.image[shmem->frame];
                    220:     cursPtr += (saveRect.miny - shmem->cursorRect.miny) * CURSORWIDTH +
                    221:                (saveRect.minx - shmem->cursorRect.minx);
                    222: 
                    223:     if (dpy->bitsPerPixel == IO_12BitsPerPixel)
                    224:     {
                    225:        for (i = saveRect.maxy - saveRect.miny; --i != -1; ) {
                    226:            for (j = width; --j != -1; ) {
                    227:                d = *savePtr++ = *vramPtr;
                    228:                if ( (s = *cursPtr++) == 0 )
                    229:                {       /* Transparent black area.  Leave dst as is. */
                    230:                    ++vramPtr;
                    231:                    continue;
                    232:                }
                    233:                if ( (f = (~s) & (unsigned int)AMASK) == 0 )
                    234:                {       /* Opaque cursor pixel.  Mark it. */
                    235:                    *vramPtr++ = s;
                    236:                    continue;
                    237:                }
                    238:                /* Alpha is not 0 or 1.0.  Sover the cursor. */
                    239:                *vramPtr++ = s + (((((d & RBMASK)>>4)*f + GAMASK) & RBMASK)
                    240:                             | ((((d & GAMASK)*f+GAMASK)>>4) & GAMASK));
                    241:            }
                    242:            cursPtr += cursRow; /* starting point of next cursor line */
                    243:            vramPtr += vramRow; /* starting point of next screen line */
                    244:        }
                    245:     }
                    246:     else       // dpy->bitsPerPixel == IO_15BitsPerPixel
                    247:     {
                    248:        // These tables should always be set by the Window Server before
                    249:        // it enables cursor drawing.  If they're not set, it's an error.
                    250:         if (   (_bm34To35SampleTable = inst->_bm34To35SampleTable) == NULL
                    251:             || (_bm35To34SampleTable = inst->_bm35To34SampleTable) == NULL )
                    252:                return;
                    253:        for (i = saveRect.maxy - saveRect.miny; --i>=0; ) {
                    254:            for (j = width; --j>=0; ) {
                    255:                d = *savePtr++ = *vramPtr;
                    256:                if ( (s = *cursPtr++) == 0 )
                    257:                {       /* Transparent black area.  Leave dst as is. */
                    258:                    ++vramPtr;
                    259:                    continue;
                    260:                }
                    261:                if ( (f = (~s) & (unsigned int)AMASK) == 0 )
                    262:                {       /* Opaque cursor pixel.  Mark it. */
                    263:                    *vramPtr++ = short34to35WithGamma(s);
                    264:                    continue;
                    265:                }
                    266:                /* Alpha is not 0 or 1.0.  Sover the cursor. */
                    267:                d = short35to34WithGamma(d);
                    268:                d = s + (((((d & RBMASK)>>4)*f + GAMASK) & RBMASK)
                    269:                    | ((((d & GAMASK)*f+GAMASK)>>4) & GAMASK));
                    270:                *vramPtr++ = short34to35WithGamma(d);
                    271:            }
                    272:            cursPtr += cursRow; /* starting point of next cursor line */
                    273:            vramPtr += vramRow; /* starting point of next screen line */
                    274:        }
                    275:     }
                    276: }
                    277: 
                    278: static inline unsigned int MUL32(unsigned int a, unsigned int b)
                    279: {
                    280:     unsigned int v, w;
                    281: 
                    282:     v  = ((a & 0xff00ff00) >> 8) * b;
                    283:     v += ((v & 0xff00ff00) >> 8) + 0x00010001;
                    284:     w  = (a & 0x00ff00ff) * b;
                    285:     w += ((w & 0xff00ff00) >> 8) + 0x00010001;
                    286: 
                    287:     return (v & 0xff00ff00) | ((w >> 8) & 0x00ff00ff);
                    288: }
                    289: 
                    290: static inline unsigned char map32to256( unsigned char *directToLogical, unsigned int s)
                    291: {
                    292:     unsigned char logicalValue;
                    293: 
                    294:     if ((s ^ (s>>8)) & 0x00ffff00) {
                    295:        logicalValue =  directToLogical[(s>>24)        + 0] +
                    296:                        directToLogical[((s>>16)&0xff) + 256] +
                    297:                        directToLogical[((s>>8)&0xff)  + 512];
                    298:     } else {
                    299:        logicalValue =  directToLogical[(s>>24)        + 768];
                    300:     }
                    301:     return( directToLogical[ logicalValue + 1024 ]);           // final conversion from NeXT palette
                    302:                                                                // to actual palette
                    303: }
                    304: 
                    305: static void StdFBDisplayCursor8(IOFramebuffer *inst)
                    306: // Description: Displays the cursor on the framebuffer by first saving
                    307: //             what's underneath the cursor, then drawing the cursor there.
                    308: //             NOTE:The topleft of the cursorRect passed in is not
                    309: //             necessarily the cursor location.The cursorRect is adjusted to
                    310: //             compensate for the cursor hotspot.If the frame buffer is
                    311: //             cacheable, flush at the end of the drawing operation. A
                    312: //             saveRect is stored which defines the actual area of the screen
                    313: //             that is saved.This is used by RemoveCursor in restoring the
                    314: //             screen data later.
                    315: {
                    316:     IODisplayInfo *dpy;
                    317:     StdFBShmem_t *shmem;
                    318:     vm_offset_t startPtr;              /* Starting screen data pointer */
                    319:     unsigned int vramRow;
                    320:     Bounds saveRect;
                    321:     short i, j, width, cursRow;
                    322:     unsigned char *vramPtr;    /* screen data pointer */
                    323:     volatile unsigned char *savePtr;   /* saved screen data pointer */
                    324:     unsigned short s, d;
                    325:     unsigned char dst, alpha;
                    326:     unsigned int rgb32val;
                    327:     volatile unsigned char *cursPtr;
                    328:     volatile unsigned char *maskPtr;           /* cursor mask pointer */
                    329:     unsigned int *_bm256To38SampleTable = inst->_bm256To38SampleTable;
                    330:     unsigned char *_bm38To256SampleTable = inst->_bm38To256SampleTable;
                    331: 
                    332:     dpy = [inst displayInfo];
                    333:     shmem = GetShmem(inst);
                    334:     saveRect = shmem->cursorRect;
                    335:     /* Clip saveRect vertical within screen bounds */
                    336:     if (saveRect.miny < shmem->screenBounds.miny)
                    337:        saveRect.miny = shmem->screenBounds.miny;
                    338:     if (saveRect.maxy > shmem->screenBounds.maxy)
                    339:        saveRect.maxy = shmem->screenBounds.maxy;
                    340:     if (saveRect.minx < shmem->screenBounds.minx)
                    341:        saveRect.minx = shmem->screenBounds.minx;
                    342:     if (saveRect.maxx > shmem->screenBounds.maxx)
                    343:        saveRect.maxx = shmem->screenBounds.maxx;
                    344:     shmem->saveRect = saveRect; /* Remember save rect for RemoveCursor */
                    345: 
                    346:     vramRow = dpy->totalWidth; /* Scanline width in pixels */
                    347:     vramPtr = (unsigned char *)dpy->frameBuffer + 
                    348:         (vramRow * (saveRect.miny - shmem->screenBounds.miny)) +
                    349:        (saveRect.minx - shmem->screenBounds.minx);
                    350:     startPtr = (vm_offset_t) vramPtr;
                    351:     width = saveRect.maxx - saveRect.minx;
                    352:     vramRow -= width;
                    353:     
                    354:     cursRow = CURSORWIDTH - width;
                    355:     savePtr = shmem->cursor.bw8.save;
                    356:     cursPtr = shmem->cursor.bw8.image[shmem->frame];
                    357:     maskPtr = shmem->cursor.bw8.mask[shmem->frame];
                    358:     i = (saveRect.miny - shmem->cursorRect.miny) * CURSORWIDTH +
                    359:        (saveRect.minx - shmem->cursorRect.minx);
                    360:     cursPtr += i;
                    361:     maskPtr += i;
                    362: 
                    363:     if (dpy->colorSpace == IO_OneIsWhiteColorSpace) {
                    364:        for (i = saveRect.maxy - saveRect.miny; --i>=0; ) {
                    365:            for (j = width; --j>=0; ) {
                    366:                int t;
                    367:                d = *savePtr++ = *vramPtr;
                    368:                s = *cursPtr++;
                    369:                t = d * (255 - *maskPtr++);
                    370:                d = s + ((t + (t >> 8) + 1) >> 8);
                    371:                *vramPtr++ = d;
                    372:            }
                    373:            cursPtr += cursRow; /* starting point of next cursor line */
                    374:            maskPtr += cursRow;
                    375:            vramPtr += vramRow; /* starting point of next screen line */
                    376:        }
                    377:     } else { // dpy->colorSpace == IO_RGBColorSpace 
                    378:        for (i = saveRect.maxy - saveRect.miny; --i>=0; ) {
                    379:            for (j = width; --j>=0; savePtr++,maskPtr++,cursPtr++,vramPtr++) {
                    380:                *savePtr = *vramPtr;
                    381:                if (alpha = *maskPtr) {
                    382:                    dst = *cursPtr;
                    383:                    if (alpha = ~alpha) {
                    384:                        rgb32val = _bm256To38SampleTable[*vramPtr];
                    385:                        rgb32val = (_bm256To38SampleTable[dst] & ~0xff) +
                    386:                                   MUL32(rgb32val, alpha);
                    387:                        dst = map32to256(_bm38To256SampleTable, rgb32val);
                    388:                    }
                    389:                    *vramPtr = dst;
                    390:                }
                    391:            }
                    392:            cursPtr += cursRow; /* starting point of next cursor line */
                    393:            maskPtr += cursRow;
                    394:            vramPtr += vramRow; /* starting point of next screen line */
                    395:        }
                    396:     }
                    397: }
                    398: 
                    399: static void StdFBRemoveCursor16(IOFramebuffer *inst)
                    400: // Description:        RemoveCursor erases the cursor by replacing the background
                    401: //             image that was saved by the previous call to DisplayCursor.
                    402: //             If the frame buffer is cacheable, flush at the end of the
                    403: //             drawing operation.
                    404: {
                    405:     IODisplayInfo *dpy;
                    406:     StdFBShmem_t *shmem;
                    407:     short i, j, width;
                    408:     vm_offset_t startPtr;
                    409:     unsigned int vramRow;
                    410:     Bounds saveRect;
                    411:     unsigned short *vramPtr;
                    412:     volatile unsigned short *savePtr;
                    413: 
                    414:     dpy = [inst displayInfo];
                    415:     shmem = GetShmem(inst);
                    416:     saveRect = shmem->saveRect;
                    417:     vramRow = dpy->totalWidth; /* Scanline width in pixels */
                    418:     vramPtr = (unsigned short *)dpy->frameBuffer +
                    419:         (vramRow * (saveRect.miny - shmem->screenBounds.miny))
                    420:        + (saveRect.minx - shmem->screenBounds.minx);
                    421:     width = saveRect.maxx - saveRect.minx;
                    422:     vramRow -= width;
                    423:     savePtr = shmem->cursor.rgb.save;
                    424:     startPtr = (vm_offset_t) vramPtr;
                    425:     for (i = saveRect.maxy - saveRect.miny; --i != -1; ) {
                    426:        for (j = width; --j != -1; )
                    427:            *vramPtr++ = *savePtr++;
                    428:        vramPtr += vramRow;
                    429:     }
                    430: }
                    431: 
                    432: static void StdFBRemoveCursor8(IOFramebuffer *inst)
                    433: // Description:        RemoveCursor erases the cursor by replacing the background
                    434: //             image that was saved by the previous call to DisplayCursor.
                    435: //             If the frame buffer is cacheable, flush at the end of the
                    436: //             drawing operation.
                    437: {
                    438:     IODisplayInfo *dpy;
                    439:     StdFBShmem_t *shmem;
                    440:     short i, j, width;
                    441:     vm_offset_t startPtr;
                    442:     unsigned int vramRow;
                    443:     Bounds saveRect;
                    444:     unsigned char *vramPtr;
                    445:     volatile unsigned char *savePtr;
                    446: 
                    447:     dpy = [inst displayInfo];
                    448:     shmem = GetShmem(inst);
                    449:     saveRect = shmem->saveRect;
                    450:     vramRow = dpy->totalWidth; /* Scanline width in pixels */
                    451:     vramPtr = (unsigned char *)dpy->frameBuffer +
                    452:         (vramRow * (saveRect.miny - shmem->screenBounds.miny))
                    453:        + (saveRect.minx - shmem->screenBounds.minx);
                    454:     width = saveRect.maxx - saveRect.minx;
                    455:     vramRow -= width;
                    456:     savePtr = shmem->cursor.bw8.save;
                    457:     startPtr = (vm_offset_t) vramPtr;
                    458:     for (i = saveRect.maxy - saveRect.miny; --i != -1; ) {
                    459:        for (j = width; --j != -1; )
                    460:            *vramPtr++ = *savePtr++;
                    461:        vramPtr += vramRow;
                    462:     }
                    463: }
                    464: 
                    465: static void StdFBDisplayCursor32(IOFramebuffer *inst)
                    466: {
                    467:     IODisplayInfo *dpy;
                    468:     StdFBShmem_t *shmem;
                    469:     unsigned int vramRow;
                    470:     Bounds saveRect;
                    471:     int i, j, width, cursRow;
                    472:     unsigned int *vramPtr;     /* screen data pointer */
                    473:     volatile unsigned int *savePtr;    /* saved screen data pointer */
                    474:     unsigned int s, d, f;
                    475:     volatile unsigned int *cursPtr;
                    476: 
                    477:     dpy = [inst displayInfo];
                    478:     shmem = GetShmem(inst);
                    479:     saveRect = shmem->cursorRect;
                    480:     /* Clip saveRect vertical within screen bounds */
                    481:     if (saveRect.miny < shmem->screenBounds.miny)
                    482:        saveRect.miny = shmem->screenBounds.miny;
                    483:     if (saveRect.maxy > shmem->screenBounds.maxy)
                    484:        saveRect.maxy = shmem->screenBounds.maxy;
                    485:     if (saveRect.minx < shmem->screenBounds.minx)
                    486:        saveRect.minx = shmem->screenBounds.minx;
                    487:     if (saveRect.maxx > shmem->screenBounds.maxx)
                    488:        saveRect.maxx = shmem->screenBounds.maxx;
                    489:     shmem->saveRect = saveRect; /* Remember save rect for RemoveCursor */
                    490: 
                    491:     vramRow = dpy->totalWidth; /* Scanline width in pixels */
                    492:     vramPtr = (unsigned int *)dpy->frameBuffer + 
                    493:         (vramRow * (saveRect.miny - shmem->screenBounds.miny)) +
                    494:        (saveRect.minx - shmem->screenBounds.minx);
                    495:     width = saveRect.maxx - saveRect.minx;
                    496:     vramRow -= width;
                    497:     
                    498:     cursRow = CURSORWIDTH - width;
                    499:     savePtr = shmem->cursor.rgb24.save;
                    500:     cursPtr = shmem->cursor.rgb24.image[shmem->frame];
                    501:     cursPtr += (saveRect.miny - shmem->cursorRect.miny) * CURSORWIDTH +
                    502:                (saveRect.minx - shmem->cursorRect.minx);
                    503: 
                    504:     if (dpy->pixelEncoding[0] == IO_SampleTypeAlpha ||
                    505:        dpy->pixelEncoding[0] == IO_SampleTypeSkip) {
                    506:        /* Pixel format is Axxx */
                    507:        for (i = saveRect.maxy - saveRect.miny; --i != -1; ) {
                    508:            for (j = width; --j != -1; ) {
                    509:                d = *savePtr++ = *vramPtr;
                    510:                s = *cursPtr++;
                    511:                f = s >> 24;
                    512:                if (f) {
                    513:                    if (f == 0xff)              // Opaque pixel
                    514:                        *vramPtr++ = s;
                    515:                    else {                      // SOVER the cursor pixel
                    516:                        s <<= 8;  d <<= 8;   /* Now pixels are xxxA */
                    517:                        f ^= 0xFF;
                    518:                        d = s+(((((d&0xFF00FF00)>>8)*f+0x00FF00FF)&0xFF00FF00)
                    519:                            | ((((d & 0x00FF00FF)*f+0x00FF00FF)>>8) &
                    520:                                0x00FF00FF));
                    521:                        *vramPtr++ = (d>>8) | 0xff000000;
                    522:                    }
                    523:                } else                  // Transparent cursor pixel
                    524:                    vramPtr++;
                    525:            }
                    526:            cursPtr += cursRow; /* starting point of next cursor line */
                    527:            vramPtr += vramRow; /* starting point of next screen line */
                    528:        }
                    529:     } else {
                    530:        /* Pixel format is xxxA */
                    531:        for (i = saveRect.maxy - saveRect.miny; --i != -1; ) {
                    532:            for (j = width; --j != -1; ) {
                    533:                d = *savePtr++ = *vramPtr;
                    534:                s = *cursPtr++;
                    535:                f = s & (unsigned int)0xFF;
                    536:                if (f) {
                    537:                    if (f == 0xff)              // Opaque pixel
                    538:                        *vramPtr++ = s;
                    539:                    else {                      // SOVER the cursor pixel
                    540:                        f ^= 0xFF;
                    541:                        d = s+(((((d&0xFF00FF00)>>8)*f+0x00FF00FF)&0xFF00FF00)
                    542:                            | ((((d & 0x00FF00FF)*f+0x00FF00FF)>>8) &
                    543:                                0x00FF00FF));
                    544:                        *vramPtr++ = d;
                    545:                    }
                    546:                } else                  // Transparent cursor pixel
                    547:                    vramPtr++;
                    548:            }
                    549:            cursPtr += cursRow; /* starting point of next cursor line */
                    550:            vramPtr += vramRow; /* starting point of next screen line */
                    551:        }
                    552:     }
                    553: }
                    554: 
                    555: static void StdFBRemoveCursor32(IOFramebuffer *inst)
                    556: {
                    557:     IODisplayInfo *dpy;
                    558:     StdFBShmem_t *shmem;
                    559:     int i, j, width;
                    560:     unsigned int vramRow;
                    561:     Bounds saveRect;
                    562:     unsigned int *vramPtr;
                    563:     unsigned int *savePtr;
                    564: 
                    565:     dpy = [inst displayInfo];
                    566:     shmem = GetShmem(inst);
                    567:     saveRect = shmem->saveRect;
                    568:     vramRow = dpy->totalWidth; /* Scanline width in pixels */
                    569:     vramPtr = (unsigned int *)dpy->frameBuffer +
                    570:         (vramRow * (saveRect.miny - shmem->screenBounds.miny))
                    571:        + (saveRect.minx - shmem->screenBounds.minx);
                    572:     width = saveRect.maxx - saveRect.minx;
                    573:     vramRow -= width;
                    574:     savePtr = (unsigned int *)shmem->cursor.rgb24.save;
                    575:     for (i = saveRect.maxy - saveRect.miny; --i != -1; ) {
                    576:        for (j = width; --j != -1; )
                    577:            *vramPtr++ = *savePtr++;
                    578:        vramPtr += vramRow;
                    579:     }
                    580: }
                    581: 
                    582: static inline void StdFBDisplayCursor(IOFramebuffer *inst) 
                    583: {
                    584:     switch (inst->cursorBitsPerPixel) {
                    585:        default:
                    586:        case IO_12BitsPerPixel:
                    587:        case IO_15BitsPerPixel:
                    588:            StdFBDisplayCursor16(inst);
                    589:            break;
                    590:        case IO_8BitsPerPixel:
                    591:            StdFBDisplayCursor8(inst);
                    592:            break;
                    593:        case IO_24BitsPerPixel:
                    594:            StdFBDisplayCursor32(inst);
                    595:        case (-1):
                    596:            break;
                    597:     }
                    598: }
                    599: 
                    600: static inline void StdFBRemoveCursor(IOFramebuffer *inst) 
                    601: {
                    602:     switch (inst->cursorBitsPerPixel) {
                    603:        default:
                    604:        case IO_12BitsPerPixel:
                    605:        case IO_15BitsPerPixel:
                    606:            StdFBRemoveCursor16(inst);
                    607:            break;
                    608:        case IO_8BitsPerPixel:
                    609:            StdFBRemoveCursor8(inst);
                    610:            break;
                    611:        case IO_24BitsPerPixel:
                    612:            StdFBRemoveCursor32(inst);
                    613:        case (-1):
                    614:            break;
                    615:     }
                    616: }
                    617: 
                    618: 
                    619: #define RemoveCursor(inst)     StdFBRemoveCursor(inst)
                    620: static inline void DisplayCursor(IOFramebuffer *inst)
                    621: {
                    622:     Point hs;
                    623:     StdFBShmem_t *shmem;
                    624: 
                    625:     shmem = GetShmem(inst);
                    626:     hs = shmem->hotSpot[shmem->frame];
                    627:     shmem->cursorRect.maxx =
                    628:         (shmem->cursorRect.minx = (shmem->cursorLoc).x - hs.x) + 16;
                    629:     shmem->cursorRect.maxy =
                    630:         (shmem->cursorRect.miny = (shmem->cursorLoc).y - hs.y) + 16;
                    631:     StdFBDisplayCursor(inst);
                    632:     shmem->oldCursorRect = shmem->cursorRect;
                    633: }
                    634: 
                    635: static inline void SysHideCursor(IOFramebuffer *inst)
                    636: {
                    637:     if (!GetShmem(inst)->cursorShow++)
                    638:        RemoveCursor(inst);
                    639: }
                    640: 
                    641: static inline void SysShowCursor(IOFramebuffer *inst)
                    642: {
                    643:     if (GetShmem(inst)->cursorShow)
                    644:        if (!--(GetShmem(inst)->cursorShow))
                    645:            DisplayCursor(inst);
                    646: }
                    647: 
                    648: static inline void CheckShield(IOFramebuffer *inst)
                    649: {
                    650:     Point hs;
                    651:     int intersect;
                    652:     Bounds tempRect;
                    653:     StdFBShmem_t *shmem;
                    654:     
                    655:     shmem = GetShmem(inst);
                    656:     /* Calculate temp cursorRect */
                    657:     hs = shmem->hotSpot[shmem->frame];
                    658:     tempRect.maxx = (tempRect.minx = (shmem->cursorLoc).x - hs.x) + 16;
                    659:     tempRect.maxy = (tempRect.miny = (shmem->cursorLoc).y - hs.y) + 16;
                    660: 
                    661:     intersect = TOUCHBOUNDS(tempRect, shmem->shieldRect);
                    662:     if (intersect != shmem->shielded)
                    663:        (shmem->shielded = intersect) ?
                    664:            SysHideCursor(inst) : SysShowCursor(inst);
                    665: }
                    666: //
                    667: // END:                Generic utility routines
                    668: //
                    669: 
                    670: 
                    671: //
                    672: // BEGIN:      Implementation of the evScreen protocol
                    673: //
                    674: - hideCursor: (int)token
                    675: {
                    676:     SETSEMA(GetShmem(self));
                    677:     SysHideCursor(self);
                    678:     CLEARSEMA(GetShmem(self));
                    679:     return self;
                    680: }
                    681: 
                    682: - moveCursor:(Point*)cursorLoc frame:(int)frame token:(int)t
                    683: {
                    684:     StdFBShmem_t *shmem;
                    685:     
                    686:     shmem = GetShmem(self);
                    687:     SETSEMA(shmem);
                    688:     shmem->frame = frame;
                    689:     shmem->cursorLoc = *cursorLoc;
                    690:     if (!shmem->cursorShow++)
                    691:        RemoveCursor(self);
                    692:     if (shmem->cursorObscured) {
                    693:        shmem->cursorObscured = 0;
                    694:        if (shmem->cursorShow)
                    695:            --shmem->cursorShow;
                    696:     }
                    697:     if (shmem->shieldFlag) CheckShield(self);
                    698:     if (shmem->cursorShow)
                    699:        if (!--shmem->cursorShow)
                    700:            DisplayCursor(self);
                    701:     CLEARSEMA(shmem);
                    702:     return self;
                    703: }
                    704: 
                    705: - showCursor:(Point*)cursorLoc frame:(int)frame token:(int)t
                    706: {
                    707:     StdFBShmem_t *shmem;
                    708:     
                    709:     shmem = GetShmem(self);
                    710:     SETSEMA(GetShmem(self));
                    711:     shmem->frame = frame;
                    712:     shmem->cursorLoc = *cursorLoc;
                    713:     if (shmem->shieldFlag) CheckShield(self);
                    714:     SysShowCursor(self);
                    715:     CLEARSEMA(shmem);
                    716:     return self;
                    717: }
                    718: 
                    719: - setBrightness:(int)level token:(int)t
                    720: {
                    721:     if ( level < EV_SCREEN_MIN_BRIGHTNESS
                    722:        || level > EV_SCREEN_MAX_BRIGHTNESS )
                    723:     {
                    724:        IOLog("%s: Invalid arg to setBrightness:%d\n",
                    725:            [self name], level );
                    726:     }
                    727:     return self;
                    728: }
                    729: //
                    730: // END:                Implementation of the evScreen protocol
                    731: //
                    732: //
                    733: // BEGIN:      EXPORTED Methods
                    734: //
                    735: 
                    736: - initFromDeviceDescription:deviceDescription
                    737: {
                    738:     extern int sprintf(char *s, const char *format, ...);
                    739:     static int nextUnit = 0;
                    740:     char nameBuf[20];
                    741: 
                    742:     if ([super initFromDeviceDescription:deviceDescription] == nil)
                    743:        return [super free];
                    744: 
                    745:     _pendingDisplayMode = -1;
                    746:     
                    747:     sprintf(nameBuf, "Display%d", nextUnit);
                    748:     [self setUnit: nextUnit++];
                    749:     [self setName:nameBuf];
                    750:     return self;
                    751: }
                    752: 
                    753: - (IOConsoleInfo *)allocateConsoleInfo;
                    754: // Description:        Allocates a console support info structure based on this
                    755: //             display. This structure, and the functions in it, are used
                    756: //             to display alert and console windows.
                    757: {
                    758:     return FBAllocateConsole([self displayInfo]);
                    759: }
                    760: 
                    761: static const char *
                    762: find_parameter(const char *parameter, const char *string)
                    763: {
                    764:     int c;
                    765:     size_t length;
                    766: 
                    767:     length = strlen(parameter);
                    768:     while (*string != 0) {
                    769:        if (strncmp(string, parameter, length) == 0) {
                    770:            string += length;
                    771:            while ((c = *string) != '\0' && (c == ' ' || c == '\t'))
                    772:                string++;
                    773:            return (c != 0) ? string : 0;
                    774:        }
                    775:        string++;
                    776:     }
                    777:     return 0;
                    778: }
                    779: 
                    780: 
                    781: static UInt32
                    782: ActiveBytes( IODisplayInfo * displayInfo )
                    783: {
                    784:     UInt32     bytesPerPixel;
                    785: 
                    786:     switch( displayInfo->bitsPerPixel) {
                    787:        case IO_8BitsPerPixel:
                    788:            bytesPerPixel  = 1;
                    789:            break;
                    790:        case IO_15BitsPerPixel:
                    791:            bytesPerPixel  = 2;
                    792:            break;
                    793:        case IO_24BitsPerPixel:
                    794:        default:
                    795:            bytesPerPixel  = 4;
                    796:            break;
                    797:     }
                    798:     // The last line may not have the full rowBytes physically present,
                    799:     // only the active pixels.
                    800:     return( displayInfo->rowBytes * (displayInfo->height - 1)
                    801:          + (displayInfo->width * bytesPerPixel));
                    802: }
                    803: 
                    804: - convertPixelInfoToDisplayInfo:(IOFBPixelInformation *)pixelInfo mono:(BOOL)mono
                    805:        displayInfo:(IODisplayInfo *)displayInfo
                    806: {
                    807:     IOBitsPerPixel     nextDepth;
                    808:     const char *       nextPixels;
                    809:     IOColorSpace       nextCSpace;
                    810:     static const char * apple8BitMonoEncoding = "WWWWWWWW";
                    811:     static const char * apple8BitEncoding = "PPPPPPPP";
                    812:     static const char * apple16BitEncoding = "-RRRRRGGGGGBBBBB";
                    813:     static const char *        apple32BitEncoding = "--------RRRRRRRRGGGGGGGGBBBBBBBB";
                    814: 
                    815:     nextCSpace = IO_RGBColorSpace;
                    816: 
                    817:     switch( pixelInfo->bitsPerPixel ) {
                    818:        default:
                    819:        case 8:
                    820:            nextDepth   = IO_8BitsPerPixel;
                    821:            if( mono) {
                    822:                nextCSpace = IO_OneIsWhiteColorSpace;
                    823:                nextPixels = apple8BitMonoEncoding;
                    824:            } else {
                    825:                nextPixels  = apple8BitEncoding;
                    826:            }
                    827:            break;
                    828:        case 16:
                    829:            nextDepth   = IO_15BitsPerPixel;
                    830:            nextPixels  = apple16BitEncoding;
                    831:            break;
                    832:        case 32:
                    833:            nextDepth   = IO_24BitsPerPixel;
                    834:            nextPixels  = apple32BitEncoding;
                    835:            break;
                    836:     }
                    837: 
                    838:     bzero(displayInfo, sizeof(IODisplayInfo));
                    839: 
                    840:     strncpy(displayInfo->pixelEncoding, nextPixels, strlen(nextPixels));
                    841:     displayInfo->width = pixelInfo->width;
                    842:     displayInfo->height = pixelInfo->height;
                    843:     displayInfo->rowBytes = pixelInfo->rowBytes;
                    844:     displayInfo->totalWidth = (pixelInfo->rowBytes * 8) / pixelInfo->bitsPerPixel;
                    845:     displayInfo->refreshRate = (pixelInfo->refreshRate + 0x8000) >> 16;
                    846:     displayInfo->bitsPerPixel = nextDepth;
                    847:     displayInfo->colorSpace = nextCSpace;
                    848:     displayInfo->flags = IO_DISPLAY_HAS_TRANSFER_TABLE
                    849:                           | [self tempFlags];
                    850:     return( self);
                    851: }
                    852: 
                    853: - (IOReturn) getNextMode:(IOFBIndex *)index modeInfo:(IOFBDisplayModeInformation *)modeInfo needFlags:(UInt32)needFlags
                    854: {
                    855:     IOReturn                   err;
                    856:     IOFBDisplayModeID          modeID;
                    857:     IOFBTimingInformation      timingInfo;
                    858:     UInt32                     flags;
                    859: 
                    860:     do {
                    861:        err = [self getDisplayModeByIndex:(*index)++ displayMode:&modeID];
                    862:        if( err)
                    863:            break;
                    864:        err = [self getDisplayModeInformation:modeID info:modeInfo];
                    865:        if( err)
                    866:            break;
                    867: 
                    868:        err = [self getDisplayModeTiming:0 mode:modeID timingInfo:&timingInfo connectFlags:&flags];
                    869: 
                    870:     } while( (err == noErr) && ((flags & needFlags) != needFlags) );
                    871: 
                    872:     return( err);
                    873: }
                    874: 
                    875: // Apple standard 8-bit CLUT
                    876: 
                    877: const UInt8 appleClut8[ 256 * 3 ] = {
                    878:        0xFF,0xFF,0xFF, 0xFF,0xFF,0xCC, 0xFF,0xFF,0x99, 0xFF,0xFF,0x66,
                    879:        0xFF,0xFF,0x33, 0xFF,0xFF,0x00, 0xFF,0xCC,0xFF, 0xFF,0xCC,0xCC,
                    880:        0xFF,0xCC,0x99, 0xFF,0xCC,0x66, 0xFF,0xCC,0x33, 0xFF,0xCC,0x00,
                    881:        0xFF,0x99,0xFF, 0xFF,0x99,0xCC, 0xFF,0x99,0x99, 0xFF,0x99,0x66,
                    882:        0xFF,0x99,0x33, 0xFF,0x99,0x00, 0xFF,0x66,0xFF, 0xFF,0x66,0xCC,
                    883:        0xFF,0x66,0x99, 0xFF,0x66,0x66, 0xFF,0x66,0x33, 0xFF,0x66,0x00,
                    884:        0xFF,0x33,0xFF, 0xFF,0x33,0xCC, 0xFF,0x33,0x99, 0xFF,0x33,0x66,
                    885:        0xFF,0x33,0x33, 0xFF,0x33,0x00, 0xFF,0x00,0xFF, 0xFF,0x00,0xCC,
                    886:        0xFF,0x00,0x99, 0xFF,0x00,0x66, 0xFF,0x00,0x33, 0xFF,0x00,0x00,
                    887:        0xCC,0xFF,0xFF, 0xCC,0xFF,0xCC, 0xCC,0xFF,0x99, 0xCC,0xFF,0x66,
                    888:        0xCC,0xFF,0x33, 0xCC,0xFF,0x00, 0xCC,0xCC,0xFF, 0xCC,0xCC,0xCC,
                    889:        0xCC,0xCC,0x99, 0xCC,0xCC,0x66, 0xCC,0xCC,0x33, 0xCC,0xCC,0x00,
                    890:        0xCC,0x99,0xFF, 0xCC,0x99,0xCC, 0xCC,0x99,0x99, 0xCC,0x99,0x66,
                    891:        0xCC,0x99,0x33, 0xCC,0x99,0x00, 0xCC,0x66,0xFF, 0xCC,0x66,0xCC,
                    892:        0xCC,0x66,0x99, 0xCC,0x66,0x66, 0xCC,0x66,0x33, 0xCC,0x66,0x00,
                    893:        0xCC,0x33,0xFF, 0xCC,0x33,0xCC, 0xCC,0x33,0x99, 0xCC,0x33,0x66,
                    894:        0xCC,0x33,0x33, 0xCC,0x33,0x00, 0xCC,0x00,0xFF, 0xCC,0x00,0xCC,
                    895:        0xCC,0x00,0x99, 0xCC,0x00,0x66, 0xCC,0x00,0x33, 0xCC,0x00,0x00,
                    896:        0x99,0xFF,0xFF, 0x99,0xFF,0xCC, 0x99,0xFF,0x99, 0x99,0xFF,0x66,
                    897:        0x99,0xFF,0x33, 0x99,0xFF,0x00, 0x99,0xCC,0xFF, 0x99,0xCC,0xCC,
                    898:        0x99,0xCC,0x99, 0x99,0xCC,0x66, 0x99,0xCC,0x33, 0x99,0xCC,0x00,
                    899:        0x99,0x99,0xFF, 0x99,0x99,0xCC, 0x99,0x99,0x99, 0x99,0x99,0x66,
                    900:        0x99,0x99,0x33, 0x99,0x99,0x00, 0x99,0x66,0xFF, 0x99,0x66,0xCC,
                    901:        0x99,0x66,0x99, 0x99,0x66,0x66, 0x99,0x66,0x33, 0x99,0x66,0x00,
                    902:        0x99,0x33,0xFF, 0x99,0x33,0xCC, 0x99,0x33,0x99, 0x99,0x33,0x66,
                    903:        0x99,0x33,0x33, 0x99,0x33,0x00, 0x99,0x00,0xFF, 0x99,0x00,0xCC,
                    904:        0x99,0x00,0x99, 0x99,0x00,0x66, 0x99,0x00,0x33, 0x99,0x00,0x00,
                    905:        0x66,0xFF,0xFF, 0x66,0xFF,0xCC, 0x66,0xFF,0x99, 0x66,0xFF,0x66,
                    906:        0x66,0xFF,0x33, 0x66,0xFF,0x00, 0x66,0xCC,0xFF, 0x66,0xCC,0xCC,
                    907:        0x66,0xCC,0x99, 0x66,0xCC,0x66, 0x66,0xCC,0x33, 0x66,0xCC,0x00,
                    908:        0x66,0x99,0xFF, 0x66,0x99,0xCC, 0x66,0x99,0x99, 0x66,0x99,0x66,
                    909:        0x66,0x99,0x33, 0x66,0x99,0x00, 0x66,0x66,0xFF, 0x66,0x66,0xCC,
                    910:        0x66,0x66,0x99, 0x66,0x66,0x66, 0x66,0x66,0x33, 0x66,0x66,0x00,
                    911:        0x66,0x33,0xFF, 0x66,0x33,0xCC, 0x66,0x33,0x99, 0x66,0x33,0x66,
                    912:        0x66,0x33,0x33, 0x66,0x33,0x00, 0x66,0x00,0xFF, 0x66,0x00,0xCC,
                    913:        0x66,0x00,0x99, 0x66,0x00,0x66, 0x66,0x00,0x33, 0x66,0x00,0x00,
                    914:        0x33,0xFF,0xFF, 0x33,0xFF,0xCC, 0x33,0xFF,0x99, 0x33,0xFF,0x66,
                    915:        0x33,0xFF,0x33, 0x33,0xFF,0x00, 0x33,0xCC,0xFF, 0x33,0xCC,0xCC,
                    916:        0x33,0xCC,0x99, 0x33,0xCC,0x66, 0x33,0xCC,0x33, 0x33,0xCC,0x00,
                    917:        0x33,0x99,0xFF, 0x33,0x99,0xCC, 0x33,0x99,0x99, 0x33,0x99,0x66,
                    918:        0x33,0x99,0x33, 0x33,0x99,0x00, 0x33,0x66,0xFF, 0x33,0x66,0xCC,
                    919:        0x33,0x66,0x99, 0x33,0x66,0x66, 0x33,0x66,0x33, 0x33,0x66,0x00,
                    920:        0x33,0x33,0xFF, 0x33,0x33,0xCC, 0x33,0x33,0x99, 0x33,0x33,0x66,
                    921:        0x33,0x33,0x33, 0x33,0x33,0x00, 0x33,0x00,0xFF, 0x33,0x00,0xCC,
                    922:        0x33,0x00,0x99, 0x33,0x00,0x66, 0x33,0x00,0x33, 0x33,0x00,0x00,
                    923:        0x00,0xFF,0xFF, 0x00,0xFF,0xCC, 0x00,0xFF,0x99, 0x00,0xFF,0x66,
                    924:        0x00,0xFF,0x33, 0x00,0xFF,0x00, 0x00,0xCC,0xFF, 0x00,0xCC,0xCC,
                    925:        0x00,0xCC,0x99, 0x00,0xCC,0x66, 0x00,0xCC,0x33, 0x00,0xCC,0x00,
                    926:        0x00,0x99,0xFF, 0x00,0x99,0xCC, 0x00,0x99,0x99, 0x00,0x99,0x66,
                    927:        0x00,0x99,0x33, 0x00,0x99,0x00, 0x00,0x66,0xFF, 0x00,0x66,0xCC,
                    928:        0x00,0x66,0x99, 0x00,0x66,0x66, 0x00,0x66,0x33, 0x00,0x66,0x00,
                    929:        0x00,0x33,0xFF, 0x00,0x33,0xCC, 0x00,0x33,0x99, 0x00,0x33,0x66,
                    930:        0x00,0x33,0x33, 0x00,0x33,0x00, 0x00,0x00,0xFF, 0x00,0x00,0xCC,
                    931:        0x00,0x00,0x99, 0x00,0x00,0x66, 0x00,0x00,0x33, 0xEE,0x00,0x00,
                    932:        0xDD,0x00,0x00, 0xBB,0x00,0x00, 0xAA,0x00,0x00, 0x88,0x00,0x00,
                    933:        0x77,0x00,0x00, 0x55,0x00,0x00, 0x44,0x00,0x00, 0x22,0x00,0x00,
                    934:        0x11,0x00,0x00, 0x00,0xEE,0x00, 0x00,0xDD,0x00, 0x00,0xBB,0x00,
                    935:        0x00,0xAA,0x00, 0x00,0x88,0x00, 0x00,0x77,0x00, 0x00,0x55,0x00,
                    936:        0x00,0x44,0x00, 0x00,0x22,0x00, 0x00,0x11,0x00, 0x00,0x00,0xEE,
                    937:        0x00,0x00,0xDD, 0x00,0x00,0xBB, 0x00,0x00,0xAA, 0x00,0x00,0x88,
                    938:        0x00,0x00,0x77, 0x00,0x00,0x55, 0x00,0x00,0x44, 0x00,0x00,0x22,
                    939:        0x00,0x00,0x11, 0xEE,0xEE,0xEE, 0xDD,0xDD,0xDD, 0xBB,0xBB,0xBB,
                    940:        0xAA,0xAA,0xAA, 0x88,0x88,0x88, 0x77,0x77,0x77, 0x55,0x55,0x55,
                    941:        0x44,0x44,0x44, 0x22,0x22,0x22, 0x11,0x11,0x11, 0x00,0x00,0x00
                    942: };
                    943: 
                    944: ///////////////////// Backwards compatibility goo /////////////////////
                    945: 
                    946: - (IOReturn) makeConfigList
                    947: {
                    948:     IOFBDisplayModeInformation info;
                    949:     IOFBPixelInformation       pixelInfo;
                    950:     IOFBIndex                  depth;
                    951:     struct ModeData    *       modeData;
                    952:     UInt32                     modeIndex;
                    953:     UInt32                     preflight;
                    954:     IOReturn                   err;
                    955:     enum {                     kNeedFlags = (kDisplayModeValidFlag /*| kDisplayModeSafeFlag */) };
                    956: 
                    957:     numModes = numConfigs = 0;
                    958:     preflight = 1;
                    959:     modeData = NULL;
                    960:     do {
                    961: 
                    962:        if( numModes) {
                    963:            modeData = IOMalloc( numModes * sizeof( struct ModeData));
                    964:            modeTable = modeData;
                    965:        }
                    966:        modeIndex = 0;
                    967:        while( (noErr == [self getNextMode:&modeIndex modeInfo:&info needFlags:kNeedFlags])) {
                    968: 
                    969:            if( modeData) {
                    970:                if( (modeData - modeTable) >= numModes)
                    971:                    kprintf("!!MODE LIST BAD!!\n");
                    972:                else {
                    973: 
                    974:                    depth = -1;
                    975:                    do {
                    976:                         err = [self getPixelInformationForDisplayMode:info.displayModeID andDepthIndex:++depth
                    977:                             pixelInfo:&pixelInfo];
                    978: 
                    979:                        if( (err == noErr) && (pixelInfo.bitsPerPixel >= 8)) {
                    980:                             modeData->modeID = info.displayModeID;
                    981:                            modeData->firstDepth = depth;
                    982:                             modeData->numDepths = 1 + info.maxDepthIndex - depth;
                    983:                             if( pixelInfo.bitsPerPixel == 8)
                    984:                                 modeData->numDepths++;                 // +MONO
                    985:                             numConfigs += modeData->numDepths;
                    986:                             modeData++;
                    987:                            break;
                    988:                        }
                    989:                    } while( (err == noErr) && (depth < info.maxDepthIndex));
                    990:                }
                    991:            } else
                    992:                numModes++;
                    993:        }
                    994:     } while( preflight--);
                    995: 
                    996:     return( noErr);
                    997: }
                    998: 
                    999: - (IOReturn) getDisplayModeAndDepthForIndex:(UInt32)configIndex
                   1000:        mode:(IOFBDisplayModeID *)mode depth:(IOFBIndex *)depth mono:(BOOL *)mono
                   1001: {
                   1002:     struct ModeData    *       modeData;
                   1003:     UInt32                     modeIndex;
                   1004: 
                   1005:     for( modeIndex = 0, modeData = modeTable;
                   1006:        modeIndex < numModes;
                   1007:        modeIndex++, modeData++) {
                   1008: 
                   1009:        if( configIndex < modeData->numDepths) {
                   1010:            *mode = modeData->modeID;
                   1011:            *mono = (configIndex == 0);
                   1012:            if( *mono)
                   1013:                *depth = modeData->firstDepth;
                   1014:            else
                   1015:                *depth = modeData->firstDepth + configIndex - 1;
                   1016:            return( noErr);
                   1017:        }
                   1018:        configIndex -= modeData->numDepths;
                   1019:     }
                   1020: 
                   1021:     return( IO_R_UNDEFINED_MODE);
                   1022: }
                   1023: 
                   1024: - (IOReturn) getConfigIndexForDisplayModeAndDepth:
                   1025:        (IOFBDisplayModeID)mode depth:(IOFBIndex)depth mono:(BOOL)mono
                   1026:         configIndex:(UInt32 *)configIndex
                   1027: {
                   1028:     UInt32                     index;
                   1029:     struct ModeData    *       modeData;
                   1030:     UInt32                     modeIndex;
                   1031: 
                   1032:     for( modeIndex = 0, modeData = modeTable, index = 0;
                   1033:        modeIndex < numModes;
                   1034:        modeIndex++, modeData++) {
                   1035: 
                   1036:        if( mode == modeData->modeID) {
                   1037:            if( depth <= modeData->firstDepth)          // 8 bpp mode
                   1038:                index += (mono ? 0 : 1);
                   1039:            else
                   1040:                index += depth - modeData->firstDepth + 1;
                   1041:            *configIndex = index;
                   1042:            return( noErr);
                   1043:        }
                   1044:        index += modeData->numDepths;
                   1045:     }
                   1046: 
                   1047:     return( IO_R_UNDEFINED_MODE);
                   1048: }
                   1049: 
                   1050: - (IOReturn) getCurrentConfigIndex:(UInt32 *)configIndex
                   1051: {
                   1052:     return( [self getConfigIndexForDisplayModeAndDepth:currentDisplayModeID
                   1053:                depth:currentDepthIndex mono:currentMono
                   1054:                configIndex:configIndex]);
                   1055: }
                   1056: 
                   1057: - (IOReturn) getDisplayInfoForConfigIndex:(UInt32)index info:(IODisplayInfo *)displayInfo
                   1058:                                                connectFlags:(UInt32 *)flags
                   1059: {
                   1060:     IOFBPixelInformation       pixelInfo;
                   1061:     IOReturn                   err;
                   1062:     IOFBDisplayModeID          mode;
                   1063:     IOFBIndex                  depth;
                   1064:     IOFBTimingInformation      timingInfo;
                   1065:     BOOL                       mono;
                   1066: 
                   1067:     err = [self getDisplayModeAndDepthForIndex:index
                   1068:                mode:&mode depth:&depth mono:&mono];
                   1069: 
                   1070:     if( err == noErr)
                   1071:        err = [self getPixelInformationForDisplayMode:mode andDepthIndex:depth
                   1072:            pixelInfo:&pixelInfo];
                   1073: 
                   1074:     if( err == noErr)
                   1075:        [self convertPixelInfoToDisplayInfo:&pixelInfo mono:mono displayInfo:displayInfo];
                   1076: 
                   1077:     if( flags &&
                   1078:         [self getDisplayModeTiming:0 mode:mode timingInfo:&timingInfo connectFlags:flags])
                   1079:             *flags = 0;
                   1080: 
                   1081:     return( err);
                   1082: }
                   1083: 
                   1084: ///////////////////////////////////////////////////////
                   1085: 
                   1086: - (IOReturn) open
                   1087: {
                   1088:     IOReturn                   err;
                   1089:     IOFBConfiguration          config;
                   1090:     IOFBTimingInformation      timingInfo;
                   1091:     IOFBDisplayModeID          startMode;
                   1092:     IOFBIndex                  startDepth;
                   1093:     UInt32                     startFlags = 0;
                   1094:     UInt32                     modeIndex;
                   1095:     IOFBDisplayModeInformation info;
                   1096: 
                   1097:     enum {                     kNeedFlags = (kDisplayModeValidFlag | kDisplayModeSafeFlag) };
                   1098: 
                   1099:     if( opened == NO) {
                   1100: 
                   1101:        opened = YES;
                   1102:        smartDisplay = [gSmartDisplayClass findForConnection:self refCon:0];
                   1103:        [self makeConfigList];
                   1104: 
                   1105:        // Check the startup mode with the display
                   1106: 
                   1107:        [self getConfiguration:&config];
                   1108:        err = [self getStartupMode:&startMode depth:&startDepth];
                   1109:        if( err) {
                   1110:            startMode = config.displayMode;
                   1111:            startDepth = config.depth;
                   1112:        }
                   1113: 
                   1114:        err = [self getDisplayModeInformation:startMode info:&info];
                   1115: 
                   1116:        if( err == noErr)
                   1117:            err = [self getDisplayModeTiming:0 mode:startMode
                   1118:                    timingInfo:&timingInfo connectFlags:&startFlags];
                   1119: 
                   1120:        if( err || ((startFlags & kDisplayModeValidFlag) != kDisplayModeValidFlag) ) {
                   1121: 
                   1122:            // look for default
                   1123:            modeIndex = 0;
                   1124:            err = [self getNextMode:&modeIndex modeInfo:&info needFlags:kDisplayModeDefaultFlag];
                   1125:            if( err) {
                   1126:                // D'oh, look for a valid and safe
                   1127:                modeIndex = 0;
                   1128:                err = [self getNextMode:&modeIndex modeInfo:&info needFlags:kNeedFlags];
                   1129:            }
                   1130:            if( err == noErr)
                   1131:                startMode = info.displayModeID;
                   1132:        }
                   1133: 
                   1134:        if( startDepth > info.maxDepthIndex)
                   1135:            startDepth = info.maxDepthIndex;
                   1136: 
                   1137:         // make the preferred mode pending, but come up at 8bpp for faster console
                   1138:         _pendingDisplayMode = 0;
                   1139:         pendingDisplayModeID = startMode;
                   1140:         pendingDepthIndex = startDepth;
                   1141:        // look for 8bpp mode
                   1142:         err = [self getConfigIndexForDisplayModeAndDepth:startMode depth:0
                   1143:                mono:NO configIndex:&modeIndex];
                   1144:        if( err == noErr)
                   1145:             err = [self getDisplayModeAndDepthForIndex:modeIndex
                   1146:                     mode:&startMode depth:&startDepth mono:&currentMono];
                   1147: 
                   1148:         currentMono = (0 != (config.flags & kFBLuminanceMapped));
                   1149:        pendingMono = currentMono;
                   1150: 
                   1151:        if( (startMode != config.displayMode) || (startDepth != config.depth)) {
                   1152: 
                   1153:            id deviceDesc = [self deviceDescription];
                   1154: 
                   1155:            if( [deviceDesc respondsTo:@selector(denyNVRAM:)])
                   1156:                [deviceDesc denyNVRAM:YES];
                   1157: 
                   1158:            [self setDisplayMode:startMode depth:startDepth page:0];
                   1159: 
                   1160:             if( [deviceDesc respondsTo:@selector(denyNVRAM:)])
                   1161:                 [deviceDesc denyNVRAM:NO];
                   1162:        }
                   1163:        [self setupForCurrentConfig];
                   1164:     }
                   1165: 
                   1166:     return( noErr);
                   1167: }
                   1168: 
                   1169: + (BOOL)probe:deviceDescription
                   1170: {
                   1171:     IOFramebuffer *inst;
                   1172:     
                   1173:     // Create an instance and initialize some basic instance variables.
                   1174:     inst = [[self alloc] initFromDeviceDescription:deviceDescription];
                   1175:     if (inst == nil)
                   1176:         return NO;
                   1177: 
                   1178:     [inst setDeviceKind:"Linear Framebuffer"];
                   1179: 
                   1180:     [inst registerDevice];
                   1181: 
                   1182:     return YES;
                   1183: }
                   1184: 
                   1185: - (IOReturn) setUserRanges
                   1186: {
                   1187:     IOReturn                   err;
                   1188:     id                         deviceDescrip;
                   1189:     UInt32                     i, start, size;
                   1190: 
                   1191:     deviceDescrip = [self deviceDescription];
                   1192:     [deviceDescrip setMemoryRangeList:0 num:0];
                   1193: 
                   1194:     // needs to be much better !!
                   1195:     for( i = 0; i < numRanges; i++) {
                   1196: 
                   1197:        start = userAccessRanges[ i ].start;
                   1198:        size = start & 0xfff;
                   1199:        start = start - size;
                   1200:        size = (size + 0xfff + userAccessRanges[ i ].size) & 0xfffff000;
                   1201:        userAccessRanges[ i ].start = start;
                   1202:        userAccessRanges[ i ].size = size;
                   1203:     }
                   1204: 
                   1205:     err = [deviceDescrip setMemoryRangeList:userAccessRanges num:numRanges];
                   1206:  
                   1207:     if(err) {
                   1208:        IOLog("%s: setMemoryRangeList FAIL:%d for \n",[self name], err );
                   1209: #if 1          // print ranges
                   1210:        for( i = 0; i < numRanges; i++)
                   1211:            IOLog(" start:%x size:%x", userAccessRanges[ i ].start, userAccessRanges[ i ].size );
                   1212: #endif
                   1213:     }
                   1214: #if 1          // print ranges
                   1215:     {
                   1216:     int                        i, num;
                   1217:     IORange    *       range;
                   1218: 
                   1219:     num = [deviceDescrip numMemoryRanges];
                   1220:        kprintf("%s: setMemoryRangeList num:%d", [self name], num);
                   1221:     for (i = 0; i < num; i++) {
                   1222:        range = [deviceDescrip memoryRangeList] + i;
                   1223:            kprintf(" start:%x size:%x", range->start, range->size);
                   1224:        }
                   1225:        kprintf("\n");
                   1226:     }
                   1227: #endif
                   1228:     return( err);
                   1229: }
                   1230: 
                   1231: - (IOReturn) addUserRanges:(IORange *)ranges num:(UInt32)num
                   1232: {
                   1233:     UInt32     i;
                   1234: 
                   1235:     for( i = 0; i < num; i++) {
                   1236:        userAccessRanges[ i + 1 ].start = ranges[ i ].start;
                   1237:        userAccessRanges[ i + 1 ].size = ranges[ i ].size;
                   1238:     }
                   1239:     numRanges = num + 1;
                   1240:     return( noErr);
                   1241: }
                   1242: 
                   1243: - (IOReturn) setupForCurrentConfig
                   1244: {
                   1245:     IOReturn                   err;
                   1246:     IOFBConfiguration          config;
                   1247:     IOFBPixelInformation       pixelInfo;
                   1248:     IODisplayInfo      *       displayInfo;
                   1249:     IOFBApertureInformation    apInfo;
                   1250:     IOFBIndex                  apIndex;
                   1251: 
                   1252:     displayInfo = [self displayInfo];          // current mode
                   1253: 
                   1254:     err = [self getConfiguration:&config];
                   1255:     if( err)
                   1256:        kprintf("setupForCurrentConfig:getConfiguration %d\n", err);
                   1257:     currentDisplayModeID = config.displayMode;
                   1258:     currentDepthIndex = config.depth;
                   1259: 
                   1260:     err = [self getPixelInformationForDisplayMode:currentDisplayModeID andDepthIndex:currentDepthIndex
                   1261:        pixelInfo:&pixelInfo];
                   1262:     if( err)
                   1263:        kprintf("setupForCurrentConfig:getPixelInformationForDisplayMode %d\n", err);
                   1264: 
                   1265:     [self convertPixelInfoToDisplayInfo:&pixelInfo
                   1266:        mono:currentMono
                   1267:        displayInfo:displayInfo];
                   1268:     displayInfo->frameBuffer = (void *) config.mappedFramebuffer;      // for cursor rendering
                   1269: 
                   1270:     if( (clutValid == NO) && (pixelInfo.pixelType == kIOFBRGBCLUTPixelType)) {
                   1271: 
                   1272:        IOFBColorEntry  *       tempTable;
                   1273:        int                     i;
                   1274: 
                   1275:        tempTable = IOMalloc( 256 * sizeof( IOFBColorEntry));
                   1276:        if( tempTable) {
                   1277: 
                   1278:            for( i = 0; i < 256; i++) {
                   1279:                 if( currentMono) {
                   1280:                     UInt32     lum;
                   1281: 
                   1282:                    lum = 0x0101 * i;
                   1283:                     tempTable[ i ].red   = lum;
                   1284:                     tempTable[ i ].green = lum;
                   1285:                     tempTable[ i ].blue  = lum;
                   1286:                 } else {
                   1287:                     tempTable[ i ].red   = (appleClut8[ i * 3 + 0 ] << 8) | appleClut8[ i * 3 + 0 ];
                   1288:                     tempTable[ i ].green = (appleClut8[ i * 3 + 1 ] << 8) | appleClut8[ i * 3 + 1 ];
                   1289:                     tempTable[ i ].blue  = (appleClut8[ i * 3 + 2 ] << 8) | appleClut8[ i * 3 + 2 ];
                   1290:                }
                   1291:            }
                   1292:            [self setCLUT:tempTable index:0 numEntries:256
                   1293:                    brightness:EV_SCREEN_MAX_BRIGHTNESS options:0];
                   1294:            IOFree( tempTable, 256 * sizeof( IOFBColorEntry));
                   1295:        }
                   1296:     }
                   1297:     clutValid = YES;
                   1298: 
                   1299:     [kmId registerDisplay:self];               // console now available
                   1300: 
                   1301:     kprintf( "%s: using (%dx%d@%dHz,%s)\n", [self name], displayInfo->width, displayInfo->height, 
                   1302:                        displayInfo->refreshRate,displayInfo->pixelEncoding );
                   1303: 
                   1304:     // our guess:
                   1305:     if( numRanges < 1)
                   1306:        numRanges = 1;
                   1307:     userAccessRanges[0].start = config.physicalFramebuffer;
                   1308:     userAccessRanges[0].size = ActiveBytes( displayInfo);
                   1309:     // what the driver says:
                   1310:     apIndex = 0;
                   1311:     while( noErr == [self getApertureInformationByIndex:apIndex++ apertureInfo:&apInfo]) {
                   1312:        if( apInfo.type == kIOFBGraphicsMemory) {
                   1313:            userAccessRanges[0].start = apInfo.physicalAddress;
                   1314:            userAccessRanges[0].size = apInfo.length;
                   1315:        }
                   1316:     }
                   1317:     err = [self setUserRanges];
                   1318: 
                   1319:     framebufferOffset = config.physicalFramebuffer - userAccessRanges[0].start;
                   1320: 
                   1321:     if( cursorShmemBitsPerPixel == displayInfo->bitsPerPixel)
                   1322:        cursorBitsPerPixel = displayInfo->bitsPerPixel;
                   1323: 
                   1324:     return( noErr);
                   1325: }
                   1326: 
                   1327: - (IOReturn)
                   1328:     getDisplayModeTiming:(IOFBIndex)connectIndex mode:(IOFBDisplayModeID)modeID
                   1329:                timingInfo:(IOFBTimingInformation *)info connectFlags:(UInt32 *)flags
                   1330: 
                   1331: {
                   1332:     OSStatus                   err = noErr;
                   1333: 
                   1334:     // if smartDisplay is nil, the flags get passed through
                   1335:     err = [smartDisplay getDisplayInfoForMode:info flags:flags];
                   1336:     return( err );
                   1337: }
                   1338: 
                   1339: //////////////////////////////////////////////////////////////////////
                   1340: // IOCallDeviceMethods:
                   1341: 
                   1342: 
                   1343: //////////////////////////////////////////////////////////////////////
                   1344: 
                   1345: // Description:        Get parameters for the display object. These include support
                   1346: //             for getting the frame buffer parameters, registering it
                   1347: //             with the event system, returning the registration token.
                   1348: 
                   1349: - (IOReturn)getIntValues:(unsigned *)parameterArray
                   1350:                forParameter:(IOParameterName)parameterName
                   1351:                count:(unsigned int *)count
                   1352: {
                   1353:     unsigned int fb_dimensions[STDFB_FB_DIMENSIONS_SIZE];
                   1354:     IOReturn r;
                   1355:     int i;
                   1356:     unsigned *returnedCount = count;
                   1357:     unsigned maxCount = *count;
                   1358:         
                   1359:     if (strcmp(parameterName, STDFB_FB_MAP) == 0) {
                   1360:         parameterArray[0] = 0;
                   1361: 
                   1362: //        [self enterLinearMode];
                   1363:        *returnedCount = 1;
                   1364:        return IO_R_SUCCESS;
                   1365: 
                   1366:     } else if (strcmp(parameterName, STDFB_FB_DIMENSIONS) == 0) {
                   1367:         IODisplayInfo *display = [self displayInfo];
                   1368: 
                   1369:        r = [self open];
                   1370:        if( r)
                   1371:            return( r);                         // this will halt WS on this display
                   1372:        if( wsStartup)
                   1373:             (void) [self _commitToPendingMode];
                   1374:        [self setupForCurrentConfig];
                   1375:        
                   1376:        fb_dimensions[STDFB_FB_WIDTH] = display->width;
                   1377:        fb_dimensions[STDFB_FB_HEIGHT] = display->height;
                   1378:        fb_dimensions[STDFB_FB_ROWBYTES] = display->rowBytes;
                   1379:        fb_dimensions[STDFB_FB_FLAGS] = display->flags;
                   1380:        switch (display->bitsPerPixel) {
                   1381:            case IO_2BitsPerPixel:
                   1382:                fb_dimensions[STDFB_FB_BITS_PER_PIXEL] = 2; break;
                   1383:            case IO_8BitsPerPixel:
                   1384:                fb_dimensions[STDFB_FB_BITS_PER_PIXEL] = 8; break;
                   1385:            case IO_12BitsPerPixel:
                   1386:                fb_dimensions[STDFB_FB_BITS_PER_PIXEL] = 12; break;
                   1387:            case IO_15BitsPerPixel:
                   1388:                fb_dimensions[STDFB_FB_BITS_PER_PIXEL] = 15; break;
                   1389:            case IO_24BitsPerPixel:
                   1390:                fb_dimensions[STDFB_FB_BITS_PER_PIXEL] = 32; break;
                   1391:            default:
                   1392:                /* Should return an error. */
                   1393:                break;
                   1394:        }
                   1395: 
                   1396:        *returnedCount = 0;
                   1397:        for( i=0; i<STDFB_FB_DIMENSIONS_SIZE; i++) {
                   1398:            if (*returnedCount == maxCount)
                   1399:                break;
                   1400:            parameterArray[i] = fb_dimensions[i];
                   1401:            (*returnedCount)++;
                   1402:        }
                   1403:        return IO_R_SUCCESS;
                   1404: 
                   1405:     } else if (strcmp(parameterName, STDFB_FB_REGISTER) == 0) {
                   1406:        r = [self _registerWithED];
                   1407:        *returnedCount = 0;
                   1408:        if (maxCount > 0) {
                   1409:            *returnedCount = 1;
                   1410:            parameterArray[0] = [self token];
                   1411:        }
                   1412:        return r;
                   1413: 
                   1414:     } else if (strcmp(parameterName, IO_GET_DISPLAY_INFO) == 0) {
                   1415:        const IODisplayInfo *displayInfo;
                   1416:        if ((*count != 5) && (*count != 7))
                   1417:            return IO_R_INVALID_ARG;
                   1418:        displayInfo = [self displayInfo];
                   1419:        parameterArray[0] = displayInfo->width;
                   1420:        parameterArray[1] = displayInfo->height;
                   1421:        parameterArray[2] = displayInfo->refreshRate;
                   1422:        parameterArray[3] = (unsigned)displayInfo->bitsPerPixel;
                   1423:        parameterArray[4] = (unsigned)displayInfo->colorSpace;
                   1424:        if (*count == 7)        {
                   1425:            parameterArray[5] = displayInfo->totalWidth;
                   1426:            parameterArray[6] = displayInfo->rowBytes;
                   1427:        }
                   1428:        return IO_R_SUCCESS;
                   1429: 
                   1430:     } else if (strcmp(parameterName, IO_GET_DISPLAY_MODE_NUM) == 0)    {
                   1431:        if (*count != 1)
                   1432:            return IO_R_INVALID_ARG;
                   1433:        parameterArray[0] = numConfigs;
                   1434:        return IO_R_SUCCESS;
                   1435:  
                   1436:    } else if (strncmp(parameterName, IO_GET_DISPLAY_MODE_INFO,
                   1437:                sizeof(IO_GET_DISPLAY_MODE_INFO)-1) == 0)       {
                   1438:        IODisplayInfo theDisplayInfo;
                   1439:        IODisplayInfo *displayInfo = &theDisplayInfo;
                   1440:        const char *s;
                   1441:        int mode;
                   1442:        UInt32  flags;
                   1443:        
                   1444:        if (*count != 14)       {
                   1445:            return IO_R_INVALID_ARG;
                   1446:        }
                   1447:        s = find_parameter(IO_GET_DISPLAY_MODE_INFO, parameterName);
                   1448:        if (s == 0)     {
                   1449:            return IO_R_INVALID_ARG;
                   1450:        }
                   1451:        mode = strtol(s, 0, 10);
                   1452: 
                   1453:         r = [self getDisplayInfoForConfigIndex:mode info:displayInfo
                   1454:                         connectFlags:&flags];
                   1455:        if( r)
                   1456:            return( r);
                   1457: 
                   1458:        parameterArray[0] = displayInfo->width;
                   1459:        parameterArray[1] = displayInfo->height;
                   1460:        parameterArray[2] = displayInfo->refreshRate;
                   1461:        parameterArray[3] = (unsigned)displayInfo->bitsPerPixel;
                   1462:        parameterArray[4] = (unsigned)displayInfo->colorSpace;
                   1463:        parameterArray[5] = displayInfo->totalWidth;
                   1464:        parameterArray[6] = displayInfo->rowBytes;
                   1465:        
                   1466:        parameterArray[7] = displayInfo->memorySize;
                   1467:        parameterArray[8] = displayInfo->scanRate;
                   1468:         parameterArray[9] = ((flags & kDisplayModeSafeFlag) ? IO_DISPLAY_MODE_SAFE : 0)
                   1469:                         |  ((flags & kDisplayModeDefaultFlag) ? IO_DISPLAY_MODE_DEFAULT : 0);
                   1470:        parameterArray[10] = displayInfo->dotClockRate;
                   1471:        parameterArray[11] = displayInfo->screenWidth;
                   1472:        parameterArray[12] = displayInfo->screenHeight;
                   1473:        parameterArray[13] = displayInfo->modeUnavailableFlag;
                   1474:        return IO_R_SUCCESS;
                   1475: 
                   1476:     } else if (strcmp(parameterName, IO_GET_DISPLAY_MEMORY) == 0)      {
                   1477:        if (*count != 1)
                   1478:            return IO_R_INVALID_ARG;
                   1479:        parameterArray[0] = 0;
                   1480:        return IO_R_SUCCESS;
                   1481: 
                   1482:     } else if (strcmp(parameterName, IO_GET_RAMDAC_SPEED) == 0)        {
                   1483:        if (*count != 1)
                   1484:            return IO_R_INVALID_ARG;
                   1485:        parameterArray[0] = 0;
                   1486:        return IO_R_SUCCESS;
                   1487: 
                   1488:     } else if (strcmp(parameterName, IO_GET_CURRENT_DISPLAY_MODE) == 0)        {
                   1489:        if (*count != 1)
                   1490:            return IO_R_INVALID_ARG;
                   1491:        return( [self getCurrentConfigIndex:(UInt32 *)parameterArray]);
                   1492: 
                   1493:     } else if (strcmp(parameterName, IO_GET_PENDING_DISPLAY_MODE) == 0)        {
                   1494:        if (*count != 1)
                   1495:            return IO_R_INVALID_ARG;
                   1496:        if (_pendingDisplayMode >= 0)   {
                   1497:            parameterArray[0] = _pendingDisplayMode;
                   1498:            return IO_R_SUCCESS;
                   1499:        } else {
                   1500:            return IO_R_UNDEFINED_MODE;
                   1501:        }
                   1502: 
                   1503:     } else if (strcmp(parameterName, "IOGetFramebufferOffset") == 0) {
                   1504: 
                   1505:        if( *count != 1)
                   1506:            return IO_R_INVALID_ARG;
                   1507:        parameterArray[0] = framebufferOffset;
                   1508:        return IO_R_SUCCESS;
                   1509: 
                   1510:     } else if (strncmp(parameterName, IO_SET_PENDING_DISPLAY_MODE,
                   1511:                sizeof(IO_SET_PENDING_DISPLAY_MODE) - 1 ) == 0) {
                   1512:        const char *s;
                   1513:        int mode;
                   1514:        
                   1515:        if (*count != 0) {
                   1516:            return IO_R_INVALID_ARG;
                   1517:        }
                   1518:        s = find_parameter(IO_SET_PENDING_DISPLAY_MODE, parameterName);
                   1519:        if (s == 0)     {
                   1520:            return IO_R_INVALID_ARG;
                   1521:        }
                   1522:        mode = strtol(s, 0, 10);
                   1523: 
                   1524:        if ([self setPendingDisplayMode:mode] == YES) {
                   1525:            return IO_R_SUCCESS;
                   1526:        } else {
                   1527:            return IO_R_FAILED_TO_SET_MODE;
                   1528:        }
                   1529: 
                   1530:     } else {
                   1531:        return [super getIntValues:parameterArray
                   1532:            forParameter:parameterName
                   1533:            count:count];
                   1534:     }
                   1535: }
                   1536: 
                   1537: 
                   1538: /* Set parameters for the display object. This can be used to unregister the
                   1539:  * frame buffer as well as to set the transfer function.
                   1540:  */
                   1541: - (IOReturn)setIntValues:(unsigned *)parameterArray
                   1542:                forParameter:(IOParameterName)parameterName
                   1543:                count:(unsigned int)count
                   1544: {
                   1545:     int i;
                   1546: 
                   1547:     if (strcmp(parameterName, STDFB_FB_UNMAP) == 0) {
                   1548:        //[self unMapFrameBuffer];
                   1549:        return IO_R_SUCCESS;
                   1550: 
                   1551:     } else if (strcmp(parameterName, STDFB_FB_UNREGISTER) == 0) {
                   1552:        if (count != 1)
                   1553:            return IO_R_INVALID_ARG;
                   1554:        [[EventDriver instance] unregisterScreen:parameterArray[0]];
                   1555:        return IO_R_SUCCESS;
                   1556: 
                   1557:     } else if (strcmp(parameterName, IO_SET_TRANSFER_TABLE) == 0) {
                   1558:        switch ([self displayInfo]->bitsPerPixel) {
                   1559:        case IO_2BitsPerPixel:
                   1560:            if (count != IO_2BPP_TRANSFER_TABLE_SIZE)
                   1561:                return IO_R_INVALID_ARG;
                   1562:            break;
                   1563:        case IO_8BitsPerPixel:
                   1564:            if (count != IO_8BPP_TRANSFER_TABLE_SIZE)
                   1565:                return IO_R_INVALID_ARG;
                   1566:            break;
                   1567:        case IO_12BitsPerPixel:
                   1568:            if (count != IO_12BPP_TRANSFER_TABLE_SIZE)
                   1569:                return IO_R_INVALID_ARG;
                   1570:            break;
                   1571:        case IO_15BitsPerPixel:
                   1572:            if (count != IO_15BPP_TRANSFER_TABLE_SIZE)
                   1573:                return IO_R_INVALID_ARG;
                   1574:            break;
                   1575:        case IO_24BitsPerPixel:
                   1576:            if (count != IO_24BPP_TRANSFER_TABLE_SIZE)
                   1577:                return IO_R_INVALID_ARG;
                   1578:            break;
                   1579:        default:
                   1580:            return IO_R_INVALID_ARG;
                   1581:        }
                   1582:        [self setTransferTable:parameterArray count:count];
                   1583:        return IO_R_SUCCESS;
                   1584: 
                   1585:     } else if (strcmp(parameterName, STDFB_BM256_TO_BM38_MAP) == 0) {
                   1586:        if (count != STDFB_BM256_TO_BM38_MAP_SIZE)
                   1587:            return IO_R_INVALID_ARG;
                   1588:        if (_bm256To38SampleTable == NULL)
                   1589:            _bm256To38SampleTable = (unsigned int *)
                   1590:                        IOMalloc(STDFB_BM256_TO_BM38_MAP_SIZE * sizeof(int));
                   1591:        for (i = 0; i < count; i++)
                   1592:            _bm256To38SampleTable[i] = parameterArray[i];
                   1593:        return IO_R_SUCCESS;
                   1594: 
                   1595:     } else if (strcmp(parameterName, STDFB_BM38_TO_BM256_MAP) == 0) {
                   1596: 
                   1597:        if ((count != STDFB_BM38_TO_BM256_MAP_SIZE)
                   1598:        && (count != STDFB_BM38_TO_256_WITH_LOGICAL_SIZE))
                   1599:            return IO_R_INVALID_ARG;
                   1600:        if (_bm38To256SampleTable == NULL) {
                   1601:            _bm38To256SampleTable = (unsigned char *)
                   1602:                        IOMalloc(STDFB_BM38_TO_256_WITH_LOGICAL_SIZE * sizeof(int));
                   1603:         }
                   1604:        if( count != STDFB_BM38_TO_256_WITH_LOGICAL_SIZE)
                   1605:            for (i = 0; i < 256; i++)
                   1606:                _bm38To256SampleTable[ 1024 + i ] = i;
                   1607:        for (i = 0; i < count; i++)
                   1608:            *(((unsigned int *)_bm38To256SampleTable) + i) = parameterArray[i];
                   1609:        return IO_R_SUCCESS;
                   1610: 
                   1611:     } else if (strcmp(parameterName, IO_SET_PENDING_DISPLAY_MODE) == 0) {
                   1612:        if (count != 1)
                   1613:            return IO_R_INVALID_ARG;
                   1614:        if ([self setPendingDisplayMode:parameterArray[0]] == YES) {
                   1615:            return IO_R_SUCCESS;
                   1616:        } else {
                   1617:            return IO_R_FAILED_TO_SET_MODE;
                   1618:        }
                   1619:     } else {
                   1620:        return [super setIntValues:parameterArray forParameter:parameterName
                   1621:            count:count];
                   1622:     }
                   1623: }
                   1624: 
                   1625: 
                   1626: /* Get parameters for the display object.
                   1627:  */
                   1628: - (IOReturn)getCharValues:(unsigned char *)parameterArray
                   1629:        forParameter:(IOParameterName)parameterName
                   1630:        count:(unsigned *)count
                   1631: {    
                   1632:     if (strcmp(parameterName, STDFB_FB_PIXEL_ENCODING) == 0) {
                   1633:        if (*count != STDFB_FB_PIXEL_ENCODING_SIZE)
                   1634:            return IO_R_INVALID_ARG;
                   1635: 
                   1636:        /* Copy the format string out of the display structure */
                   1637:        strncpy(parameterArray, [self displayInfo]->pixelEncoding,
                   1638:                STDFB_FB_PIXEL_ENCODING_SIZE);
                   1639:        return IO_R_SUCCESS;
                   1640: 
                   1641: 
                   1642:     } else if (strcmp(parameterName, "PostScript Driver") == 0) {
                   1643:        wsStartup = YES;
                   1644:         return IO_R_UNSUPPORTED;
                   1645: 
                   1646: #if 0
                   1647:     } else if (strcmp(parameterName, "PostScript Driver") == 0) {
                   1648: 
                   1649:        if (*count != sizeof(IOString))
                   1650:            return IO_R_INVALID_ARG;
                   1651: 
                   1652:        strcpy(parameterArray, "NDRV_psdrvr");
                   1653:        return IO_R_SUCCESS;
                   1654: 
                   1655:     } else if (strcmp(parameterName, "Server Name") == 0) {
                   1656: 
                   1657:        strcpy(parameterArray, "IONDRVFramebuffer");
                   1658:        return IO_R_SUCCESS;
                   1659: #endif
                   1660: 
                   1661:     } else {
                   1662:        return [super getCharValues:parameterArray
                   1663:            forParameter:parameterName
                   1664:            count:count];
                   1665:     }
                   1666: }
                   1667: 
                   1668: // Description:        Set parameters for the display object. This can be used
                   1669: //             to set the mapping tables used for conversion between
                   1670: //             4 BPS and 5 BPS data in 5-5-5 frame buffer support,
                   1671: //             and bm256 <--> bm38 conversion tables as well.
                   1672: //
                   1673: - (IOReturn)setCharValues:(unsigned char *)parameterArray
                   1674:                forParameter:(IOParameterName)parameterName
                   1675:                count:(unsigned int)count
                   1676: {
                   1677:     int i;
                   1678: 
                   1679:     if (strcmp(parameterName, STDFB_4BPS_TO_5BPS_MAP) == 0) {
                   1680:        if (count != STDFB_4BPS_TO_5BPS_MAP_SIZE)
                   1681:            return IO_R_INVALID_ARG;
                   1682:        if (_bm34To35SampleTable == NULL)
                   1683:            _bm34To35SampleTable = IOMalloc(STDFB_4BPS_TO_5BPS_MAP_SIZE);
                   1684:        for (i = 0; i < count; i++)
                   1685:            _bm34To35SampleTable[i] = parameterArray[i];
                   1686:        return IO_R_SUCCESS;
                   1687: 
                   1688:     } else if (strcmp(parameterName, STDFB_5BPS_TO_4BPS_MAP) == 0) {
                   1689:        if (count != STDFB_5BPS_TO_4BPS_MAP_SIZE)
                   1690:            return IO_R_INVALID_ARG;
                   1691:        if (_bm35To34SampleTable == NULL)
                   1692:            _bm35To34SampleTable = IOMalloc(STDFB_5BPS_TO_4BPS_MAP_SIZE);
                   1693:        for (i = 0; i < count; i++)
                   1694:            _bm35To34SampleTable[i] = parameterArray[i];
                   1695:        return IO_R_SUCCESS;
                   1696:     } else if (strcmp(parameterName, IO_COMMIT_TO_PENDING_DISPLAY_MODE) == 0) {
                   1697:        if ( [self _commitToPendingMode]) {
                   1698:            return IO_R_SUCCESS;
                   1699:        } else {
                   1700:            return IO_R_UNSUPPORTED;
                   1701:        }
                   1702:     } else {
                   1703:        return [super setCharValues:parameterArray
                   1704:            forParameter:parameterName
                   1705:            count:count];
                   1706:     }
                   1707: }
                   1708: 
                   1709: 
                   1710: - (BOOL)setPendingDisplayMode:(int)configIndex
                   1711: {
                   1712:     IOReturn           err;
                   1713: 
                   1714:     err = [self getDisplayModeAndDepthForIndex:configIndex
                   1715:                mode:&pendingDisplayModeID depth:&pendingDepthIndex mono:&pendingMono];
                   1716:     if( err == noErr) {
                   1717:        wsStartup = NO;
                   1718:        _pendingDisplayMode = configIndex;
                   1719:        [self setStartupMode:pendingDisplayModeID depth:pendingDepthIndex];
                   1720:     }
                   1721:     return( err == noErr);
                   1722: }
                   1723: 
                   1724: - (int)pendingDisplayMode
                   1725: {
                   1726:     return _pendingDisplayMode;
                   1727: }
                   1728: 
                   1729: - setTransferTable:(const unsigned int *)table count:(int)count
                   1730: {
                   1731:     return self;
                   1732: }
                   1733: 
                   1734: - (UInt32) tempFlags
                   1735: {
                   1736:     return( 0);
                   1737: }
                   1738: 
                   1739: - (BOOL)_commitToPendingMode
                   1740: {
                   1741: 
                   1742:     if( _pendingDisplayMode < 0)
                   1743:        return( NO);
                   1744: 
                   1745:     [kmId unregisterDisplay:self];             // tell kmDevice this device is unavail
                   1746:     cursorBitsPerPixel = (-1);
                   1747:     currentMono = pendingMono;
                   1748:     [self setDisplayMode:pendingDisplayModeID depth:pendingDepthIndex page:0];
                   1749:     _pendingDisplayMode = -1;  /* mode switch is complete */
                   1750:     [self setupForCurrentConfig];
                   1751: 
                   1752:     return( YES);
                   1753: }
                   1754: 
                   1755: + initialize
                   1756: {
                   1757:     gSmartDisplayClass = objc_lookUpClass("IOSmartDisplay");
                   1758:     return( self);
                   1759: }
                   1760: 
                   1761: //////////////////////////////////////////////////////////////////////////////////////////////////////
                   1762: // IOCallDeviceMethods:
                   1763: 
                   1764: // these should be somewhere else, IODevice or something:
                   1765: 
                   1766: - (IOReturn) IOGetApertures:(IOApertureInfo *)outputParams size:(unsigned *) outputCount
                   1767: {
                   1768:     IOReturn   err = noErr;
                   1769:     UInt32     items;
                   1770: 
                   1771:     items = (*outputCount) / sizeof( IOApertureInfo);
                   1772:     err = [[self deviceDescription]
                   1773:        getApertures:outputParams items:&items];
                   1774:     *outputCount = items * sizeof( IOApertureInfo);
                   1775: 
                   1776:     return( err);
                   1777: }
                   1778: 
                   1779: 
                   1780: - (IOReturn) IOGetDeviceName:(char *)outputParams size:(unsigned *) outputCount
                   1781: {
                   1782:     IOReturn   err = noErr;
                   1783:     char *     name;
                   1784:     UInt32     len, plen;
                   1785: 
                   1786:     name = [[self deviceDescription] nodeName];
                   1787:     plen = strlen( name);
                   1788:     len = *outputCount - 1;
                   1789:     *outputCount = plen + 1;
                   1790:     if( plen < len)
                   1791:        len = plen;
                   1792:     strncpy( outputParams, name, len);
                   1793:     outputParams[ len ] = 0;
                   1794: 
                   1795:     return( err);
                   1796: }
                   1797: 
                   1798: // really IOFramebuffer:
                   1799: 
                   1800: - (IOReturn) IOFBSetUserRange:(IORange *)inputParams size:(unsigned) inputCount
                   1801: {
                   1802:     IOReturn   err = noErr;
                   1803:     UInt32     items;
                   1804: 
                   1805:     items = inputCount / sizeof( IORange);
                   1806:     err = [self addUserRanges:(IORange *)inputParams num:items];
                   1807:     if( err == noErr)
                   1808:        err = [self setUserRanges];
                   1809: 
                   1810:     return( err);
                   1811: 
                   1812: }
                   1813: 
                   1814: - property_IODeviceClass:(char *)classes length:(unsigned int *)maxLen
                   1815: {
                   1816:     strcpy( classes, IOClassFramebuffer);
                   1817:     return( self);
                   1818: }
                   1819: 
                   1820: //////////////////////////////////////////////////////////////////////////////////////////////////////
                   1821: 
                   1822: - (IOReturn)
                   1823:     getDisplayModeByIndex:(IOFBIndex)modeIndex displayMode:(IOFBDisplayModeID *)displayModeID  {}
                   1824: 
                   1825: - (IOReturn)
                   1826:     getDisplayModeInformation:(IOFBDisplayModeID)modeID info:(IOFBDisplayModeInformation *)info  {}
                   1827: 
                   1828: - (IOReturn)
                   1829:     getPixelInformationForDisplayMode:(IOFBDisplayModeID)mode andDepthIndex:(IOFBIndex)depthIndex
                   1830:         pixelInfo:(IOFBPixelInformation *)info  {}
                   1831: 
                   1832: - (IOReturn)
                   1833:     setDisplayMode:(IOFBDisplayModeID)modeID depth:(IOFBIndex)depthIndex page:(IOFBIndex)pageIndex  {}
                   1834: - (IOReturn)
                   1835:     setStartupMode:(IOFBDisplayModeID)modeID depth:(IOFBIndex)depthIndex  {}
                   1836: - (IOReturn)
                   1837:     getStartupMode:(IOFBDisplayModeID *)modeID depth:(IOFBIndex *)depthIndex  {}
                   1838: 
                   1839: - (IOReturn)
                   1840:     getConfiguration:(IOFBConfiguration *)config   {}
                   1841: 
                   1842: - (IOReturn)
                   1843:     getAttributeForMode:(IOFBDisplayModeID) modeID andDepth:(IOFBIndex)depthIndex
                   1844:                                attribute:(IOFBSelect)attr value:(UInt32 *)value  {}
                   1845: 
                   1846: - (IOReturn)
                   1847:     getApertureInformationByIndex:(IOFBIndex)apertureIndex
                   1848:                         apertureInfo:(IOFBApertureInformation *)apertureInfo
                   1849: {
                   1850:     return( IO_R_UNSUPPORTED);
                   1851: }
                   1852: 
                   1853: - (IOReturn)
                   1854:     setCLUT:(IOFBColorEntry *) colors index:(UInt32)index numEntries:(UInt32)numEntries 
                   1855:        brightness:(IOFixed)brightness options:(IOOptionBits)options  {}
                   1856: 
                   1857: //// Gammas
                   1858: 
                   1859: - (IOReturn)
                   1860:     setGammaTable:(UInt32) channelCount dataCount:(UInt32)dataCount dataWidth:(UInt32)dataWidth
                   1861:        data:(void *)data  {}
                   1862: 
                   1863: 
                   1864: + (IOReturn)
                   1865:     convertCursorImage:(void *)cursorImage hwDescription:(HardwareCursorDescriptorRec *)hwDescrip
                   1866:                        cursorResult:(HardwareCursorInfoRec *)cursorResult  {}
                   1867: 
                   1868: 
                   1869: - (IOReturn)
                   1870:     setCursorImage:(void *)cursorImage  {}
                   1871: - (IOReturn)
                   1872:     setCursorState:(SInt32)x y:(SInt32)y visible:(Boolean)visible  {}
                   1873: 
                   1874: - (IOReturn)
                   1875:     registerForInterruptType:(IOFBSelect)interruptType proc:(IOFBInterruptProc)proc refcon:(UInt32)refcon  {}
                   1876: 
                   1877: - (IOReturn)
                   1878:     setInterruptState:(IOFBSelect)interruptType state:(UInt32)state  {}
                   1879: 
                   1880: - (IOReturn)
                   1881:     setAttribute:(IOFBSelect)attribute value:(UInt32)value  {}
                   1882: 
                   1883: - (IOReturn)
                   1884:     getAttribute:(IOFBSelect)attribute value:(UInt32 *)value  {}
                   1885: 
                   1886: - (IOReturn)
                   1887:     privateCall:(IOFBSelect)callClass select:(IOFBSelect)select
                   1888:                paramSize:(UInt32)paramSize params:(void *)params
                   1889:                resultSize:(UInt32 *)resultSize results:(void *)results  {}
                   1890: 
                   1891: - (IOReturn)
                   1892:     getConnections:(IOFBIndex)connectIndex 
                   1893:                 connectInfo:(IOFBConnectionInfo *)info  {}
                   1894: 
                   1895: - (IOReturn)
                   1896:     setConnectionAttribute:(IOFBIndex)connectIndex attribute:(IOFBSelect)attribute value:(UInt32)value  {}
                   1897: 
                   1898: - (IOReturn)
                   1899:     getConnectionAttribute:(IOFBIndex)connectIndex attribute:(IOFBSelect)attribute value:(UInt32 *)value  {}
                   1900: 
                   1901: 
                   1902: @end
                   1903: 

unix.superglobalmegacorp.com

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