Annotation of driverkit/libDriver/Kernel/IOFrameBufferDisplay.m, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: /*     Copyright (c) 1992-96 NeXT Software, Inc.  All rights reserved. 
        !            25:  *
        !            26:  * IOFrameBufferDisplay.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: #endif
        !            65: 
        !            66: #import        <driverkit/EventDriver.h>
        !            67: #import        <bsd/dev/evio.h>
        !            68: 
        !            69: #ifdef i386
        !            70: #import        <bsd/dev/i386/kmDevice.h>
        !            71: #endif
        !            72: #ifdef ppc
        !            73: #import        <bsd/dev/ppc/kmDevice.h>
        !            74: #endif
        !            75: 
        !            76: #import <driverkit/KernBus.h>
        !            77: #import <driverkit/KernBusMemory.h>
        !            78: #import <driverkit/IODisplayPrivate.h>
        !            79: #import        <driverkit/IOFrameBufferDisplay.h>
        !            80: #import        <driverkit/IOFrameBufferShared.h>
        !            81: #import <driverkit/IODirectDevicePrivate.h>
        !            82: #import <driverkit/displayDefs.h>
        !            83: #ifdef i386
        !            84: #import <driverkit/i386/directDevice.h>
        !            85: #import <driverkit/i386/driverTypes.h>
        !            86: #endif
        !            87: #ifdef ppc
        !            88: #import <driverkit/ppc/directDevice.h>
        !            89: #import <driverkit/ppc/driverTypes.h>
        !            90: #endif
        !            91: 
        !            92: #define CLEARSEMA(shmem)       ev_unlock(&shmem->cursorSema)
        !            93: #define SETSEMA(shmem)         \
        !            94:        if (!ev_try_lock(&shmem->cursorSema)) return self;
        !            95: #define TOUCHBOUNDS(one, two) \
        !            96:        (((one.minx < two.maxx) && (two.minx < one.maxx)) && \
        !            97:        ((one.miny < two.maxy) && (two.miny < one.maxy)))
        !            98: 
        !            99: #define RBMASK 0xF0F0          /* Short, or 16 bit format */
        !           100: #define GAMASK 0x0F0F          /* Short, or 16 bit format */
        !           101: #define AMASK  0x000F          /* Short, or 16 bit format */
        !           102: 
        !           103: #define        GetShmem(instance)      ((StdFBShmem_t *)(instance->priv))
        !           104: 
        !           105: extern long int strtol(const char *nptr, char **endptr, int base);
        !           106: 
        !           107: @interface IOFrameBufferDisplay(Private)
        !           108: - (BOOL)_commitToPendingMode;
        !           109: @end
        !           110: 
        !           111: @implementation IOFrameBufferDisplay
        !           112: 
        !           113: //
        !           114: // BEGIN:      Generic utility routines and methods
        !           115: //
        !           116: - (IOReturn)_registerWithED
        !           117: // Description:        Register this display device with the event driver.
        !           118: {
        !           119:     int token;
        !           120:     int shmem_size;
        !           121:     Bounds bounds;
        !           122:     StdFBShmem_t *shmem;
        !           123:     
        !           124:     token = [[EventDriver instance] registerScreen:self
        !           125:        bounds:&bounds
        !           126:        shmem:&(self->priv)
        !           127:        size:&shmem_size];
        !           128:     shmem = GetShmem(self);
        !           129:     if ( token == -1 )
        !           130:        return IO_R_INVALID_ARG;
        !           131:     // We allow the shmem_size to be less than sizeof(StdFBShmem_t)
        !           132:     // so that we need not consume the extra space that some of the
        !           133:     // larger cursor variants require if we are really a lower bitdepth.
        !           134:     if ( shmem_size > sizeof(StdFBShmem_t) )
        !           135:     {
        !           136:        IOLog("%s: shmem_size > sizeof (StdFBShmem_t)(%d<>%d)\n",
        !           137:            [self name], shmem_size, sizeof (StdFBShmem_t));
        !           138:        [[EventDriver instance] unregisterScreen:token];
        !           139:        return IO_R_INVALID_ARG;
        !           140:     }
        !           141:     // Init shared memory area
        !           142:     memset((char *)shmem, 0, shmem_size);
        !           143:     shmem->cursorShow = 1;
        !           144:     shmem->screenBounds = bounds;
        !           145:     [self setToken:token];
        !           146:     
        !           147:     return IO_R_SUCCESS;
        !           148: }
        !           149: 
        !           150: #define short34to35WithGamma(x) \
        !           151:        (  (_bm34To35SampleTable[((x) & 0x00F0) >> 4])          \
        !           152:         | (_bm34To35SampleTable[((x) & 0x0F00) >> 8] << 5)     \
        !           153:         | (_bm34To35SampleTable[(x) >> 12] << 10) )
        !           154: 
        !           155: #define short35to34WithGamma(x) \
        !           156:        (  0x000F                                               \
        !           157:         | (_bm35To34SampleTable[x & 0x001F] << 4)              \
        !           158:         | (_bm35To34SampleTable[(x & 0x03E0) >> 5] << 8)       \
        !           159:         | (_bm35To34SampleTable[(x & 0x7C00) >> 10] << 12) )
        !           160: 
        !           161: static void StdFBDisplayCursor16(IOFrameBufferDisplay *inst)
        !           162: // Description: Displays the cursor on the framebuffer by first saving
        !           163: //             what's underneath the cursor, then drawing the cursor there.
        !           164: //             NOTE:The topleft of the cursorRect passed in is not
        !           165: //             necessarily the cursor location.The cursorRect is adjusted to
        !           166: //             compensate for the cursor hotspot.If the frame buffer is
        !           167: //             cacheable, flush at the end of the drawing operation. A
        !           168: //             saveRect is stored which defines the actual area of the screen
        !           169: //             that is saved.This is used by RemoveCursor in restoring the
        !           170: //             screen data later.
        !           171: {
        !           172:     IODisplayInfo *dpy;
        !           173:     StdFBShmem_t *shmem;
        !           174:     vm_offset_t startPtr;              /* Starting screen data pointer */
        !           175:     unsigned int vramRow;
        !           176:     Bounds saveRect;
        !           177:     short i, j, width, cursRow;
        !           178:     unsigned short *vramPtr;   /* screen data pointer */
        !           179:     unsigned short *savePtr;   /* saved screen data pointer */
        !           180:     unsigned short s, d, f;
        !           181:     volatile unsigned short *cursPtr;
        !           182:     unsigned char *_bm34To35SampleTable;
        !           183:     unsigned char *_bm35To34SampleTable;
        !           184: 
        !           185:     dpy = [inst displayInfo];
        !           186:     shmem = GetShmem(inst);
        !           187:     saveRect = shmem->cursorRect;
        !           188:     /* Clip saveRect vertical within screen bounds */
        !           189:     if (saveRect.miny < shmem->screenBounds.miny)
        !           190:        saveRect.miny = shmem->screenBounds.miny;
        !           191:     if (saveRect.maxy > shmem->screenBounds.maxy)
        !           192:        saveRect.maxy = shmem->screenBounds.maxy;
        !           193:     if (saveRect.minx < shmem->screenBounds.minx)
        !           194:        saveRect.minx = shmem->screenBounds.minx;
        !           195:     if (saveRect.maxx > shmem->screenBounds.maxx)
        !           196:        saveRect.maxx = shmem->screenBounds.maxx;
        !           197:     shmem->saveRect = saveRect; /* Remember save rect for RemoveCursor */
        !           198: 
        !           199:     vramRow = dpy->totalWidth; /* Scanline width in pixels */
        !           200:     vramPtr = (unsigned short *)dpy->frameBuffer + 
        !           201:         (vramRow * (saveRect.miny - shmem->screenBounds.miny)) +
        !           202:        (saveRect.minx - shmem->screenBounds.minx);
        !           203:     startPtr = (vm_offset_t) vramPtr;
        !           204:     width = saveRect.maxx - saveRect.minx;
        !           205:     vramRow -= width;
        !           206:     
        !           207:     cursRow = CURSORWIDTH - width;
        !           208:     savePtr = shmem->cursor.rgb.save;
        !           209:     cursPtr = shmem->cursor.rgb.image[shmem->frame];
        !           210:     cursPtr += (saveRect.miny - shmem->cursorRect.miny) * CURSORWIDTH +
        !           211:                (saveRect.minx - shmem->cursorRect.minx);
        !           212: 
        !           213:     if (dpy->bitsPerPixel == IO_12BitsPerPixel)
        !           214:     {
        !           215:        for (i = saveRect.maxy - saveRect.miny; --i != -1; ) {
        !           216:            for (j = width; --j != -1; ) {
        !           217:                d = *savePtr++ = *vramPtr;
        !           218:                if ( (s = *cursPtr++) == 0 )
        !           219:                {       /* Transparent black area.  Leave dst as is. */
        !           220:                    ++vramPtr;
        !           221:                    continue;
        !           222:                }
        !           223:                if ( (f = (~s) & (unsigned int)AMASK) == 0 )
        !           224:                {       /* Opaque cursor pixel.  Mark it. */
        !           225:                    *vramPtr++ = s;
        !           226:                    continue;
        !           227:                }
        !           228:                /* Alpha is not 0 or 1.0.  Sover the cursor. */
        !           229:                *vramPtr++ = s + (((((d & RBMASK)>>4)*f + GAMASK) & RBMASK)
        !           230:                             | ((((d & GAMASK)*f+GAMASK)>>4) & GAMASK));
        !           231:            }
        !           232:            cursPtr += cursRow; /* starting point of next cursor line */
        !           233:            vramPtr += vramRow; /* starting point of next screen line */
        !           234:        }
        !           235:     }
        !           236:     else       // dpy->bitsPerPixel == IO_15BitsPerPixel
        !           237:     {
        !           238:        // These tables should always be set by the Window Server before
        !           239:        // it enables cursor drawing.  If they're not set, it's an error.
        !           240:         if (   (_bm34To35SampleTable = inst->_bm34To35SampleTable) == NULL
        !           241:             || (_bm35To34SampleTable = inst->_bm35To34SampleTable) == NULL )
        !           242:                return;
        !           243:        for (i = saveRect.maxy - saveRect.miny; --i>=0; ) {
        !           244:            for (j = width; --j>=0; ) {
        !           245:                d = *savePtr++ = *vramPtr;
        !           246:                if ( (s = *cursPtr++) == 0 )
        !           247:                {       /* Transparent black area.  Leave dst as is. */
        !           248:                    ++vramPtr;
        !           249:                    continue;
        !           250:                }
        !           251:                if ( (f = (~s) & (unsigned int)AMASK) == 0 )
        !           252:                {       /* Opaque cursor pixel.  Mark it. */
        !           253:                    *vramPtr++ = short34to35WithGamma(s);
        !           254:                    continue;
        !           255:                }
        !           256:                /* Alpha is not 0 or 1.0.  Sover the cursor. */
        !           257:                d = short35to34WithGamma(d);
        !           258:                d = s + (((((d & RBMASK)>>4)*f + GAMASK) & RBMASK)
        !           259:                    | ((((d & GAMASK)*f+GAMASK)>>4) & GAMASK));
        !           260:                *vramPtr++ = short34to35WithGamma(d);
        !           261:            }
        !           262:            cursPtr += cursRow; /* starting point of next cursor line */
        !           263:            vramPtr += vramRow; /* starting point of next screen line */
        !           264:        }
        !           265:     }
        !           266: }
        !           267: 
        !           268: static inline unsigned int MUL32(unsigned int a, unsigned int b)
        !           269: {
        !           270:     unsigned int v, w;
        !           271: 
        !           272:     v  = ((a & 0xff00ff00) >> 8) * b;
        !           273:     v += ((v & 0xff00ff00) >> 8) + 0x00010001;
        !           274:     w  = (a & 0x00ff00ff) * b;
        !           275:     w += ((w & 0xff00ff00) >> 8) + 0x00010001;
        !           276: 
        !           277:     return (v & 0xff00ff00) | ((w >> 8) & 0x00ff00ff);
        !           278: }
        !           279: 
        !           280: static inline unsigned char map32to256( unsigned char *directToLogical, unsigned int s)
        !           281: {
        !           282:     unsigned char logicalValue;
        !           283: 
        !           284:     if ((s ^ (s>>8)) & 0x00ffff00) {
        !           285:        logicalValue =  directToLogical[(s>>24)        + 0] +
        !           286:                        directToLogical[((s>>16)&0xff) + 256] +
        !           287:                        directToLogical[((s>>8)&0xff)  + 512];
        !           288:     } else {
        !           289:        logicalValue =  directToLogical[(s>>24)        + 768];
        !           290:     }
        !           291:     return( directToLogical[ logicalValue + 1024 ]);           // final conversion from NeXT palette
        !           292:                                                                // to actual palette
        !           293: }
        !           294: 
        !           295: static void StdFBDisplayCursor8(IOFrameBufferDisplay *inst)
        !           296: // Description: Displays the cursor on the framebuffer by first saving
        !           297: //             what's underneath the cursor, then drawing the cursor there.
        !           298: //             NOTE:The topleft of the cursorRect passed in is not
        !           299: //             necessarily the cursor location.The cursorRect is adjusted to
        !           300: //             compensate for the cursor hotspot.If the frame buffer is
        !           301: //             cacheable, flush at the end of the drawing operation. A
        !           302: //             saveRect is stored which defines the actual area of the screen
        !           303: //             that is saved.This is used by RemoveCursor in restoring the
        !           304: //             screen data later.
        !           305: {
        !           306:     IODisplayInfo *dpy;
        !           307:     StdFBShmem_t *shmem;
        !           308:     vm_offset_t startPtr;              /* Starting screen data pointer */
        !           309:     unsigned int vramRow;
        !           310:     Bounds saveRect;
        !           311:     short i, j, width, cursRow;
        !           312:     unsigned char *vramPtr;    /* screen data pointer */
        !           313:     unsigned char *savePtr;    /* saved screen data pointer */
        !           314:     unsigned short s, d;
        !           315:     unsigned char dst, alpha;
        !           316:     unsigned int rgb32val;
        !           317:     volatile unsigned char *cursPtr;
        !           318:     volatile unsigned char *maskPtr;           /* cursor mask pointer */
        !           319:     unsigned int *_bm256To38SampleTable = inst->_bm256To38SampleTable;
        !           320:     unsigned char *_bm38To256SampleTable = inst->_bm38To256SampleTable;
        !           321: 
        !           322:     dpy = [inst displayInfo];
        !           323:     shmem = GetShmem(inst);
        !           324:     saveRect = shmem->cursorRect;
        !           325:     /* Clip saveRect vertical within screen bounds */
        !           326:     if (saveRect.miny < shmem->screenBounds.miny)
        !           327:        saveRect.miny = shmem->screenBounds.miny;
        !           328:     if (saveRect.maxy > shmem->screenBounds.maxy)
        !           329:        saveRect.maxy = shmem->screenBounds.maxy;
        !           330:     if (saveRect.minx < shmem->screenBounds.minx)
        !           331:        saveRect.minx = shmem->screenBounds.minx;
        !           332:     if (saveRect.maxx > shmem->screenBounds.maxx)
        !           333:        saveRect.maxx = shmem->screenBounds.maxx;
        !           334:     shmem->saveRect = saveRect; /* Remember save rect for RemoveCursor */
        !           335: 
        !           336:     vramRow = dpy->totalWidth; /* Scanline width in pixels */
        !           337:     vramPtr = (unsigned char *)dpy->frameBuffer + 
        !           338:         (vramRow * (saveRect.miny - shmem->screenBounds.miny)) +
        !           339:        (saveRect.minx - shmem->screenBounds.minx);
        !           340:     startPtr = (vm_offset_t) vramPtr;
        !           341:     width = saveRect.maxx - saveRect.minx;
        !           342:     vramRow -= width;
        !           343:     
        !           344:     cursRow = CURSORWIDTH - width;
        !           345:     savePtr = shmem->cursor.bw8.save;
        !           346:     cursPtr = shmem->cursor.bw8.image[shmem->frame];
        !           347:     maskPtr = shmem->cursor.bw8.mask[shmem->frame];
        !           348:     i = (saveRect.miny - shmem->cursorRect.miny) * CURSORWIDTH +
        !           349:        (saveRect.minx - shmem->cursorRect.minx);
        !           350:     cursPtr += i;
        !           351:     maskPtr += i;
        !           352: 
        !           353:     if (dpy->colorSpace == IO_OneIsWhiteColorSpace) {
        !           354:        for (i = saveRect.maxy - saveRect.miny; --i>=0; ) {
        !           355:            for (j = width; --j>=0; ) {
        !           356:                int t;
        !           357:                d = *savePtr++ = *vramPtr;
        !           358:                s = *cursPtr++;
        !           359:                t = d * (255 - *maskPtr++);
        !           360:                d = s + ((t + (t >> 8) + 1) >> 8);
        !           361:                *vramPtr++ = d;
        !           362:            }
        !           363:            cursPtr += cursRow; /* starting point of next cursor line */
        !           364:            maskPtr += cursRow;
        !           365:            vramPtr += vramRow; /* starting point of next screen line */
        !           366:        }
        !           367:     } else { // dpy->colorSpace == IO_RGBColorSpace 
        !           368:        for (i = saveRect.maxy - saveRect.miny; --i>=0; ) {
        !           369:            for (j = width; --j>=0; savePtr++,maskPtr++,cursPtr++,vramPtr++) {
        !           370:                *savePtr = *vramPtr;
        !           371:                if (alpha = *maskPtr) {
        !           372:                    dst = *cursPtr;
        !           373:                    if (alpha = ~alpha) {
        !           374:                        rgb32val = _bm256To38SampleTable[*vramPtr];
        !           375:                        rgb32val = (_bm256To38SampleTable[dst] & ~0xff) +
        !           376:                                   MUL32(rgb32val, alpha);
        !           377:                        dst = map32to256(_bm38To256SampleTable, rgb32val);
        !           378:                    }
        !           379:                    *vramPtr = dst;
        !           380:                }
        !           381:            }
        !           382:            cursPtr += cursRow; /* starting point of next cursor line */
        !           383:            maskPtr += cursRow;
        !           384:            vramPtr += vramRow; /* starting point of next screen line */
        !           385:        }
        !           386:     }
        !           387: }
        !           388: 
        !           389: static void StdFBRemoveCursor16(IOFrameBufferDisplay *inst)
        !           390: // Description:        RemoveCursor erases the cursor by replacing the background
        !           391: //             image that was saved by the previous call to DisplayCursor.
        !           392: //             If the frame buffer is cacheable, flush at the end of the
        !           393: //             drawing operation.
        !           394: {
        !           395:     IODisplayInfo *dpy;
        !           396:     StdFBShmem_t *shmem;
        !           397:     short i, j, width;
        !           398:     vm_offset_t startPtr;
        !           399:     unsigned int vramRow;
        !           400:     Bounds saveRect;
        !           401:     unsigned short *vramPtr;
        !           402:     unsigned short *savePtr;
        !           403: 
        !           404:     dpy = [inst displayInfo];
        !           405:     shmem = GetShmem(inst);
        !           406:     saveRect = shmem->saveRect;
        !           407:     vramRow = dpy->totalWidth; /* Scanline width in pixels */
        !           408:     vramPtr = (unsigned short *)dpy->frameBuffer +
        !           409:         (vramRow * (saveRect.miny - shmem->screenBounds.miny))
        !           410:        + (saveRect.minx - shmem->screenBounds.minx);
        !           411:     width = saveRect.maxx - saveRect.minx;
        !           412:     vramRow -= width;
        !           413:     savePtr = shmem->cursor.rgb.save;
        !           414:     startPtr = (vm_offset_t) vramPtr;
        !           415:     for (i = saveRect.maxy - saveRect.miny; --i != -1; ) {
        !           416:        for (j = width; --j != -1; )
        !           417:            *vramPtr++ = *savePtr++;
        !           418:        vramPtr += vramRow;
        !           419:     }
        !           420: }
        !           421: 
        !           422: static void StdFBRemoveCursor8(IOFrameBufferDisplay *inst)
        !           423: // Description:        RemoveCursor erases the cursor by replacing the background
        !           424: //             image that was saved by the previous call to DisplayCursor.
        !           425: //             If the frame buffer is cacheable, flush at the end of the
        !           426: //             drawing operation.
        !           427: {
        !           428:     IODisplayInfo *dpy;
        !           429:     StdFBShmem_t *shmem;
        !           430:     short i, j, width;
        !           431:     vm_offset_t startPtr;
        !           432:     unsigned int vramRow;
        !           433:     Bounds saveRect;
        !           434:     unsigned char *vramPtr;
        !           435:     unsigned char *savePtr;
        !           436: 
        !           437:     dpy = [inst displayInfo];
        !           438:     shmem = GetShmem(inst);
        !           439:     saveRect = shmem->saveRect;
        !           440:     vramRow = dpy->totalWidth; /* Scanline width in pixels */
        !           441:     vramPtr = (unsigned char *)dpy->frameBuffer +
        !           442:         (vramRow * (saveRect.miny - shmem->screenBounds.miny))
        !           443:        + (saveRect.minx - shmem->screenBounds.minx);
        !           444:     width = saveRect.maxx - saveRect.minx;
        !           445:     vramRow -= width;
        !           446:     savePtr = shmem->cursor.bw8.save;
        !           447:     startPtr = (vm_offset_t) vramPtr;
        !           448:     for (i = saveRect.maxy - saveRect.miny; --i != -1; ) {
        !           449:        for (j = width; --j != -1; )
        !           450:            *vramPtr++ = *savePtr++;
        !           451:        vramPtr += vramRow;
        !           452:     }
        !           453: }
        !           454: 
        !           455: static void StdFBDisplayCursor32(IOFrameBufferDisplay *inst)
        !           456: {
        !           457:     IODisplayInfo *dpy;
        !           458:     StdFBShmem_t *shmem;
        !           459:     unsigned int vramRow;
        !           460:     Bounds saveRect;
        !           461:     int i, j, width, cursRow;
        !           462:     unsigned int *vramPtr;     /* screen data pointer */
        !           463:     unsigned int *savePtr;     /* saved screen data pointer */
        !           464:     unsigned int s, d, f;
        !           465:     volatile unsigned int *cursPtr;
        !           466: 
        !           467:     dpy = [inst displayInfo];
        !           468:     shmem = GetShmem(inst);
        !           469:     saveRect = shmem->cursorRect;
        !           470:     /* Clip saveRect vertical within screen bounds */
        !           471:     if (saveRect.miny < shmem->screenBounds.miny)
        !           472:        saveRect.miny = shmem->screenBounds.miny;
        !           473:     if (saveRect.maxy > shmem->screenBounds.maxy)
        !           474:        saveRect.maxy = shmem->screenBounds.maxy;
        !           475:     if (saveRect.minx < shmem->screenBounds.minx)
        !           476:        saveRect.minx = shmem->screenBounds.minx;
        !           477:     if (saveRect.maxx > shmem->screenBounds.maxx)
        !           478:        saveRect.maxx = shmem->screenBounds.maxx;
        !           479:     shmem->saveRect = saveRect; /* Remember save rect for RemoveCursor */
        !           480: 
        !           481:     vramRow = dpy->totalWidth; /* Scanline width in pixels */
        !           482:     vramPtr = (unsigned int *)dpy->frameBuffer + 
        !           483:         (vramRow * (saveRect.miny - shmem->screenBounds.miny)) +
        !           484:        (saveRect.minx - shmem->screenBounds.minx);
        !           485:     width = saveRect.maxx - saveRect.minx;
        !           486:     vramRow -= width;
        !           487:     
        !           488:     cursRow = CURSORWIDTH - width;
        !           489:     savePtr = shmem->cursor.rgb24.save;
        !           490:     cursPtr = shmem->cursor.rgb24.image[shmem->frame];
        !           491:     cursPtr += (saveRect.miny - shmem->cursorRect.miny) * CURSORWIDTH +
        !           492:                (saveRect.minx - shmem->cursorRect.minx);
        !           493: 
        !           494:     if (dpy->pixelEncoding[0] == IO_SampleTypeAlpha ||
        !           495:        dpy->pixelEncoding[0] == IO_SampleTypeSkip) {
        !           496:        /* Pixel format is Axxx */
        !           497:        for (i = saveRect.maxy - saveRect.miny; --i != -1; ) {
        !           498:            for (j = width; --j != -1; ) {
        !           499:                d = *savePtr++ = *vramPtr;
        !           500:                s = *cursPtr++;
        !           501:                f = s >> 24;
        !           502:                if (f) {
        !           503:                    if (f == 0xff)              // Opaque pixel
        !           504:                        *vramPtr++ = s;
        !           505:                    else {                      // SOVER the cursor pixel
        !           506:                        s <<= 8;  d <<= 8;   /* Now pixels are xxxA */
        !           507:                        f ^= 0xFF;
        !           508:                        d = s+(((((d&0xFF00FF00)>>8)*f+0x00FF00FF)&0xFF00FF00)
        !           509:                            | ((((d & 0x00FF00FF)*f+0x00FF00FF)>>8) &
        !           510:                                0x00FF00FF));
        !           511:                        *vramPtr++ = (d>>8) | 0xff000000;
        !           512:                    }
        !           513:                } else                  // Transparent cursor pixel
        !           514:                    vramPtr++;
        !           515:            }
        !           516:            cursPtr += cursRow; /* starting point of next cursor line */
        !           517:            vramPtr += vramRow; /* starting point of next screen line */
        !           518:        }
        !           519:     } else {
        !           520:        /* Pixel format is xxxA */
        !           521:        for (i = saveRect.maxy - saveRect.miny; --i != -1; ) {
        !           522:            for (j = width; --j != -1; ) {
        !           523:                d = *savePtr++ = *vramPtr;
        !           524:                s = *cursPtr++;
        !           525:                f = s & (unsigned int)0xFF;
        !           526:                if (f) {
        !           527:                    if (f == 0xff)              // Opaque pixel
        !           528:                        *vramPtr++ = s;
        !           529:                    else {                      // SOVER the cursor pixel
        !           530:                        f ^= 0xFF;
        !           531:                        d = s+(((((d&0xFF00FF00)>>8)*f+0x00FF00FF)&0xFF00FF00)
        !           532:                            | ((((d & 0x00FF00FF)*f+0x00FF00FF)>>8) &
        !           533:                                0x00FF00FF));
        !           534:                        *vramPtr++ = d;
        !           535:                    }
        !           536:                } else                  // Transparent cursor pixel
        !           537:                    vramPtr++;
        !           538:            }
        !           539:            cursPtr += cursRow; /* starting point of next cursor line */
        !           540:            vramPtr += vramRow; /* starting point of next screen line */
        !           541:        }
        !           542:     }
        !           543: }
        !           544: 
        !           545: static void StdFBRemoveCursor32(IOFrameBufferDisplay *inst)
        !           546: {
        !           547:     IODisplayInfo *dpy;
        !           548:     StdFBShmem_t *shmem;
        !           549:     int i, j, width;
        !           550:     unsigned int vramRow;
        !           551:     Bounds saveRect;
        !           552:     unsigned int *vramPtr;
        !           553:     unsigned int *savePtr;
        !           554: 
        !           555:     dpy = [inst displayInfo];
        !           556:     shmem = GetShmem(inst);
        !           557:     saveRect = shmem->saveRect;
        !           558:     vramRow = dpy->totalWidth; /* Scanline width in pixels */
        !           559:     vramPtr = (unsigned int *)dpy->frameBuffer +
        !           560:         (vramRow * (saveRect.miny - shmem->screenBounds.miny))
        !           561:        + (saveRect.minx - shmem->screenBounds.minx);
        !           562:     width = saveRect.maxx - saveRect.minx;
        !           563:     vramRow -= width;
        !           564:     savePtr = (unsigned int *)shmem->cursor.rgb24.save;
        !           565:     for (i = saveRect.maxy - saveRect.miny; --i != -1; ) {
        !           566:        for (j = width; --j != -1; )
        !           567:            *vramPtr++ = *savePtr++;
        !           568:        vramPtr += vramRow;
        !           569:     }
        !           570: }
        !           571: 
        !           572: static inline void StdFBDisplayCursor(IOFrameBufferDisplay *inst) 
        !           573: {
        !           574:     switch ([inst displayInfo]->bitsPerPixel) {
        !           575:        default:
        !           576:        case IO_12BitsPerPixel:
        !           577:        case IO_15BitsPerPixel:
        !           578:            StdFBDisplayCursor16(inst);
        !           579:            break;
        !           580:        case IO_8BitsPerPixel:
        !           581:            StdFBDisplayCursor8(inst);
        !           582:            break;
        !           583:        case IO_24BitsPerPixel:
        !           584:            StdFBDisplayCursor32(inst);
        !           585:            break;
        !           586:     }
        !           587: }
        !           588: 
        !           589: static inline void StdFBRemoveCursor(IOFrameBufferDisplay *inst) 
        !           590: {
        !           591:     switch ([inst displayInfo]->bitsPerPixel) {
        !           592:        default:
        !           593:        case IO_12BitsPerPixel:
        !           594:        case IO_15BitsPerPixel:
        !           595:            StdFBRemoveCursor16(inst);
        !           596:            break;
        !           597:        case IO_8BitsPerPixel:
        !           598:            StdFBRemoveCursor8(inst);
        !           599:            break;
        !           600:        case IO_24BitsPerPixel:
        !           601:            StdFBRemoveCursor32(inst);
        !           602:            break;
        !           603:     }
        !           604: }
        !           605: 
        !           606: 
        !           607: #define RemoveCursor(inst)     StdFBRemoveCursor(inst)
        !           608: static inline void DisplayCursor(IOFrameBufferDisplay *inst)
        !           609: {
        !           610:     Point hs;
        !           611:     StdFBShmem_t *shmem;
        !           612: 
        !           613:     shmem = GetShmem(inst);
        !           614:     hs = shmem->hotSpot[shmem->frame];
        !           615:     shmem->cursorRect.maxx =
        !           616:         (shmem->cursorRect.minx = (shmem->cursorLoc).x - hs.x) + 16;
        !           617:     shmem->cursorRect.maxy =
        !           618:         (shmem->cursorRect.miny = (shmem->cursorLoc).y - hs.y) + 16;
        !           619:     StdFBDisplayCursor(inst);
        !           620:     shmem->oldCursorRect = shmem->cursorRect;
        !           621: }
        !           622: 
        !           623: static inline void SysHideCursor(IOFrameBufferDisplay *inst)
        !           624: {
        !           625:     if (!GetShmem(inst)->cursorShow++)
        !           626:        RemoveCursor(inst);
        !           627: }
        !           628: 
        !           629: static inline void SysShowCursor(IOFrameBufferDisplay *inst)
        !           630: {
        !           631:     if (GetShmem(inst)->cursorShow)
        !           632:        if (!--(GetShmem(inst)->cursorShow))
        !           633:            DisplayCursor(inst);
        !           634: }
        !           635: 
        !           636: static inline void CheckShield(IOFrameBufferDisplay *inst)
        !           637: {
        !           638:     Point hs;
        !           639:     int intersect;
        !           640:     Bounds tempRect;
        !           641:     StdFBShmem_t *shmem;
        !           642:     
        !           643:     shmem = GetShmem(inst);
        !           644:     /* Calculate temp cursorRect */
        !           645:     hs = shmem->hotSpot[shmem->frame];
        !           646:     tempRect.maxx = (tempRect.minx = (shmem->cursorLoc).x - hs.x) + 16;
        !           647:     tempRect.maxy = (tempRect.miny = (shmem->cursorLoc).y - hs.y) + 16;
        !           648: 
        !           649:     intersect = TOUCHBOUNDS(tempRect, shmem->shieldRect);
        !           650:     if (intersect != shmem->shielded)
        !           651:        (shmem->shielded = intersect) ?
        !           652:            SysHideCursor(inst) : SysShowCursor(inst);
        !           653: }
        !           654: //
        !           655: // END:                Generic utility routines
        !           656: //
        !           657: 
        !           658: 
        !           659: //
        !           660: // BEGIN:      Implementation of the evScreen protocol
        !           661: //
        !           662: - hideCursor: (int)token
        !           663: {
        !           664:     SETSEMA(GetShmem(self));
        !           665:     SysHideCursor(self);
        !           666:     CLEARSEMA(GetShmem(self));
        !           667:     return self;
        !           668: }
        !           669: 
        !           670: - moveCursor:(Point*)cursorLoc frame:(int)frame token:(int)t
        !           671: {
        !           672:     StdFBShmem_t *shmem;
        !           673:     
        !           674:     shmem = GetShmem(self);
        !           675:     SETSEMA(shmem);
        !           676:     shmem->frame = frame;
        !           677:     shmem->cursorLoc = *cursorLoc;
        !           678:     if (!shmem->cursorShow++)
        !           679:        RemoveCursor(self);
        !           680:     if (shmem->cursorObscured) {
        !           681:        shmem->cursorObscured = 0;
        !           682:        if (shmem->cursorShow)
        !           683:            --shmem->cursorShow;
        !           684:     }
        !           685:     if (shmem->shieldFlag) CheckShield(self);
        !           686:     if (shmem->cursorShow)
        !           687:        if (!--shmem->cursorShow)
        !           688:            DisplayCursor(self);
        !           689:     CLEARSEMA(shmem);
        !           690:     return self;
        !           691: }
        !           692: 
        !           693: - showCursor:(Point*)cursorLoc frame:(int)frame token:(int)t
        !           694: {
        !           695:     StdFBShmem_t *shmem;
        !           696:     
        !           697:     shmem = GetShmem(self);
        !           698:     SETSEMA(GetShmem(self));
        !           699:     shmem->frame = frame;
        !           700:     shmem->cursorLoc = *cursorLoc;
        !           701:     if (shmem->shieldFlag) CheckShield(self);
        !           702:     SysShowCursor(self);
        !           703:     CLEARSEMA(shmem);
        !           704:     return self;
        !           705: }
        !           706: 
        !           707: - setBrightness:(int)level token:(int)t
        !           708: {
        !           709:     if ( level < EV_SCREEN_MIN_BRIGHTNESS
        !           710:        || level > EV_SCREEN_MAX_BRIGHTNESS )
        !           711:     {
        !           712:        IOLog("%s: Invalid arg to setBrightness:%d\n",
        !           713:            [self name], level );
        !           714:     }
        !           715:     return self;
        !           716: }
        !           717: //
        !           718: // END:                Implementation of the evScreen protocol
        !           719: //
        !           720: //
        !           721: // BEGIN:      EXPORTED Methods
        !           722: //
        !           723: + (BOOL)probe:deviceDescription
        !           724: {
        !           725:     IOFrameBufferDisplay *inst;
        !           726:     
        !           727:     // Create an instance and initialize some basic instance variables.
        !           728:     inst = [[self alloc] initFromDeviceDescription:deviceDescription];
        !           729:     if (inst == nil)
        !           730:         return NO;
        !           731: 
        !           732:     [inst setDeviceKind:"Linear Framebuffer"];
        !           733: 
        !           734:     [inst registerDevice];
        !           735: 
        !           736:     return YES;
        !           737: }
        !           738: 
        !           739: - initFromDeviceDescription:deviceDescription
        !           740: {
        !           741:     extern int sprintf(char *s, const char *format, ...);
        !           742:     static int nextUnit = 0;
        !           743:     char nameBuf[20];
        !           744: 
        !           745:     if ([super initFromDeviceDescription:deviceDescription] == nil)
        !           746:        return [super free];
        !           747: 
        !           748:     _currentDisplayMode = _pendingDisplayMode = -1;
        !           749:     _displayModeCount = -1; _displayModes = NULL;
        !           750:     
        !           751:     sprintf(nameBuf, "Display%d", nextUnit);
        !           752:     [self setUnit: nextUnit++];
        !           753:     [self setName:nameBuf];
        !           754:     return self;
        !           755: }
        !           756: 
        !           757: - (IOConsoleInfo *)allocateConsoleInfo;
        !           758: // Description:        Allocates a console support info structure based on this
        !           759: //             display. This structure, and the functions in it, are used
        !           760: //             to display alert and console windows.
        !           761: {
        !           762:     return FBAllocateConsole([self displayInfo]);
        !           763: }
        !           764: 
        !           765: static const char *
        !           766: find_parameter(const char *parameter, const char *string)
        !           767: {
        !           768:     int c;
        !           769:     size_t length;
        !           770: 
        !           771:     length = strlen(parameter);
        !           772:     while (*string != 0) {
        !           773:        if (strncmp(string, parameter, length) == 0) {
        !           774:            string += length;
        !           775:            while ((c = *string) != '\0' && (c == ' ' || c == '\t'))
        !           776:                string++;
        !           777:            return (c != 0) ? string : 0;
        !           778:        }
        !           779:        string++;
        !           780:     }
        !           781:     return 0;
        !           782: }
        !           783: 
        !           784: 
        !           785: // Description:        Get parameters for the display object. These include support
        !           786: //             for getting the frame buffer parameters, registering it
        !           787: //             with the event system, returning the registration token.
        !           788: 
        !           789: - (IOReturn)getIntValues:(unsigned *)parameterArray
        !           790:                forParameter:(IOParameterName)parameterName
        !           791:                count:(unsigned int *)count
        !           792: {
        !           793:     unsigned int fb_dimensions[STDFB_FB_DIMENSIONS_SIZE];
        !           794:     IOReturn r;
        !           795:     int i;
        !           796:     unsigned *returnedCount = count;
        !           797:     unsigned maxCount = *count;
        !           798:         
        !           799:     if (strcmp(parameterName, STDFB_FB_MAP) == 0) {
        !           800:         parameterArray[0] = 0;
        !           801:        [self revertToVGAMode];         // start from a well-defined state
        !           802:        [self enterLinearMode];
        !           803:        [kmId registerDisplay:self];
        !           804:        *returnedCount = 1;
        !           805:        return IO_R_SUCCESS;
        !           806: 
        !           807:     } else if (strcmp(parameterName, STDFB_FB_DIMENSIONS) == 0) {
        !           808:         IODisplayInfo *display = [self displayInfo];
        !           809:        
        !           810:        fb_dimensions[STDFB_FB_WIDTH] = display->width;
        !           811:        fb_dimensions[STDFB_FB_HEIGHT] = display->height;
        !           812:        fb_dimensions[STDFB_FB_ROWBYTES] = display->rowBytes;
        !           813:        fb_dimensions[STDFB_FB_FLAGS] = display->flags;
        !           814:        switch (display->bitsPerPixel) {
        !           815:            case IO_2BitsPerPixel:
        !           816:                fb_dimensions[STDFB_FB_BITS_PER_PIXEL] = 2; break;
        !           817:            case IO_8BitsPerPixel:
        !           818:                fb_dimensions[STDFB_FB_BITS_PER_PIXEL] = 8; break;
        !           819:            case IO_12BitsPerPixel:
        !           820:                fb_dimensions[STDFB_FB_BITS_PER_PIXEL] = 12; break;
        !           821:            case IO_15BitsPerPixel:
        !           822:                fb_dimensions[STDFB_FB_BITS_PER_PIXEL] = 15; break;
        !           823:            case IO_24BitsPerPixel:
        !           824:                fb_dimensions[STDFB_FB_BITS_PER_PIXEL] = 32; break;
        !           825:            default:
        !           826:                /* Should return an error. */
        !           827:                break;
        !           828:        }
        !           829: 
        !           830:        *returnedCount = 0;
        !           831:        for( i=0; i<STDFB_FB_DIMENSIONS_SIZE; i++) {
        !           832:            if (*returnedCount == maxCount)
        !           833:                break;
        !           834:            parameterArray[i] = fb_dimensions[i];
        !           835:            (*returnedCount)++;
        !           836:        }
        !           837:        return IO_R_SUCCESS;
        !           838: 
        !           839:     } else if (strcmp(parameterName, STDFB_FB_REGISTER) == 0) {
        !           840:        r = [self _registerWithED];
        !           841:        *returnedCount = 0;
        !           842:        if (maxCount > 0) {
        !           843:            *returnedCount = 1;
        !           844:            parameterArray[0] = [self token];
        !           845:        }
        !           846:        return r;
        !           847: 
        !           848:     } else if (strcmp(parameterName, IO_GET_DISPLAY_INFO) == 0) {
        !           849:        const IODisplayInfo *displayInfo;
        !           850:        if ((*count != 5) && (*count != 7))
        !           851:            return IO_R_INVALID_ARG;
        !           852:        displayInfo = [self displayInfo];
        !           853:        parameterArray[0] = displayInfo->width;
        !           854:        parameterArray[1] = displayInfo->height;
        !           855:        parameterArray[2] = displayInfo->refreshRate;
        !           856:        parameterArray[3] = (unsigned)displayInfo->bitsPerPixel;
        !           857:        parameterArray[4] = (unsigned)displayInfo->colorSpace;
        !           858:        if (*count == 7)        {
        !           859:            parameterArray[5] = displayInfo->totalWidth;
        !           860:            parameterArray[6] = displayInfo->rowBytes;
        !           861:        }
        !           862:        return IO_R_SUCCESS;
        !           863: 
        !           864:     } else if (strcmp(parameterName, IO_GET_DISPLAY_MODE_NUM) == 0)    {
        !           865:        if (*count != 1)
        !           866:            return IO_R_INVALID_ARG;
        !           867:        parameterArray[0] = [self displayModeCount];
        !           868:        return IO_R_SUCCESS;
        !           869:     } else if (strncmp(parameterName, IO_GET_DISPLAY_MODE_INFO,
        !           870:                sizeof(IO_GET_DISPLAY_MODE_INFO)-1) == 0)       {
        !           871:        const IODisplayInfo *displayInfo, *displayModes;
        !           872:        const char *s;
        !           873:        int mode;
        !           874:        
        !           875:        if (*count != 14)       {
        !           876:            return IO_R_INVALID_ARG;
        !           877:        }
        !           878:        s = find_parameter(IO_GET_DISPLAY_MODE_INFO, parameterName);
        !           879:        if (s == 0)     {
        !           880:            return IO_R_INVALID_ARG;
        !           881:        }
        !           882:        mode = strtol(s, 0, 10);
        !           883:        if (mode < 0 || mode >= [self displayModeCount])
        !           884:            return IO_R_INVALID_ARG;
        !           885:            
        !           886:        displayModes = [self displayModes];
        !           887:        displayInfo = &displayModes[mode];
        !           888:        
        !           889:        parameterArray[0] = displayInfo->width;
        !           890:        parameterArray[1] = displayInfo->height;
        !           891:        parameterArray[2] = displayInfo->refreshRate;
        !           892:        parameterArray[3] = (unsigned)displayInfo->bitsPerPixel;
        !           893:        parameterArray[4] = (unsigned)displayInfo->colorSpace;
        !           894:        parameterArray[5] = displayInfo->totalWidth;
        !           895:        parameterArray[6] = displayInfo->rowBytes;
        !           896:        
        !           897:        parameterArray[7] = displayInfo->memorySize;
        !           898:        parameterArray[8] = displayInfo->scanRate;
        !           899:        parameterArray[9] = 0;
        !           900:        parameterArray[10] = displayInfo->dotClockRate;
        !           901:        parameterArray[11] = displayInfo->screenWidth;
        !           902:        parameterArray[12] = displayInfo->screenHeight;
        !           903:        parameterArray[13] = displayInfo->modeUnavailableFlag;
        !           904:        
        !           905:        return IO_R_SUCCESS;
        !           906:     } else if (strcmp(parameterName, IO_GET_DISPLAY_MEMORY) == 0)      {
        !           907:        if (*count != 1)
        !           908:            return IO_R_INVALID_ARG;
        !           909:        parameterArray[0] = [self displayMemorySize];
        !           910:        return IO_R_SUCCESS;
        !           911:     } else if (strcmp(parameterName, IO_GET_RAMDAC_SPEED) == 0)        {
        !           912:        if (*count != 1)
        !           913:            return IO_R_INVALID_ARG;
        !           914:        parameterArray[0] = [self ramdacSpeed];
        !           915:        return IO_R_SUCCESS;
        !           916:     } else if (strcmp(parameterName, IO_GET_CURRENT_DISPLAY_MODE) == 0)        {
        !           917:        if (*count != 1)
        !           918:            return IO_R_INVALID_ARG;
        !           919:        if (_currentDisplayMode >= 0)   {
        !           920:            parameterArray[0] = _currentDisplayMode;
        !           921:            return IO_R_SUCCESS;
        !           922:        } else {
        !           923:            return IO_R_UNDEFINED_MODE;
        !           924:        }
        !           925:     } else if (strcmp(parameterName, IO_GET_PENDING_DISPLAY_MODE) == 0)        {
        !           926:        if (*count != 1)
        !           927:            return IO_R_INVALID_ARG;
        !           928:        if (_pendingDisplayMode >= 0)   {
        !           929:            parameterArray[0] = _pendingDisplayMode;
        !           930:            return IO_R_SUCCESS;
        !           931:        } else {
        !           932:            return IO_R_UNDEFINED_MODE;
        !           933:        }
        !           934: 
        !           935:     } else if (strncmp(parameterName, IO_SET_PENDING_DISPLAY_MODE,
        !           936:                sizeof(IO_SET_PENDING_DISPLAY_MODE) - 1 ) == 0) {
        !           937:        const char *s;
        !           938:        int mode;
        !           939:        
        !           940:        if (*count != 0) {
        !           941:            return IO_R_INVALID_ARG;
        !           942:        }
        !           943:        s = find_parameter(IO_SET_PENDING_DISPLAY_MODE, parameterName);
        !           944:        if (s == 0)     {
        !           945:            return IO_R_INVALID_ARG;
        !           946:        }
        !           947:        mode = strtol(s, 0, 10);
        !           948: 
        !           949:        if ([self setPendingDisplayMode:mode] == YES) {
        !           950:            return IO_R_SUCCESS;
        !           951:        } else {
        !           952:            return IO_R_FAILED_TO_SET_MODE;
        !           953:        }
        !           954: 
        !           955:     } else {
        !           956:        return [super getIntValues:parameterArray
        !           957:            forParameter:parameterName
        !           958:            count:count];
        !           959:     }
        !           960: }
        !           961: 
        !           962: 
        !           963: /* Set parameters for the display object. This can be used to unregister the
        !           964:  * frame buffer as well as to set the transfer function.
        !           965:  */
        !           966: - (IOReturn)setIntValues:(unsigned *)parameterArray
        !           967:                forParameter:(IOParameterName)parameterName
        !           968:                count:(unsigned int)count
        !           969: {
        !           970:     int i;
        !           971: 
        !           972:     if (strcmp(parameterName, STDFB_FB_UNMAP) == 0) {
        !           973:         [self revertToVGAMode];
        !           974:        //[self unMapFrameBuffer];
        !           975:        return IO_R_SUCCESS;
        !           976: 
        !           977:     } else if (strcmp(parameterName, STDFB_FB_UNREGISTER) == 0) {
        !           978:        if (count != 1)
        !           979:            return IO_R_INVALID_ARG;
        !           980:        [[EventDriver instance] unregisterScreen:parameterArray[0]];
        !           981:        return IO_R_SUCCESS;
        !           982: 
        !           983:     } else if (strcmp(parameterName, IO_SET_TRANSFER_TABLE) == 0) {
        !           984:        switch ([self displayInfo]->bitsPerPixel) {
        !           985:        case IO_2BitsPerPixel:
        !           986:            if (count != IO_2BPP_TRANSFER_TABLE_SIZE)
        !           987:                return IO_R_INVALID_ARG;
        !           988:            break;
        !           989:        case IO_8BitsPerPixel:
        !           990:            if (count != IO_8BPP_TRANSFER_TABLE_SIZE)
        !           991:                return IO_R_INVALID_ARG;
        !           992:            break;
        !           993:        case IO_12BitsPerPixel:
        !           994:            if (count != IO_12BPP_TRANSFER_TABLE_SIZE)
        !           995:                return IO_R_INVALID_ARG;
        !           996:            break;
        !           997:        case IO_15BitsPerPixel:
        !           998:            if (count != IO_15BPP_TRANSFER_TABLE_SIZE)
        !           999:                return IO_R_INVALID_ARG;
        !          1000:            break;
        !          1001:        case IO_24BitsPerPixel:
        !          1002:            if (count != IO_24BPP_TRANSFER_TABLE_SIZE)
        !          1003:                return IO_R_INVALID_ARG;
        !          1004:            break;
        !          1005:        default:
        !          1006:            return IO_R_INVALID_ARG;
        !          1007:        }
        !          1008:        [self setTransferTable:parameterArray count:count];
        !          1009:        return IO_R_SUCCESS;
        !          1010: 
        !          1011:     } else if (strcmp(parameterName, STDFB_BM256_TO_BM38_MAP) == 0) {
        !          1012:        if (count != STDFB_BM256_TO_BM38_MAP_SIZE)
        !          1013:            return IO_R_INVALID_ARG;
        !          1014:        if (_bm256To38SampleTable == NULL)
        !          1015:            _bm256To38SampleTable = (unsigned int *)
        !          1016:                        IOMalloc(STDFB_BM256_TO_BM38_MAP_SIZE * sizeof(int));
        !          1017:        for (i = 0; i < count; i++)
        !          1018:            _bm256To38SampleTable[i] = parameterArray[i];
        !          1019:        return IO_R_SUCCESS;
        !          1020: 
        !          1021:     } else if (strcmp(parameterName, STDFB_BM38_TO_BM256_MAP) == 0) {
        !          1022: 
        !          1023: // For NeXT logical palette to real palette conversion, an additional
        !          1024: //   256 bytes can be added to the table
        !          1025: #define STDFB_BM38_TO_256_WITH_LOGICAL_SIZE    (STDFB_BM38_TO_BM256_MAP_SIZE + (256/sizeof(int)))
        !          1026: 
        !          1027:        if ((count != STDFB_BM38_TO_BM256_MAP_SIZE) && (count != STDFB_BM38_TO_256_WITH_LOGICAL_SIZE))
        !          1028:            return IO_R_INVALID_ARG;
        !          1029:        if (_bm38To256SampleTable == NULL) {
        !          1030:            _bm38To256SampleTable = (unsigned char *)
        !          1031:                        IOMalloc(STDFB_BM38_TO_256_WITH_LOGICAL_SIZE * sizeof(int));
        !          1032:         }
        !          1033:        if( count != STDFB_BM38_TO_256_WITH_LOGICAL_SIZE)
        !          1034:            for (i = 0; i < 256; i++)
        !          1035:                _bm38To256SampleTable[ 1024 + i ] = i;
        !          1036:        for (i = 0; i < count; i++)
        !          1037:            *(((unsigned int *)_bm38To256SampleTable) + i) = parameterArray[i];
        !          1038:        return IO_R_SUCCESS;
        !          1039: 
        !          1040:     } else if (strcmp(parameterName, IO_SET_PENDING_DISPLAY_MODE) == 0) {
        !          1041:        if (count != 1)
        !          1042:            return IO_R_INVALID_ARG;
        !          1043:        if ([self setPendingDisplayMode:parameterArray[0]] == YES) {
        !          1044:            return IO_R_SUCCESS;
        !          1045:        } else {
        !          1046:            return IO_R_FAILED_TO_SET_MODE;
        !          1047:        }
        !          1048:     } else {
        !          1049:        return [super setIntValues:parameterArray forParameter:parameterName
        !          1050:            count:count];
        !          1051:     }
        !          1052: }
        !          1053: 
        !          1054: /*
        !          1055:  * This is the first message sent by the windowserver. If there is a pending
        !          1056:  * display mode then we commit to it (i.e. update our IODisplayInfo
        !          1057:  * structure). 
        !          1058:  */
        !          1059: #define IO_POSTSCRIPT_DRIVER           "PostScript Driver"
        !          1060: 
        !          1061: /* Get parameters for the display object.
        !          1062:  */
        !          1063: - (IOReturn)getCharValues:(unsigned char *)parameterArray
        !          1064:        forParameter:(IOParameterName)parameterName
        !          1065:        count:(unsigned *)count
        !          1066: {    
        !          1067:     if (strcmp(parameterName, STDFB_FB_PIXEL_ENCODING) == 0) {
        !          1068:        if (*count != STDFB_FB_PIXEL_ENCODING_SIZE)
        !          1069:            return IO_R_INVALID_ARG;
        !          1070: 
        !          1071:        /* Copy the format string out of the display structure */
        !          1072:        strncpy(parameterArray, [self displayInfo]->pixelEncoding,
        !          1073:                STDFB_FB_PIXEL_ENCODING_SIZE);
        !          1074:        return IO_R_SUCCESS;
        !          1075:     } else if (strcmp(parameterName, IO_POSTSCRIPT_DRIVER) == 0) {
        !          1076:        /*
        !          1077:         * FIXME: This is a temporary hack till WS gets fixed. At that time
        !          1078:         * WS will use IO_COMMIT_TO_PENDING_DISPLAY_MODE and this code can be
        !          1079:         * deleted. -- rkd.
        !          1080:         */
        !          1081:        if (_pendingDisplayMode >= 0) {
        !          1082:            (void) [self _commitToPendingMode];
        !          1083:            _pendingDisplayMode = -1;   /* mode switch is complete */
        !          1084:        }
        !          1085:        return [super getCharValues:parameterArray
        !          1086:            forParameter:parameterName
        !          1087:            count:count];
        !          1088:     } else {
        !          1089:        return [super getCharValues:parameterArray
        !          1090:            forParameter:parameterName
        !          1091:            count:count];
        !          1092:     }
        !          1093: }
        !          1094: 
        !          1095: // Description:        Set parameters for the display object. This can be used
        !          1096: //             to set the mapping tables used for conversion between
        !          1097: //             4 BPS and 5 BPS data in 5-5-5 frame buffer support,
        !          1098: //             and bm256 <--> bm38 conversion tables as well.
        !          1099: //
        !          1100: - (IOReturn)setCharValues:(unsigned char *)parameterArray
        !          1101:                forParameter:(IOParameterName)parameterName
        !          1102:                count:(unsigned int)count
        !          1103: {
        !          1104:     int i, mode;
        !          1105: 
        !          1106:     if (strcmp(parameterName, STDFB_4BPS_TO_5BPS_MAP) == 0) {
        !          1107:        if (count != STDFB_4BPS_TO_5BPS_MAP_SIZE)
        !          1108:            return IO_R_INVALID_ARG;
        !          1109:        if (_bm34To35SampleTable == NULL)
        !          1110:            _bm34To35SampleTable = IOMalloc(STDFB_4BPS_TO_5BPS_MAP_SIZE);
        !          1111:        for (i = 0; i < count; i++)
        !          1112:            _bm34To35SampleTable[i] = parameterArray[i];
        !          1113:        return IO_R_SUCCESS;
        !          1114: 
        !          1115:     } else if (strcmp(parameterName, STDFB_5BPS_TO_4BPS_MAP) == 0) {
        !          1116:        if (count != STDFB_5BPS_TO_4BPS_MAP_SIZE)
        !          1117:            return IO_R_INVALID_ARG;
        !          1118:        if (_bm35To34SampleTable == NULL)
        !          1119:            _bm35To34SampleTable = IOMalloc(STDFB_5BPS_TO_4BPS_MAP_SIZE);
        !          1120:        for (i = 0; i < count; i++)
        !          1121:            _bm35To34SampleTable[i] = parameterArray[i];
        !          1122:        return IO_R_SUCCESS;
        !          1123:     } else if (strcmp(parameterName, IO_COMMIT_TO_PENDING_DISPLAY_MODE) == 0) {
        !          1124:        if (_pendingDisplayMode >= 0) {
        !          1125:            (void) [self _commitToPendingMode];
        !          1126:            _pendingDisplayMode = -1;   /* mode switch is complete */
        !          1127:            return IO_R_SUCCESS;
        !          1128:        } else {
        !          1129:            return IO_R_UNSUPPORTED;
        !          1130:        }
        !          1131:     } else {
        !          1132:        return [super setCharValues:parameterArray
        !          1133:            forParameter:parameterName
        !          1134:            count:count];
        !          1135:     }
        !          1136: }
        !          1137: 
        !          1138: - (void)enterLinearMode;
        !          1139: // Description:        Put the display into linear framebuffer mode. This typically
        !          1140: //             happens when the window server starts running. This method
        !          1141: //             is implemented by subclasses in a device specific way. The
        !          1142: //             value returned is a pointer to the framebuffer in user space.
        !          1143: {
        !          1144: }
        !          1145: 
        !          1146: - (void)revertToVGAMode;
        !          1147: // Description:        Get the device out of whatever advanced linear mode it was
        !          1148: //             using and back into a state where it can be used as a standard
        !          1149: //             VGA device. This method is implemented by subclasses in a
        !          1150: //             device specific way.
        !          1151: {
        !          1152: }
        !          1153: 
        !          1154: - (BOOL)setPendingDisplayMode:(int)displayMode
        !          1155: {
        !          1156:     IODisplayInfo *displayInfo; 
        !          1157:        
        !          1158:     displayInfo = [self displayInfo];          // current mode
        !          1159:     
        !          1160:     if (displayMode < 0 || displayMode >= [self displayModeCount])     {
        !          1161:         IOLog("%s: Invalid display mode: %d\n", [self name], displayMode);
        !          1162:        return NO;
        !          1163:     }
        !          1164:     if (displayInfo->modeUnavailableFlag != 0) {
        !          1165:         IOLog("%s: Display mode %d not available (error 0x%0x)\n", 
        !          1166:                [self name], displayMode, displayInfo->modeUnavailableFlag);
        !          1167:        return NO;
        !          1168:     }
        !          1169:     _pendingDisplayMode = displayMode;
        !          1170:     return YES;
        !          1171: }
        !          1172: 
        !          1173: - (int)pendingDisplayMode
        !          1174: {
        !          1175:     return _pendingDisplayMode;
        !          1176: }
        !          1177: 
        !          1178: /*
        !          1179:  * The subclass must implement these two methods if it want display mode
        !          1180:  * changes. 
        !          1181:  */
        !          1182: - (unsigned int)displayModeCount
        !          1183: {
        !          1184:     return _displayModeCount;
        !          1185: }
        !          1186: 
        !          1187: - (IODisplayInfo *)displayModes
        !          1188: {
        !          1189:     return _displayModes;
        !          1190: }
        !          1191: 
        !          1192: /*
        !          1193:  * Subclass should override and supply appropriate values. 
        !          1194:  */
        !          1195: - (unsigned int)displayMemorySize
        !          1196: {
        !          1197:     return 0;
        !          1198: }
        !          1199: 
        !          1200: - (unsigned int)ramdacSpeed
        !          1201: {
        !          1202:     return 0;
        !          1203: }
        !          1204: 
        !          1205: - (vm_address_t)mapFrameBufferAtPhysicalAddress:(unsigned int)addr
        !          1206:        length:(int)length;
        !          1207: // Description:        Look up the physical memory location for this device instance
        !          1208: //             and map it into VM for use by the device driver. If problems
        !          1209: //             occur, the method returns (vm_address_t)0. If addr is not 0,
        !          1210: //             then it is used as the physical memory address and
        !          1211: //             length is used as the length.
        !          1212: {
        !          1213:     vm_address_t       vmLocation;
        !          1214:     IOReturn           result = IO_R_SUCCESS;
        !          1215:     IOCache            cacheType;
        !          1216:     
        !          1217:     switch ([self displayInfo]->flags & IO_DISPLAY_CACHE_MASK) {
        !          1218:         default:
        !          1219:         case IO_DISPLAY_CACHE_WRITETHROUGH:
        !          1220:            cacheType = IO_WriteThrough;
        !          1221:            break;
        !          1222:        case IO_DISPLAY_CACHE_COPYBACK:
        !          1223:            cacheType = IO_CopyBack;
        !          1224:            break;
        !          1225:        case IO_DISPLAY_CACHE_OFF:
        !          1226:            cacheType = IO_CacheOff;
        !          1227:            break;
        !          1228:        }
        !          1229: 
        !          1230:     if (addr != 0)     // Override configuration XXX BOGUS!!!
        !          1231:     {
        !          1232:        // This is totally bogus.  I cannot believe that it is
        !          1233:        // public API.  NB: This mapping cannot be freed using
        !          1234:        // unmapMemoryRange:from: in IOEISADirectDevice.
        !          1235:        if (_KernBusMemoryCreateMapping(addr,
        !          1236:                                length,
        !          1237:                                &vmLocation,
        !          1238:                                current_task_EXTERNAL(),
        !          1239:                                YES,
        !          1240:                                cacheType) != KERN_SUCCESS)
        !          1241:                result = IO_R_NO_MEMORY;
        !          1242:     }
        !          1243:     else
        !          1244:     {
        !          1245:        result = [self  mapMemoryRange:0
        !          1246:                        to:&vmLocation
        !          1247:                        findSpace:YES
        !          1248:                        cache:cacheType];
        !          1249:     }
        !          1250: 
        !          1251:     if (result != IO_R_SUCCESS)
        !          1252:     {
        !          1253:        IOLog(
        !          1254:            "IOFrameBufferDisplay/mapFrameBuffer: Can't map memory (%s)\n",
        !          1255:            [self stringFromReturn:result]);
        !          1256:        return (vm_address_t)0;
        !          1257:     }
        !          1258:     
        !          1259:     return vmLocation;
        !          1260: }
        !          1261: 
        !          1262: #if 0
        !          1263: - (vm_address_t)mapFrameBufferAtPhysicalAddress:(unsigned int)addr
        !          1264:        length:(int)length;
        !          1265: // Description:        Look up the physical memory location for this device instance
        !          1266: //             and map it into VM for use by the device driver. If problems
        !          1267: //             occur, the method returns (vm_address_t)0. If addr is not 0,
        !          1268: //             then it is used as the physical memory address and
        !          1269: //             length is used as the length.
        !          1270: {
        !          1271:     vm_address_t       vmLocation;
        !          1272:     IOReturn           result = IO_R_SUCCESS;
        !          1273:     IOCache            cacheType;
        !          1274:     IORange            *range;
        !          1275:     
        !          1276:     /* The default is no cache */
        !          1277:     switch ([self displayInfo]->flags & IO_DISPLAY_CACHE_MASK) {
        !          1278:         default:
        !          1279:         case IO_DISPLAY_CACHE_WRITETHROUGH:
        !          1280:            cacheType = IO_WriteThrough;
        !          1281:            break;
        !          1282:        case IO_DISPLAY_CACHE_COPYBACK:
        !          1283:            cacheType = IO_CopyBack;
        !          1284:            break;
        !          1285:        case IO_DISPLAY_CACHE_OFF:
        !          1286:            cacheType = IO_CacheOff;
        !          1287:            break;
        !          1288:        }
        !          1289: 
        !          1290:     range = [[self deviceDescription] memoryRangeList];
        !          1291:     
        !          1292:     if (addr == 0)
        !          1293:        addr = range[0].start;
        !          1294:     if (length == 0)
        !          1295:        length = range[0].size;
        !          1296: 
        !          1297:     /*
        !          1298:      * The framebuffer must be contained in memory range 0. 
        !          1299:      */
        !          1300:     if ((addr < range[0].start) || 
        !          1301:         (addr+length > range[0].start + range[0].size))        {
        !          1302:        IOLog("%s: framebuffer is not contained in first memory range\n",
        !          1303:                [self name]);
        !          1304:        return IO_R_NO_MEMORY;
        !          1305:     }
        !          1306:     
        !          1307:     result = [self  mapMemoryRange:0
        !          1308:                    to:&vmLocation
        !          1309:                    findSpace:YES
        !          1310:                    cache:cacheType];
        !          1311:     IOLog("%s: Mapped framed buffer at 0x%x\n", [self name],
        !          1312:                vmLocation);
        !          1313:     
        !          1314:     if (result != IO_R_SUCCESS) {
        !          1315:        IOLog(
        !          1316:            "IOFrameBufferDisplay/mapFrameBuffer: Can't map memory (%s)\n",
        !          1317:            [self stringFromReturn:result]);
        !          1318:        return (vm_address_t)0;
        !          1319:     }
        !          1320:     
        !          1321:     return vmLocation + (addr - range[0].start);
        !          1322: }
        !          1323: 
        !          1324: - (void)unMapFrameBuffer:(unsigned int)addr length:(int)length
        !          1325: {
        !          1326:     void       *vmLocation;
        !          1327:     IORange    *range;
        !          1328:     
        !          1329:     range = [[self deviceDescription] memoryRangeList];
        !          1330:     
        !          1331:     if (addr == 0)
        !          1332:        addr = range[0].start;
        !          1333:     if (length == 0)
        !          1334:        length = range[0].size;
        !          1335: 
        !          1336:     /*
        !          1337:      * The framebuffer must be contained in memory range 0. 
        !          1338:      */
        !          1339:     if ((addr < range[0].start) || 
        !          1340:         (addr+length > range[0].start + range[0].size))        {
        !          1341:        IOLog("%s: framebuffer is not contained in first memory range\n",
        !          1342:                [self name]);
        !          1343:        return IO_R_NO_MEMORY;
        !          1344:     }
        !          1345:     
        !          1346:     vmLocation = [self displayInfo]->frameBuffer - (addr - range[0].start);
        !          1347:     
        !          1348:     if (vmLocation)    {
        !          1349:        [self unmapMemoryRange:0 from:(vm_address_t)vmLocation];
        !          1350:     }
        !          1351: }
        !          1352: #endif 0
        !          1353: 
        !          1354: 
        !          1355: - (int)selectMode:(const IODisplayInfo *)modeList count:(int)count
        !          1356:        valid:(const BOOL *)isValid modeString:(const char *)modeString
        !          1357: {
        !          1358:     const char *displayMode;
        !          1359:     IOConfigTable *configTable;
        !          1360:     int k, width, height;
        !          1361:     int screenWidth, screenHeight, memorySize, ramdacSpeed;
        !          1362:     int scanRate;
        !          1363:     unsigned int modeUnavailableFlag;
        !          1364:     IOBitsPerPixel bitsPerPixel;
        !          1365:     IOColorSpace colorSpace;
        !          1366:     int refreshRate;
        !          1367:     const char *s;
        !          1368: 
        !          1369:     _displayModeCount = count;
        !          1370:     _displayModes = modeList;
        !          1371:     
        !          1372:     /* Get the string describing the display mode. */
        !          1373: 
        !          1374:     if (modeString == NULL)    {
        !          1375:     
        !          1376:        configTable = [[self deviceDescription] configTable];
        !          1377:        if (configTable == nil)
        !          1378:            return -1;
        !          1379: 
        !          1380:        displayMode = [configTable valueForStringKey:"Display Mode"];
        !          1381:        if (displayMode == 0) {
        !          1382:            /* Historical: for 3.1 drivers only. */
        !          1383:            displayMode = [configTable valueForStringKey:"DisplayMode"];
        !          1384:            if (displayMode == 0)
        !          1385:                return -1;
        !          1386:        }
        !          1387:     } else {
        !          1388:        displayMode = modeString;
        !          1389:     }
        !          1390: 
        !          1391:     /* Parse the string.  It should be of the form
        !          1392:      *   Width:# Height:# ColorSpace:(BW:#|RGB:###/#) Refresh:# Hz
        !          1393:      * where `Width' and `Height' specify the width and height of the
        !          1394:      * framebuffer, `ColorSpace' specifies the color space for the
        !          1395:      * framebuffer, and `Refresh' specifies the refresh rate in Hz.
        !          1396:      * The color space parameter should be either BW followed by the
        !          1397:      * bits/pixel, or RGB followed by the bits/component for each
        !          1398:      * component followed by the bits/pixel.
        !          1399:      *
        !          1400:      * For example, here is the display mode specification for the
        !          1401:      * RGB mode of the S3:
        !          1402:      *   Width: 800 Height: 600 ColorSpace: RGB:555/16 Refresh: 60 Hz
        !          1403:      */
        !          1404: 
        !          1405:     height = width = 0;
        !          1406:     s = find_parameter("Width:", displayMode);
        !          1407:     if (s != 0)        {
        !          1408:        width = strtol(s, 0, 10);
        !          1409:     }
        !          1410:     
        !          1411:     s = find_parameter("Height:", displayMode);
        !          1412:     if (s != 0)        {
        !          1413:        height = strtol(s, 0, 10);
        !          1414:     }
        !          1415: 
        !          1416:     s = find_parameter("Refresh:", displayMode);
        !          1417:     if (s == 0)
        !          1418:        return -1;
        !          1419:     refreshRate = strtol(s, 0, 10);
        !          1420: 
        !          1421:     s = find_parameter("ColorSpace:", displayMode);
        !          1422:     if (s == 0)
        !          1423:        return -1;
        !          1424:     if (strncmp(s, "BW:2", 4) == 0) {
        !          1425:         bitsPerPixel = IO_2BitsPerPixel;
        !          1426:        colorSpace = IO_OneIsBlackColorSpace;
        !          1427:     } else if (strncmp(s, "BW:8", 4) == 0) {
        !          1428:         bitsPerPixel = IO_8BitsPerPixel;
        !          1429:        colorSpace = IO_OneIsWhiteColorSpace;
        !          1430:     } else if (strncmp(s, "RGB:256/8", 9) == 0) {
        !          1431:         bitsPerPixel = IO_8BitsPerPixel;
        !          1432:        colorSpace = IO_RGBColorSpace;
        !          1433:     } else if (strncmp(s, "RGB:444/16", 10) == 0) {
        !          1434:         bitsPerPixel = IO_12BitsPerPixel;
        !          1435:        colorSpace = IO_RGBColorSpace;
        !          1436:     } else if (strncmp(s, "RGB:555/16", 10) == 0) {
        !          1437:         bitsPerPixel = IO_15BitsPerPixel;
        !          1438:        colorSpace = IO_RGBColorSpace;
        !          1439:     } else if (strncmp(s, "RGB:888/32", 10) == 0) {
        !          1440:         bitsPerPixel = IO_24BitsPerPixel;
        !          1441:        colorSpace = IO_RGBColorSpace;
        !          1442:     } else {
        !          1443:        return -1;
        !          1444:     }
        !          1445: 
        !          1446:     /*
        !          1447:      * Now look for 4.0 style optional parameters. The display mode
        !          1448:      * specification looks like "Resolution:1280x1024 Screen:1600x1200
        !          1449:      * Refresh:60Hz ColorSpace:RGB:444/16 Memory:4MB RAMDAC:175Hz Sync:100Hz"; 
        !          1450:      */
        !          1451:      
        !          1452:     s = find_parameter("Resolution:", displayMode);
        !          1453:     if (s != 0)        {
        !          1454:         char *end;
        !          1455:        width = strtol(s, &end, 10);
        !          1456:        height = strtol(end+1, 0, 10);
        !          1457:     }
        !          1458:     
        !          1459:     if ((height == 0) || (width == 0))
        !          1460:        return -1;
        !          1461:        
        !          1462:     s = find_parameter("Screen:", displayMode);
        !          1463:     if (s != 0)        {
        !          1464:         char *end;
        !          1465:        screenWidth = strtol(s, &end, 10);
        !          1466:        screenHeight = strtol(end+1, 0, 10);
        !          1467:     } else {
        !          1468:        screenWidth = width;
        !          1469:        screenHeight = height;
        !          1470:     }
        !          1471: 
        !          1472:     /* These parameters are not used by the superclass. */
        !          1473:     s = find_parameter("Memory:", displayMode);
        !          1474:     if (s != 0)        {
        !          1475:        memorySize = strtol(s, 0, 10);
        !          1476:     }
        !          1477: 
        !          1478:     s = find_parameter("RAMDAC:", displayMode);
        !          1479:     if (s != 0)        {
        !          1480:        ramdacSpeed = strtol(s, 0, 10);
        !          1481:     }
        !          1482: 
        !          1483:     s = find_parameter("Sync:", displayMode);
        !          1484:     if (s != 0)        {
        !          1485:        scanRate = strtol(s, 0, 10);
        !          1486:     }
        !          1487: 
        !          1488:     modeUnavailableFlag = 0;
        !          1489:     s = find_parameter("Available:", displayMode);
        !          1490:     if (s != 0)        {
        !          1491:        modeUnavailableFlag = strtol(s, 0, 10);
        !          1492:     }
        !          1493:     
        !          1494:     /* Now try to match these parameters with the list of modes. */
        !          1495:     for (k = 0; k < count; k++) {
        !          1496:         
        !          1497:        if (isValid != 0 && !isValid[k])
        !          1498:            continue;
        !          1499:         if (modeUnavailableFlag != 0)
        !          1500:             continue;
        !          1501:        if (modeList[k].width == width
        !          1502:            && modeList[k].height == height
        !          1503:            && modeList[k].colorSpace == colorSpace
        !          1504:            && modeList[k].bitsPerPixel == bitsPerPixel
        !          1505:            && modeList[k].refreshRate == refreshRate) {
        !          1506:            switch (bitsPerPixel) {
        !          1507:            case IO_2BitsPerPixel:  s = "BW:2"; break;
        !          1508:            case IO_8BitsPerPixel:
        !          1509:                if (colorSpace == IO_RGBColorSpace) s = "RGB:256/8";
        !          1510:                else                                s = "BW:8";
        !          1511:                break;
        !          1512:            case IO_12BitsPerPixel: s = "RGB:444/16"; break;
        !          1513:            case IO_15BitsPerPixel: s = "RGB:555/16"; break;
        !          1514:            case IO_24BitsPerPixel: s = "RGB:888/32"; break;
        !          1515:            default:     s = "Unknown color space"; break;
        !          1516:            }
        !          1517:            IOLog("Display: Mode selected: %d x %d @ %d Hz (%s)\n",
        !          1518:                width, height, refreshRate, s);
        !          1519:            _currentDisplayMode = k;
        !          1520:            return k;
        !          1521:        }
        !          1522:     }
        !          1523:     IOLog("Display: Requested mode is not available.\n");
        !          1524:     return -1;
        !          1525: }
        !          1526: 
        !          1527: - (int)selectMode: (const IODisplayInfo *)modeList count:(int)count
        !          1528: {
        !          1529:     return [self selectMode:modeList count:count valid:0 modeString:NULL];
        !          1530: }
        !          1531: 
        !          1532: - (int)selectMode:(const IODisplayInfo *)modeList count:(int)count
        !          1533:        valid:(const BOOL *)isValid
        !          1534: {
        !          1535:     return [self selectMode:modeList count:count valid:isValid modeString:NULL];
        !          1536: }
        !          1537: 
        !          1538: - setTransferTable:(const unsigned int *)table count:(int)count
        !          1539: {
        !          1540:     return self;
        !          1541: }
        !          1542: 
        !          1543: @end
        !          1544: 
        !          1545: 
        !          1546: //
        !          1547: // BEGIN:      PRIVATE Methods
        !          1548: //
        !          1549: @implementation IOFrameBufferDisplay(Private)
        !          1550: 
        !          1551: - (BOOL)_commitToPendingMode
        !          1552: {
        !          1553:     IODisplayInfo *displayInfo, *displayModes;
        !          1554:     int mode = _pendingDisplayMode; 
        !          1555:        
        !          1556:     displayInfo = [self displayInfo];          // current mode
        !          1557:     
        !          1558:     displayModes = [self displayModes];                // all possible modes
        !          1559:     if (displayModes == NULL)
        !          1560:        return NO;
        !          1561:        
        !          1562:     bzero(displayInfo->pixelEncoding, IO_MAX_PIXEL_BITS);
        !          1563:     strncpy(displayInfo->pixelEncoding, displayModes[mode].pixelEncoding,
        !          1564:        strlen(displayModes[mode].pixelEncoding));
        !          1565:     displayInfo->width = displayModes[mode].width;
        !          1566:     displayInfo->height = displayModes[mode].height;
        !          1567:     displayInfo->totalWidth = displayModes[mode].totalWidth;
        !          1568:     displayInfo->rowBytes = displayModes[mode].rowBytes;
        !          1569:     displayInfo->refreshRate = displayModes[mode].refreshRate;
        !          1570:     displayInfo->bitsPerPixel = displayModes[mode].bitsPerPixel;
        !          1571:     displayInfo->colorSpace = displayModes[mode].colorSpace;
        !          1572:     displayInfo->parameters = displayModes[mode].parameters;
        !          1573: 
        !          1574:     displayInfo->screenWidth = displayModes[mode].screenWidth;
        !          1575:     displayInfo->screenHeight = displayModes[mode].screenHeight;
        !          1576:     displayInfo->scanRate = displayModes[mode].scanRate;
        !          1577:     displayInfo->memorySize = displayModes[mode].memorySize;
        !          1578:     displayInfo->dotClockRate = displayModes[mode].dotClockRate;
        !          1579:     displayInfo->modeUnavailableFlag = displayModes[mode].modeUnavailableFlag;
        !          1580: 
        !          1581:     /*
        !          1582:      * If the driver defined the flag use it else chhose a default behavior. 
        !          1583:      */
        !          1584:     if (displayModes[mode].flags != 0) {
        !          1585:        displayInfo->flags = displayModes[mode].flags;
        !          1586:     } else {
        !          1587:        if (displayInfo->bitsPerPixel == IO_8BitsPerPixel) {
        !          1588:            displayInfo->flags = IO_DISPLAY_HAS_TRANSFER_TABLE;
        !          1589:        } else {
        !          1590:            displayInfo->flags = IO_DISPLAY_NEEDS_SOFTWARE_GAMMA_CORRECTION;
        !          1591:        }
        !          1592:     }
        !          1593:     _currentDisplayMode = mode;
        !          1594:     
        !          1595:     return YES;
        !          1596: }
        !          1597: 
        !          1598: - property_IODeviceClass:(char *)classes length:(unsigned int *)maxLen
        !          1599: {
        !          1600:     strcpy( classes, IOClassFramebuffer);
        !          1601:     return( self);
        !          1602: }
        !          1603: 
        !          1604: @end
        !          1605: 

unix.superglobalmegacorp.com

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