|
|
1.1 root 1: /*
2: * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
24: *
25: * HISTORY
26: *
27: * 01 Sep 92 Portions from Joe Pasqua, Created.
28: */
29:
30:
31: #include <IOKit/IOLib.h>
32: #include <libkern/c++/OSContainers.h>
33:
34: #include <IOKit/IOWorkLoop.h>
35: #include <IOKit/IOInterruptEventSource.h>
36: #include <IOKit/IOPlatformExpert.h>
37: #include <IOKit/IOBufferMemoryDescriptor.h>
38:
39: #define IOFRAMEBUFFER_PRIVATE
40: #include <IOKit/graphics/IOFramebuffer.h>
41: #include <IOKit/graphics/IODisplay.h>
42:
43: #include "IOFramebufferUserClient.h"
44: #include "IODisplayWrangler.h"
45: #include "IOFramebufferReallyPrivate.h"
46:
47: #include <string.h>
48: #include <IOKit/assert.h>
49:
50: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
51:
52: #undef super
53: #define super IOGraphicsDevice
54:
55: OSDefineMetaClass( IOFramebuffer, IOGraphicsDevice )
56: OSDefineAbstractStructors( IOFramebuffer, IOGraphicsDevice )
57:
58: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
59:
60: #define GetShmem(instance) ((StdFBShmem_t *)(instance->priv))
61:
62: #define CLEARSEMA(shmem) ev_unlock(&shmem->cursorSema)
63: #define SETSEMA(shmem) \
64: if (!ev_try_lock(&shmem->cursorSema)) return;
65: #define TOUCHBOUNDS(one, two) \
66: (((one.minx < two.maxx) && (two.minx < one.maxx)) && \
67: ((one.miny < two.maxy) && (two.miny < one.maxy)))
68:
69: /*
70: * Cursor rendering
71: */
72:
73: #include "IOCursorBlits.h"
74:
75: inline void IOFramebuffer::StdFBDisplayCursor( IOFramebuffer * inst )
76: {
77: StdFBShmem_t *shmem;
78: Bounds saveRect;
79: volatile unsigned char *vramPtr; /* screen data pointer */
80: unsigned int cursStart;
81: unsigned int cursorWidth;
82: int width;
83: int height;
84:
85: shmem = GetShmem(inst);
86: saveRect = shmem->cursorRect;
87: /* Clip saveRect vertical within screen bounds */
88: if (saveRect.miny < shmem->screenBounds.miny)
89: saveRect.miny = shmem->screenBounds.miny;
90: if (saveRect.maxy > shmem->screenBounds.maxy)
91: saveRect.maxy = shmem->screenBounds.maxy;
92: if (saveRect.minx < shmem->screenBounds.minx)
93: saveRect.minx = shmem->screenBounds.minx;
94: if (saveRect.maxx > shmem->screenBounds.maxx)
95: saveRect.maxx = shmem->screenBounds.maxx;
96: shmem->saveRect = saveRect; /* Remember save rect for RemoveCursor */
97:
98: vramPtr = inst->frameBuffer +
99: (inst->rowBytes * (saveRect.miny - shmem->screenBounds.miny)) +
100: (inst->bytesPerPixel * (saveRect.minx - shmem->screenBounds.minx));
101:
102: width = saveRect.maxx - saveRect.minx;
103: height = saveRect.maxy - saveRect.miny;
104: cursorWidth = shmem->cursorSize[shmem->frame].width;
105:
106: cursStart = (saveRect.miny - shmem->cursorRect.miny) * cursorWidth +
107: (saveRect.minx - shmem->cursorRect.minx);
108:
109: if( inst->cursorBlitProc)
110: inst->cursorBlitProc( inst,
111: (void *) shmem,
112: vramPtr,
113: cursStart,
114: inst->totalWidth - width, /* vramRow */
115: cursorWidth - width, /* cursRow */
116: width,
117: height);
118: }
119:
120: // Description: RemoveCursor erases the cursor by replacing the background
121: // image that was saved by the previous call to DisplayCursor.
122: // If the frame buffer is cacheable, flush at the end of the
123: // drawing operation.
124:
125: inline void IOFramebuffer::StdFBRemoveCursor( IOFramebuffer * inst )
126: {
127: StdFBShmem_t *shmem;
128: volatile unsigned char *vramPtr; /* screen data pointer */
129: unsigned int vramRow;
130: int width;
131: int height;
132:
133: shmem = GetShmem(inst);
134:
135: vramRow = inst->totalWidth; /* Scanline width in pixels */
136:
137: vramPtr = inst->frameBuffer +
138: (inst->rowBytes * (shmem->saveRect.miny - shmem->screenBounds.miny))
139: + (inst->bytesPerPixel *
140: (shmem->saveRect.minx - shmem->screenBounds.minx));
141:
142: width = shmem->saveRect.maxx - shmem->saveRect.minx;
143: height = shmem->saveRect.maxy - shmem->saveRect.miny;
144: vramRow -= width;
145:
146: if( inst->cursorRemoveProc)
147: inst->cursorRemoveProc( inst, (void *)shmem,
148: vramPtr, vramRow, width, height);
149: }
150:
151: inline void IOFramebuffer::RemoveCursor( IOFramebuffer * inst )
152: {
153: StdFBShmem_t * shmem = GetShmem(inst);
154:
155: if( shmem->hardwareCursorActive ) {
156: Point * hs;
157:
158: hs = &shmem->hotSpot[shmem->frame];
159: inst->setCursorState(
160: shmem->cursorLoc.x - hs->x - shmem->screenBounds.minx,
161: shmem->cursorLoc.y - hs->y - shmem->screenBounds.miny, false );
162: } else
163: StdFBRemoveCursor(inst);
164: }
165:
166: inline void IOFramebuffer::DisplayCursor( IOFramebuffer * inst )
167: {
168: Point * hs;
169: StdFBShmem_t * shmem = GetShmem(inst);
170: SInt32 x, y;
171:
172: hs = &shmem->hotSpot[shmem->frame];
173: x = shmem->cursorLoc.x - hs->x;
174: y = shmem->cursorLoc.y - hs->y;
175:
176: if( shmem->hardwareCursorActive )
177: inst->setCursorState( x - shmem->screenBounds.minx,
178: y - shmem->screenBounds.miny, true );
179: else {
180: shmem->cursorRect.maxx = (shmem->cursorRect.minx = x)
181: + shmem->cursorSize[shmem->frame].width;
182: shmem->cursorRect.maxy = (shmem->cursorRect.miny = y)
183: + shmem->cursorSize[shmem->frame].height;
184: StdFBDisplayCursor(inst);
185: shmem->oldCursorRect = shmem->cursorRect;
186: }
187: }
188:
189: inline void IOFramebuffer::SysHideCursor( IOFramebuffer * inst )
190: {
191: if (!GetShmem(inst)->cursorShow++)
192: RemoveCursor(inst);
193: }
194:
195: inline void IOFramebuffer::SysShowCursor( IOFramebuffer * inst )
196: {
197: StdFBShmem_t *shmem;
198:
199: shmem = GetShmem(inst);
200:
201: if (shmem->cursorShow)
202: if (!--(shmem->cursorShow))
203: DisplayCursor(inst);
204: }
205:
206: inline void IOFramebuffer::CheckShield( IOFramebuffer * inst )
207: {
208: Point * hs;
209: int intersect;
210: Bounds tempRect;
211: StdFBShmem_t * shmem = GetShmem(inst);
212:
213: /* Calculate temp cursorRect */
214: hs = &shmem->hotSpot[shmem->frame];
215: tempRect.maxx = (tempRect.minx = (shmem->cursorLoc).x - hs->x)
216: + shmem->cursorSize[shmem->frame].width;
217: tempRect.maxy = (tempRect.miny = (shmem->cursorLoc).y - hs->y)
218: + shmem->cursorSize[shmem->frame].height;
219:
220: intersect = TOUCHBOUNDS(tempRect, shmem->shieldRect);
221: if (intersect != shmem->shielded)
222: (shmem->shielded = intersect) ?
223: SysHideCursor(inst) : SysShowCursor(inst);
224: }
225:
226: /**
227: ** external methods
228: **/
229:
230: void IOFramebuffer::setupCursor( IOPixelInformation * info )
231: {
232: StdFBShmem_t * shmem = GetShmem(this);
233: volatile unsigned char * bits;
234: IOByteCount cursorImageBytes;
235:
236: rowBytes = info->bytesPerRow;
237: totalWidth = (rowBytes * 8) / info->bitsPerPixel;
238: bytesPerPixel = info->bitsPerPixel / 8;
239: frameBuffer = (volatile unsigned char *) vramMap->getVirtualAddress();
240:
241: #ifdef __i386__
242: {
243: // FIX!!!
244: extern void * vid_start;
245: frameBuffer = (volatile unsigned char *) vid_start;
246: }
247: #endif
248:
249: if( shmem) {
250: // a default if no one calls IOFBSetBounds()
251: shmem->screenBounds.maxx = info->activeWidth;
252: shmem->screenBounds.maxy = info->activeHeight;
253:
254: cursorImageBytes = maxCursorSize.width * maxCursorSize.height
255: * bytesPerPixel;
256: bits = shmem->cursor;
257: for( int i = 0; i < kIOFBNumCursorFrames; i++ ) {
258: cursorImages[i] = bits;
259: bits += cursorImageBytes;
260: shmem->cursorSize[i] = maxCursorSize;
261: }
262: if( info->bitsPerPixel <= 8) {
263: for( int i = 0; i < kIOFBNumCursorFrames; i++ ) {
264: cursorMasks[i] = bits;
265: bits += cursorImageBytes;
266: }
267: }
268: cursorSave = bits;
269: }
270:
271: switch( info->bitsPerPixel) {
272: case 8:
273: if( colorConvert.t._bm256To38SampleTable
274: && colorConvert.t._bm38To256SampleTable) {
275: cursorBlitProc = (CursorBlitProc) StdFBDisplayCursor8P;
276: cursorRemoveProc = (CursorRemoveProc) StdFBRemoveCursor8;
277: }
278: break;
279: case 16:
280: if( colorConvert.t._bm34To35SampleTable
281: && colorConvert.t._bm35To34SampleTable) {
282: cursorBlitProc = (CursorBlitProc) StdFBDisplayCursor555;
283: cursorRemoveProc = (CursorRemoveProc) StdFBRemoveCursor16;
284: }
285: break;
286: case 32:
287: if( colorConvert.t._bm256To38SampleTable
288: && colorConvert.t._bm38To256SampleTable) {
289: cursorBlitProc = (CursorBlitProc) StdFBDisplayCursor32Axxx;
290: cursorRemoveProc = (CursorRemoveProc) StdFBRemoveCursor32;
291: }
292: break;
293: default:
294: IOLog("%s: can't do cursor at depth %ld\n",
295: getName(), info->bitsPerPixel);
296: cursorBlitProc = (CursorBlitProc) NULL;
297: cursorRemoveProc = (CursorRemoveProc) NULL;
298: break;
299: }
300: }
301:
302: void IOFramebuffer::stopCursor( void )
303: {
304: cursorBlitProc = (CursorBlitProc) NULL;
305: cursorRemoveProc = (CursorRemoveProc) NULL;
306: }
307:
308: IOReturn IOFramebuffer::createSharedCursor(
309: int shmemVersion, int maxWidth, int maxHeight )
310: {
311: StdFBShmem_t * shmem;
312: IOByteCount size, maxImageSize;
313:
314: kprintf("createSharedCursor vers = %d, %d x %d\n",
315: shmemVersion, maxWidth, maxHeight);
316:
317: if( shmemVersion != kIOFBCurrentShmemVersion)
318: return( kIOReturnUnsupported);
319:
320: shmemClientVersion = shmemVersion;
321: if( sharedCursor) {
322: sharedCursor->release();
323: priv = 0;
324: }
325:
326: maxImageSize = (maxWidth * maxHeight * kIOFBMaxCursorDepth) / 8;
327:
328: size = sizeof( StdFBShmem_t)
329: + ((kIOFBNumCursorFrames + 1) * maxImageSize);
330:
331: sharedCursor = IOBufferMemoryDescriptor::withCapacity(
332: round_page(size), kIODirectionNone, false );
333: if( !sharedCursor)
334: return( kIOReturnNoMemory );
335: sharedCursor->setLength( size );
336:
337: shmem = (StdFBShmem_t *) sharedCursor->getBytesNoCopy();
338: priv = shmem;
339:
340: // Init shared memory area
341: bzero( shmem, size );
342: shmem->version = kIOFBCurrentShmemVersion;
343: shmem->structSize = size;
344: shmem->cursorShow = 1;
345: shmem->hardwareCursorCapable = haveHWCursor;
346:
347: maxCursorSize.width = maxWidth;
348: maxCursorSize.height = maxHeight;
349:
350: doSetup( false );
351:
352: return( kIOReturnSuccess);
353: }
354:
355: IOReturn IOFramebuffer::setBoundingRect( Bounds * bounds )
356: {
357: StdFBShmem_t *shmem;
358:
359: shmem = GetShmem(this);
360: if( NULL == shmem)
361: return( kIOReturnUnsupported);
362:
363: shmem->screenBounds = *bounds;
364:
365: return( kIOReturnSuccess);
366: }
367:
368: /**
369: ** IOUserClient methods
370: **/
371:
372: IOReturn IOFramebuffer::newUserClient( task_t owningTask,
373: void * security_id,
374: UInt32 type,
375: IOUserClient ** handler )
376:
377: {
378: #if 1
379: static UInt8 data[] = { 0x00, 0x03, 0x04, 0x07, 0x08, 0x0b, 0x0c, 0x0f,
380: 0x10, 0x13, 0x14, 0x17, 0x18, 0x1b, 0x1c, 0x1f,
381:
382: 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03,
383: 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07,
384: 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b,
385: 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f };
386: colorConvert.t._bm34To35SampleTable = data;
387: colorConvert.t._bm35To34SampleTable = data + 16;
388: #endif
389:
390: IOReturn err = kIOReturnSuccess;
391: IOUserClient * newConnect = 0;
392: IOUserClient * theConnect = 0;
393:
394: switch( type ) {
395:
396: case kIOFBServerConnectType:
397: if( serverConnect)
398: err = kIOReturnExclusiveAccess;
399: else {
400:
401: if( isConsoleDevice())
402: getPlatform()->setConsoleInfo( 0, kPEReleaseScreen);
403:
404: err = IODisplayWrangler::clientStart( this );
405: if( kIOReturnSuccess == err)
406: newConnect = IOFramebufferUserClient::withTask(owningTask);
407: }
408: break;
409:
410: case kIOFBSharedConnectType:
411: if( sharedConnect) {
412: theConnect = sharedConnect;
413: theConnect->retain();
414: } else if( serverConnect)
415: newConnect = IOFramebufferSharedUserClient::withTask(owningTask);
416: else
417: err = kIOReturnNotOpen;
418: break;
419:
420: case kIOFBEngineControllerConnectType:
421: case kIOFBEngineConnectType:
422: newConnect = IOGraphicsEngineClient::withTask(owningTask);
423: break;
424:
425: default:
426: err = kIOReturnBadArgument;
427: }
428:
429: if( newConnect) {
430: if( (false == newConnect->attach( this ))
431: || (false == newConnect->start( this ))) {
432: newConnect->detach( this );
433: newConnect->release();
434: } else
435: theConnect = newConnect;
436: }
437:
438: *handler = theConnect;
439: return( err );
440: }
441:
442: IOReturn IOFramebuffer::extGetDisplayModeCount( IOItemCount * count )
443: {
444: *count = getDisplayModeCount();
445: return( kIOReturnSuccess);
446: }
447:
448: IOReturn IOFramebuffer::extGetDisplayModes( IODisplayModeID * allModes, IOByteCount * size )
449: {
450: IOReturn err;
451: IOByteCount outSize;
452:
453: outSize = getDisplayModeCount() * sizeof( IODisplayModeID);
454:
455: if( *size < outSize)
456: return( kIOReturnBadArgument);
457:
458: *size = outSize;
459: err = getDisplayModes( allModes );
460:
461: return( err);
462: }
463:
464: IOReturn IOFramebuffer::extGetVRAMMapOffset( IOPixelAperture /* aperture */,
465: IOByteCount * offset )
466: {
467: *offset = vramMapOffset;
468:
469: return( kIOReturnSuccess );
470: }
471:
472: IOReturn IOFramebuffer::extSetBounds( Bounds * bounds )
473: {
474: StdFBShmem_t *shmem;
475:
476: shmem = GetShmem(this);
477: if( shmem)
478: shmem->screenBounds = *bounds;
479:
480: return( kIOReturnSuccess );
481: }
482:
483: IOReturn IOFramebuffer::extSetColorConvertTable( UInt32 select,
484: UInt8 * data, IOByteCount length )
485: {
486: static const IOByteCount checkLength[] = {
487: 16 * sizeof( UInt8),
488: 32 * sizeof( UInt8),
489: 256 * sizeof( UInt32),
490: 5 * 256 * sizeof( UInt8) };
491:
492: UInt8 * table;
493:
494: if( select > 3)
495: return( kIOReturnBadArgument );
496:
497: if( length != checkLength[select])
498: return( kIOReturnBadArgument );
499:
500: table = colorConvert.tables[select];
501: if( 0 == table) {
502: table = (UInt8 *) IOMalloc( length );
503: colorConvert.tables[select] = table;
504: }
505:
506: if( table) {
507: bcopy( data, table, length );
508: if( select == 3)
509: white = data[data[255] + data[511] + data[767] + 1024];
510: return( kIOReturnSuccess );
511: } else
512: return( kIOReturnNoMemory );
513: }
514:
515: IOReturn IOFramebuffer::extSetCLUTWithEntries( UInt32 index, IOOptionBits options,
516: IOColorEntry * colors, IOByteCount inputCount )
517: {
518: IOReturn kr;
519:
520: kr = setCLUTWithEntries( colors, index,
521: inputCount / sizeof( IOColorEntry),
522: options );
523:
524: return( kr );
525: }
526:
527: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
528:
529: //
530: // BEGIN: Implementation of the evScreen protocol
531: //
532:
533: void IOFramebuffer::hideCursor( void )
534: {
535: StdFBShmem_t *shmem = GetShmem(this);
536:
537: SETSEMA(shmem);
538: SysHideCursor(this);
539: CLEARSEMA(shmem);
540: }
541:
542: #if 0
543: void IOFramebuffer::free()
544: {
545: if( vblSemaphore)
546: semaphore_destroy(kernel_task, vblSemaphore);
547: super::free();
548: }
549: #endif
550:
551: void IOFramebuffer::deferredMoveCursor( IOFramebuffer * inst, void * ref )
552: {
553: StdFBShmem_t * shmem = GetShmem(inst);
554: IOReturn err = kIOReturnSuccess;
555:
556: if( shmem)
557: clock_get_uptime( &shmem->vblTime );
558: if( inst->vblSemaphore)
559: semaphore_signal_all(inst->vblSemaphore);
560:
561: if( !inst->needCursorService)
562: return;
563:
564: SETSEMA(shmem);
565: shmem->frame = inst->nextCursorFrame;
566: shmem->cursorLoc = inst->nextCursorLoc;
567:
568: if( shmem->hardwareCursorActive ) {
569:
570: if (shmem->cursorObscured) {
571: shmem->cursorObscured = 0;
572: if (shmem->cursorShow)
573: --shmem->cursorShow;
574: }
575: if (!shmem->cursorShow) {
576: Point * hs;
577: hs = &shmem->hotSpot[shmem->frame];
578: err = inst->setCursorState(
579: shmem->cursorLoc.x - hs->x - shmem->screenBounds.minx,
580: shmem->cursorLoc.y - hs->y - shmem->screenBounds.miny, true );
581: }
582:
583: } else {
584:
585: if (!shmem->cursorShow++)
586: RemoveCursor(inst);
587: if (shmem->cursorObscured) {
588: shmem->cursorObscured = 0;
589: if (shmem->cursorShow)
590: --shmem->cursorShow;
591: }
592: if (shmem->shieldFlag) CheckShield(inst);
593: if (shmem->cursorShow)
594: if (!--shmem->cursorShow)
595: DisplayCursor(inst);
596:
597: inst->flushCursor();
598: }
599: inst->needCursorService = (kIOReturnBusy == err);
600:
601: CLEARSEMA(shmem);
602: }
603:
604: void IOFramebuffer::moveCursor( Point * cursorLoc, int frame )
605: {
606: nextCursorLoc = *cursorLoc;
607: nextCursorFrame = frame;
608: needCursorService = true;
609: if( !haveVBLService)
610: deferredMoveCursor( this, 0 );
611: }
612:
613: void IOFramebuffer::showCursor( Point * cursorLoc, int frame )
614: {
615: StdFBShmem_t *shmem;
616:
617: shmem = GetShmem(this);
618: SETSEMA(shmem);
619: shmem->frame = frame;
620: shmem->cursorLoc = *cursorLoc;
621: if (shmem->shieldFlag) CheckShield(this);
622: SysShowCursor(this);
623: CLEARSEMA(shmem);
624: }
625:
626: void IOFramebuffer::setBrightness( int /* level */ )
627: {
628: }
629:
630: void IOFramebuffer::getBoundingRect( Bounds ** bounds )
631: {
632: StdFBShmem_t *shmem;
633:
634: shmem = GetShmem(this);
635: if( NULL == shmem)
636: *bounds = NULL;
637: else
638: *bounds = &shmem->screenBounds;
639: }
640:
641: //
642: // END: Implementation of the evScreen protocol
643: //
644:
645: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
646:
647: IOReturn IOFramebuffer::getNotificationSemaphore(
648: IOSelect interruptType, semaphore_t * semaphore )
649: {
650: kern_return_t kr;
651: semaphore_t sema;
652:
653: if( interruptType != kIOFBVBLInterruptType)
654: return( kIOReturnUnsupported );
655:
656: if( !haveVBLService)
657: return( kIOReturnNoResources );
658:
659: if( MACH_PORT_NULL == vblSemaphore) {
660: kr = semaphore_create(kernel_task, &sema, SYNC_POLICY_FIFO, 0);
661: if( kr == KERN_SUCCESS)
662: vblSemaphore = sema;
663: } else
664: kr = KERN_SUCCESS;
665:
666: if( kr == KERN_SUCCESS)
667: *semaphore = vblSemaphore;
668:
669: return( kr );
670: }
671:
672: IOReturn IOFramebuffer::extSetCursorVisible( bool visible )
673: {
674: IOReturn err;
675: Point * hs;
676: StdFBShmem_t * shmem = GetShmem(this);
677:
678: if( shmem->hardwareCursorActive ) {
679: hs = &shmem->hotSpot[shmem->frame];
680: err = setCursorState(
681: shmem->cursorLoc.x - hs->x - shmem->screenBounds.minx,
682: shmem->cursorLoc.y - hs->y - shmem->screenBounds.miny,
683: visible );
684: } else
685: err = kIOReturnBadArgument;
686:
687: return( err );
688: }
689:
690: IOReturn IOFramebuffer::extSetCursorPosition( SInt32 x, SInt32 y )
691: {
692: return( kIOReturnUnsupported );
693: }
694:
695: IOReturn IOFramebuffer::extSetNewCursor( void * cursor, IOIndex frame,
696: IOOptionBits options )
697: {
698: StdFBShmem_t * shmem = GetShmem(this);
699: IOReturn err;
700:
701: if( cursor || options || (frame >= kIOFBNumCursorFrames))
702: err = kIOReturnBadArgument;
703: else {
704:
705: if( (shmem->cursorSize[frame].width > maxCursorSize.width)
706: || (shmem->cursorSize[frame].height > maxCursorSize.height))
707: err = kIOReturnBadArgument;
708:
709: else if( haveHWCursor)
710: err = setCursorImage( (void *) frame );
711: else
712: err = kIOReturnUnsupported;
713: }
714:
715: shmem->hardwareCursorActive = (kIOReturnSuccess == err);
716:
717: return( err );
718: }
719:
720: bool IOFramebuffer::convertCursorImage( void * cursorImage,
721: IOHardwareCursorDescriptor * hwDesc,
722: IOHardwareCursorInfo * hwCursorInfo )
723: {
724: StdFBShmem_t * shmem = GetShmem(this);
725: UInt8 * dataOut = hwCursorInfo->hardwareCursorData;
726: IOColorEntry * clut = hwCursorInfo->colorMap;
727: UInt32 maxColors = hwDesc->numColors;
728: int frame = (int) cursorImage;
729:
730: volatile unsigned short * cursPtr16;
731: volatile unsigned int * cursPtr32;
732: SInt32 x, y;
733: UInt32 index, numColors = 0;
734: UInt16 alpha, red, green, blue;
735: UInt16 s16;
736: UInt32 s32;
737: UInt8 data = 0;
738: UInt8 pixel = 0;
739: bool ok = true;
740:
741: assert( frame < kIOFBNumCursorFrames );
742:
743: if( bytesPerPixel == 4) {
744: cursPtr32 = (volatile unsigned int *) cursorImages[ frame ];
745: cursPtr16 = 0;
746: } else if( bytesPerPixel == 2) {
747: cursPtr32 = 0;
748: cursPtr16 = (volatile unsigned short *) cursorImages[ frame ];
749: } else
750: return( false );
751:
752: x = shmem->cursorSize[frame].width;
753: y = shmem->cursorSize[frame].height;
754:
755: if( (x > (SInt32) hwDesc->width) || (y > (SInt32) hwDesc->height))
756: return( false );
757: #if 0
758: hwCursorInfo->cursorWidth = x;
759: hwCursorInfo->cursorHeight = y;
760: while( (--y != -1) ) {
761: x = shmem->cursorSize[frame].width;
762: while( (--x != -1) ) {
763:
764: if( cursPtr32) {
765: s32 = *(cursPtr32++);
766: alpha = (s32 >> 28) & 0xf;
767: if( alpha && (alpha != 0xf))
768: *(cursPtr32 - 1) = 0x00ffffff;
769:
770: } else {
771: s16 = *(cursPtr16++);
772: alpha = s16 & 0x000F;
773: if( alpha && (alpha != 0xf))
774: *(cursPtr16 - 1) = 0xfff0;
775: }
776: }
777: }
778: #endif
779:
780: hwCursorInfo->cursorWidth = x;
781: hwCursorInfo->cursorHeight = y;
782:
783: while( ok && (--y != -1) ) {
784: x = shmem->cursorSize[frame].width;
785: while( ok && (--x != -1) ) {
786:
787: if( cursPtr32) {
788: s32 = *(cursPtr32++);
789: alpha = (s32 >> 28) & 0xf;
790: red = (s32 >> 16) & 0xff;
791: red |= (red << 8);
792: green = (s32 >> 8) & 0xff;
793: green |= (green << 8);
794: blue = (s32) & 0xff;
795: blue |= (blue << 8);
796:
797: } else {
798: #define RMASK16 0xF000
799: #define GMASK16 0x0F00
800: #define BMASK16 0x00F0
801: #define AMASK16 0x000F
802: s16 = *(cursPtr16++);
803: alpha = s16 & AMASK16;
804: red = s16 & RMASK16;
805: red |= (red >> 4) | (red >> 8) | (red >> 12);
806: green = s16 & GMASK16;
807: green |= (green << 4) | (green >> 4) | (green >> 8);
808: blue = s16 & BMASK16;
809: blue |= (blue << 8) | (blue << 4) | (blue >> 4);
810: }
811:
812: if( alpha == 0 ) {
813:
814: if( 0 == (red | green | blue)) {
815: /* Transparent black area. Leave dst as is. */
816: if( kTransparentEncodedPixel
817: & hwDesc->supportedSpecialEncodings)
818: pixel = hwDesc->specialEncodings[kTransparentEncoding];
819: else
820: ok = false;
821: } else if (0xffff == (red & green & blue)) {
822: /* Transparent white area. Invert dst. */
823: if( kInvertingEncodedPixel
824: & hwDesc->supportedSpecialEncodings)
825: pixel = hwDesc->specialEncodings[kInvertingEncoding];
826: else
827: ok = false;
828: } else
829: ok = false;
830:
831: } else if( alpha == 0xf ) {
832:
833: /* Opaque cursor pixel. Mark it. */
834: for( index = 0; index < numColors; index++ ) {
835: if( (red == clut[ index ].red)
836: && (green == clut[ index ].green)
837: && (blue == clut[ index ].blue) ) {
838:
839: pixel = clut[ index ].index;
840: break;
841: }
842: }
843: if( index == numColors) {
844: ok = (numColors < maxColors);
845: if( ok) {
846: pixel = hwDesc->colorEncodings[ numColors++ ];
847: clut[ index ].red = red;
848: clut[ index ].green = green;
849: clut[ index ].blue = blue;
850: clut[ index ].index = pixel;
851: }
852: }
853:
854: } else {
855: /* Alpha is not 0 or 1.0. Sover the cursor. */
856: ok = false;
857: break;
858: }
859:
860: data <<= hwDesc->bitDepth;
861: data |= pixel;
862:
863: if( 0 == (x & ((8 / hwDesc->bitDepth) - 1)))
864: *dataOut++ = data;
865: } /* x */
866: } /* y */
867:
868: // if( !ok) kprintf("Couldnt do a hw curs\n");
869:
870: return( ok );
871: }
872:
873: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
874:
875: void IOFramebuffer::initialize()
876: {
877: #if 0
878: static IOWorkLoop * gIOFramebufferWorkloop;
879: static IOLock * gIOFramebufferLock;
880:
881: gIOFramebufferLock = IOLockAlloc();
882:
883: gIOFramebufferWorkloop = IOWorkLoop::workLoop();
884:
885: assert( gIOFramebufferLock && gIOFramebufferWorkloop );
886: #endif
887: }
888:
889:
890: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
891:
892: static bool serializeInfoCB( void * target, void * ref, OSSerialize * s )
893: {
894: return( ((IOFramebuffer *)target)->serializeInfo(s) );
895: }
896:
897: bool IOFramebuffer::start( IOService * provider )
898: {
899: OSSerializer * infoSerializer;
900:
901: if( ! super::start( provider))
902: return( false );
903:
904: userAccessRanges = OSArray::withCapacity( 1 );
905: engineAccessRanges = OSArray::withCapacity( 1 );
906:
907: infoSerializer = OSSerializer::forTarget( (void *) this, &serializeInfoCB );
908: if( !infoSerializer)
909: return( false );
910:
911: setProperty( kIOFramebufferInfoKey, infoSerializer );
912: infoSerializer->release();
913:
914: #if 0
915:
916: IOInterruptEventSource * eventSrc;
917:
918: eventSrc = IOInterruptEventSource::interruptEventSource(
919: this, autopollArrived);
920: if (!eventSrc ||
921: kIOReturnSuccess != workLoop->addEventSource(eventSrc) ) {
922: kprintf("Start is bailing\n");
923: return false;
924: }
925: #endif
926:
927: closed = true;
928: registerService();
929:
930: // initialize superclass power management variables
931: PMinit();
932: // attach into the power management hierarchy
933: provider->joinPMtree(this);
934: // clamp power on (the user client will change that when appropriate)
935: changeStateToPriv(pm_vars->theNumberOfPowerStates - 1);
936:
937: return( true );
938: }
939:
940: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
941:
942: // Apple standard 8-bit CLUT
943:
944: UInt8 appleClut8[ 256 * 3 ] = {
945: // 00
946: 0xFF,0xFF,0xFF, 0xFF,0xFF,0xCC, 0xFF,0xFF,0x99, 0xFF,0xFF,0x66,
947: 0xFF,0xFF,0x33, 0xFF,0xFF,0x00, 0xFF,0xCC,0xFF, 0xFF,0xCC,0xCC,
948: 0xFF,0xCC,0x99, 0xFF,0xCC,0x66, 0xFF,0xCC,0x33, 0xFF,0xCC,0x00,
949: 0xFF,0x99,0xFF, 0xFF,0x99,0xCC, 0xFF,0x99,0x99, 0xFF,0x99,0x66,
950: // 10
951: 0xFF,0x99,0x33, 0xFF,0x99,0x00, 0xFF,0x66,0xFF, 0xFF,0x66,0xCC,
952: 0xFF,0x66,0x99, 0xFF,0x66,0x66, 0xFF,0x66,0x33, 0xFF,0x66,0x00,
953: 0xFF,0x33,0xFF, 0xFF,0x33,0xCC, 0xFF,0x33,0x99, 0xFF,0x33,0x66,
954: 0xFF,0x33,0x33, 0xFF,0x33,0x00, 0xFF,0x00,0xFF, 0xFF,0x00,0xCC,
955: // 20
956: 0xFF,0x00,0x99, 0xFF,0x00,0x66, 0xFF,0x00,0x33, 0xFF,0x00,0x00,
957: 0xCC,0xFF,0xFF, 0xCC,0xFF,0xCC, 0xCC,0xFF,0x99, 0xCC,0xFF,0x66,
958: 0xCC,0xFF,0x33, 0xCC,0xFF,0x00, 0xCC,0xCC,0xFF, 0xCC,0xCC,0xCC,
959: 0xCC,0xCC,0x99, 0xCC,0xCC,0x66, 0xCC,0xCC,0x33, 0xCC,0xCC,0x00,
960: // 30
961: 0xCC,0x99,0xFF, 0xCC,0x99,0xCC, 0xCC,0x99,0x99, 0xCC,0x99,0x66,
962: 0xCC,0x99,0x33, 0xCC,0x99,0x00, 0xCC,0x66,0xFF, 0xCC,0x66,0xCC,
963: 0xCC,0x66,0x99, 0xCC,0x66,0x66, 0xCC,0x66,0x33, 0xCC,0x66,0x00,
964: 0xCC,0x33,0xFF, 0xCC,0x33,0xCC, 0xCC,0x33,0x99, 0xCC,0x33,0x66,
965: // 40
966: 0xCC,0x33,0x33, 0xCC,0x33,0x00, 0xCC,0x00,0xFF, 0xCC,0x00,0xCC,
967: 0xCC,0x00,0x99, 0xCC,0x00,0x66, 0xCC,0x00,0x33, 0xCC,0x00,0x00,
968: 0x99,0xFF,0xFF, 0x99,0xFF,0xCC, 0x99,0xFF,0x99, 0x99,0xFF,0x66,
969: 0x99,0xFF,0x33, 0x99,0xFF,0x00, 0x99,0xCC,0xFF, 0x99,0xCC,0xCC,
970: // 50
971: 0x99,0xCC,0x99, 0x99,0xCC,0x66, 0x99,0xCC,0x33, 0x99,0xCC,0x00,
972: 0x99,0x99,0xFF, 0x99,0x99,0xCC, 0x99,0x99,0x99, 0x99,0x99,0x66,
973: 0x99,0x99,0x33, 0x99,0x99,0x00, 0x99,0x66,0xFF, 0x99,0x66,0xCC,
974: 0x99,0x66,0x99, 0x99,0x66,0x66, 0x99,0x66,0x33, 0x99,0x66,0x00,
975: // 60
976: 0x99,0x33,0xFF, 0x99,0x33,0xCC, 0x99,0x33,0x99, 0x99,0x33,0x66,
977: 0x99,0x33,0x33, 0x99,0x33,0x00, 0x99,0x00,0xFF, 0x99,0x00,0xCC,
978: 0x99,0x00,0x99, 0x99,0x00,0x66, 0x99,0x00,0x33, 0x99,0x00,0x00,
979: 0x66,0xFF,0xFF, 0x66,0xFF,0xCC, 0x66,0xFF,0x99, 0x66,0xFF,0x66,
980: // 70
981: 0x66,0xFF,0x33, 0x66,0xFF,0x00, 0x66,0xCC,0xFF, 0x66,0xCC,0xCC,
982: 0x66,0xCC,0x99, 0x66,0xCC,0x66, 0x66,0xCC,0x33, 0x66,0xCC,0x00,
983: 0x66,0x99,0xFF, 0x66,0x99,0xCC, 0x66,0x99,0x99, 0x66,0x99,0x66,
984: 0x66,0x99,0x33, 0x66,0x99,0x00, 0x66,0x66,0xFF, 0x66,0x66,0xCC,
985: // 80
986: 0x66,0x66,0x99, 0x66,0x66,0x66, 0x66,0x66,0x33, 0x66,0x66,0x00,
987: 0x66,0x33,0xFF, 0x66,0x33,0xCC, 0x66,0x33,0x99, 0x66,0x33,0x66,
988: 0x66,0x33,0x33, 0x66,0x33,0x00, 0x66,0x00,0xFF, 0x66,0x00,0xCC,
989: 0x66,0x00,0x99, 0x66,0x00,0x66, 0x66,0x00,0x33, 0x66,0x00,0x00,
990: // 90
991: 0x33,0xFF,0xFF, 0x33,0xFF,0xCC, 0x33,0xFF,0x99, 0x33,0xFF,0x66,
992: 0x33,0xFF,0x33, 0x33,0xFF,0x00, 0x33,0xCC,0xFF, 0x33,0xCC,0xCC,
993: 0x33,0xCC,0x99, 0x33,0xCC,0x66, 0x33,0xCC,0x33, 0x33,0xCC,0x00,
994: 0x33,0x99,0xFF, 0x33,0x99,0xCC, 0x33,0x99,0x99, 0x33,0x99,0x66,
995: // a0
996: 0x33,0x99,0x33, 0x33,0x99,0x00, 0x33,0x66,0xFF, 0x33,0x66,0xCC,
997: 0x33,0x66,0x99, 0x33,0x66,0x66, 0x33,0x66,0x33, 0x33,0x66,0x00,
998: 0x33,0x33,0xFF, 0x33,0x33,0xCC, 0x33,0x33,0x99, 0x33,0x33,0x66,
999: 0x33,0x33,0x33, 0x33,0x33,0x00, 0x33,0x00,0xFF, 0x33,0x00,0xCC,
1000: // b0
1001: 0x33,0x00,0x99, 0x33,0x00,0x66, 0x33,0x00,0x33, 0x33,0x00,0x00,
1002: 0x00,0xFF,0xFF, 0x00,0xFF,0xCC, 0x00,0xFF,0x99, 0x00,0xFF,0x66,
1003: 0x00,0xFF,0x33, 0x00,0xFF,0x00, 0x00,0xCC,0xFF, 0x00,0xCC,0xCC,
1004: 0x00,0xCC,0x99, 0x00,0xCC,0x66, 0x00,0xCC,0x33, 0x00,0xCC,0x00,
1005: // c0
1006: 0x00,0x99,0xFF, 0x00,0x99,0xCC, 0x00,0x99,0x99, 0x00,0x99,0x66,
1007: 0x00,0x99,0x33, 0x00,0x99,0x00, 0x00,0x66,0xFF, 0x00,0x66,0xCC,
1008: 0x00,0x66,0x99, 0x00,0x66,0x66, 0x00,0x66,0x33, 0x00,0x66,0x00,
1009: 0x00,0x33,0xFF, 0x00,0x33,0xCC, 0x00,0x33,0x99, 0x00,0x33,0x66,
1010: // d0
1011: 0x00,0x33,0x33, 0x00,0x33,0x00, 0x00,0x00,0xFF, 0x00,0x00,0xCC,
1012: 0x00,0x00,0x99, 0x00,0x00,0x66, 0x00,0x00,0x33, 0xEE,0x00,0x00,
1013: 0xDD,0x00,0x00, 0xBB,0x00,0x00, 0xAA,0x00,0x00, 0x88,0x00,0x00,
1014: 0x77,0x00,0x00, 0x55,0x00,0x00, 0x44,0x00,0x00, 0x22,0x00,0x00,
1015: // e0
1016: 0x11,0x00,0x00, 0x00,0xEE,0x00, 0x00,0xDD,0x00, 0x00,0xBB,0x00,
1017: 0x00,0xAA,0x00, 0x00,0x88,0x00, 0x00,0x77,0x00, 0x00,0x55,0x00,
1018: 0x00,0x44,0x00, 0x00,0x22,0x00, 0x00,0x11,0x00, 0x00,0x00,0xEE,
1019: 0x00,0x00,0xDD, 0x00,0x00,0xBB, 0x00,0x00,0xAA, 0x00,0x00,0x88,
1020: // f0
1021: 0x00,0x00,0x77, 0x00,0x00,0x55, 0x00,0x00,0x44, 0x00,0x00,0x22,
1022: 0x00,0x00,0x11, 0xEE,0xEE,0xEE, 0xDD,0xDD,0xDD, 0xBB,0xBB,0xBB,
1023: 0xAA,0xAA,0xAA, 0x88,0x88,0x88, 0x77,0x77,0x77, 0x55,0x55,0x55,
1024: 0x44,0x44,0x44, 0x22,0x22,0x22, 0x11,0x11,0x11, 0x00,0x00,0x00
1025: };
1026:
1027:
1028: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1029: // disallowPowerDown
1030: //
1031: // Called by the User Client to disallow powering down the frame buffer.
1032: // This condition exists between the instantiation of the User Client and
1033: // the Window Server registering with it for power state notifications.
1034: //
1035: // As policy-maker, we request the highest power state, and this clamps
1036: // the power on.
1037: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1038:
1039: void IOFramebuffer::disallowPowerDown( void )
1040: {
1041: changeStateToPriv(pm_vars->theNumberOfPowerStates - 1);
1042: }
1043:
1044:
1045: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1046: // allowPowerDown
1047: //
1048: // Called by the User Client to allow powering down the frame buffer.
1049: // This condition exists after the Window Server registers with it for power
1050: // state notifications and when the Window Server closes, regardless of
1051: // whether or not it ever registered.
1052: //
1053: // As policy-maker, we request the lowest power state. The power state
1054: // is therefore controlled by the desires of our children (the displays).
1055: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1056:
1057: void IOFramebuffer::allowPowerDown( void )
1058: {
1059: changeStateToPriv(0);
1060: }
1061:
1062:
1063: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1064: // powerStateWillChangeTo
1065: //
1066: // We are informed, as an Interested Driver, that our device is about to
1067: // change power state. If the new state is unusable, we warn the console
1068: // to stop accessing the frame buffer for a while, since it will be powered off.
1069: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1070:
1071: IOReturn IOFramebuffer::powerStateWillChangeTo( IOPMPowerFlags newState,
1072: unsigned long, IOService* whatDevice )
1073: {
1074: if ( ! (newState & IOPMDeviceUsable) ) {
1075: if( isConsoleDevice()) {
1076: getPlatform()->setConsoleInfo( 0, kPEDisableScreen);
1077: }
1078: }
1079: return 0;
1080: }
1081:
1082:
1083: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1084: // powerStateDidChangeTo
1085: //
1086: // We are informed, as an Interested Driver, that our device has changed
1087: // power state. If the new state is usable, we tell the console that it may
1088: // access the frame buffer now, since it has powered on.
1089: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1090:
1091: IOReturn IOFramebuffer::powerStateDidChangeTo( IOPMPowerFlags newState,
1092: unsigned long, IOService* whatDevice )
1093: {
1094: if ( newState & IOPMDeviceUsable ) {
1095: if( isConsoleDevice()) {
1096: getPlatform()->setConsoleInfo( 0, kPEEnableScreen);
1097: }
1098: }
1099: return 0;
1100: }
1101:
1102: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1103:
1104: IODeviceMemory * IOFramebuffer::getVRAMRange( void )
1105: {
1106: return( getApertureRange( kIOFBSystemAperture ));
1107: }
1108:
1109: void IOFramebuffer::close( void ) // called by the user client when
1110: { // the window server exits
1111:
1112: }
1113:
1114:
1115:
1116: IOReturn IOFramebuffer::open( void )
1117: {
1118: IOReturn err = kIOReturnSuccess;
1119: UInt32 value;
1120:
1121: do {
1122: if( opened)
1123: continue;
1124:
1125: // tell the console if it's on this display, it's going away
1126: if( isConsoleDevice())
1127: getPlatform()->setConsoleInfo( 0, kPEDisableScreen);
1128:
1129: deliverFramebufferNotification( kIOFBNotifyDisplayModeWillChange );
1130:
1131: err = enableController();
1132: if( kIOReturnSuccess != err)
1133: continue;
1134:
1135: err = registerForInterruptType( kIOFBVBLInterruptType,
1136: (IOFBInterruptProc) &deferredMoveCursor,
1137: this, priv, &vblInterrupt );
1138: haveVBLService = (err == kIOReturnSuccess );
1139:
1140: err = getAttribute( kIOHardwareCursorAttribute, &value );
1141: haveHWCursor = ((err == kIOReturnSuccess ) && value);
1142:
1143: err = kIOReturnSuccess;
1144: opened = true;
1145:
1146: } while( false );
1147:
1148: return( err );
1149: }
1150:
1151: IOReturn IOFramebuffer::setUserRanges( void )
1152: {
1153: #if 1 /* print ranges */
1154:
1155: UInt32 i, numRanges;
1156: IODeviceMemory * mem;
1157:
1158: numRanges = userAccessRanges->getCount();
1159: IOLog("%s: user ranges num:%ld", getName(), numRanges);
1160: for( i = 0; i < numRanges; i++) {
1161: mem = (IODeviceMemory *) userAccessRanges->getObject( i );
1162: if( 0 == mem)
1163: continue;
1164: IOLog(" start:%lx size:%lx",
1165: mem->getPhysicalAddress(), mem->getLength() );
1166: }
1167: IOLog("\n");
1168:
1169: #endif
1170: return( kIOReturnSuccess);
1171: }
1172:
1173: IOReturn IOFramebuffer::setupForCurrentConfig( void )
1174: {
1175: return( doSetup( true ));
1176: }
1177:
1178: IOReturn IOFramebuffer::doSetup( bool full )
1179: {
1180: IOReturn err;
1181: IODisplayModeID mode;
1182: IOIndex depth;
1183: IOPixelInformation info;
1184: IODisplayModeInformation dmInfo;
1185: IODeviceMemory * mem;
1186: IODeviceMemory * fbRange;
1187: IOPhysicalAddress base;
1188: PE_Video newConsole;
1189:
1190: err = getCurrentDisplayMode( &mode, &depth );
1191: if( err)
1192: IOLog("%s: getCurrentDisplayMode %d\n", getName(), err);
1193:
1194: err = getPixelInformation( mode, depth, kIOFBSystemAperture, &info );
1195: if( err)
1196: IOLog("%s: getPixelInformation %d\n", getName(), err);
1197:
1198: if( full && (clutValid == false) && (info.pixelType == kIOCLUTPixels)) {
1199:
1200: IOColorEntry * tempTable;
1201: int i;
1202:
1203: tempTable = (IOColorEntry *) IOMalloc( 256 * sizeof( *tempTable));
1204: if( tempTable) {
1205:
1206: for( i = 0; i < 256; i++) {
1207: if( currentMono) {
1208: UInt32 lum;
1209:
1210: lum = 0x0101 * i;
1211: tempTable[ i ].red = lum;
1212: tempTable[ i ].green = lum;
1213: tempTable[ i ].blue = lum;
1214: } else {
1215: tempTable[ i ].red = (appleClut8[ i * 3 + 0 ] << 8)
1216: | appleClut8[ i * 3 + 0 ];
1217: tempTable[ i ].green = (appleClut8[ i * 3 + 1 ] << 8)
1218: | appleClut8[ i * 3 + 1 ];
1219: tempTable[ i ].blue = (appleClut8[ i * 3 + 2 ] << 8)
1220: | appleClut8[ i * 3 + 2 ];
1221: }
1222: }
1223: setCLUTWithEntries( tempTable, 0, 256, 1 * kSetCLUTImmediately );
1224: IOFree( tempTable, 256 * sizeof( *tempTable));
1225: }
1226: clutValid = true;
1227: }
1228:
1229: fbRange = getApertureRange( kIOFBSystemAperture );
1230:
1231: if( full && fbRange) {
1232:
1233: userAccessRanges->removeObject( kIOFBSystemAperture );
1234: userAccessRanges->setObject( kIOFBSystemAperture, fbRange );
1235: err = setUserRanges();
1236:
1237: base = fbRange->getPhysicalAddress();
1238: if( (mem = getVRAMRange())) {
1239: vramMapOffset = base - mem->getPhysicalAddress();
1240: mem->release();
1241: }
1242:
1243: if( vramMap)
1244: vramMap->release();
1245: vramMap = fbRange->map();
1246: assert( vramMap );
1247: if( vramMap)
1248: base = vramMap->getVirtualAddress();
1249:
1250: // console now available
1251: if( info.activeWidth >= 128) {
1252: newConsole.v_baseAddr = base;
1253: newConsole.v_rowBytes = info.bytesPerRow;
1254: newConsole.v_width = info.activeWidth;
1255: newConsole.v_height = info.activeHeight;
1256: newConsole.v_depth = info.bitsPerPixel;
1257: // strcpy( consoleInfo->v_pixelFormat, "PPPPPPPP");
1258: getPlatform()->setConsoleInfo( &newConsole, kPEEnableScreen );
1259: }
1260:
1261: deliverFramebufferNotification( kIOFBNotifyDisplayModeDidChange, 0 );
1262:
1263: (void) getInformationForDisplayMode( mode, &dmInfo );
1264: IOLog( "%s: using (%ldx%ld@%ldHz,%ld bpp)\n", getName(),
1265: info.activeWidth, info.activeHeight,
1266: (dmInfo.refreshRate + 0x8000) >> 16, info.bitsPerPixel );
1267: }
1268:
1269: if( fbRange)
1270: fbRange->release();
1271: if( vramMap)
1272: setupCursor( &info );
1273:
1274: return( kIOReturnSuccess );
1275: }
1276:
1277: IOReturn IOFramebuffer::extSetDisplayMode( IODisplayModeID displayMode,
1278: IOIndex depth )
1279: {
1280: IOReturn err;
1281:
1282: stopCursor();
1283:
1284: if( isConsoleDevice())
1285: getPlatform()->setConsoleInfo( 0, kPEDisableScreen);
1286:
1287: deliverFramebufferNotification( kIOFBNotifyDisplayModeWillChange );
1288:
1289: err = setDisplayMode( displayMode, depth );
1290:
1291: clutValid = false;
1292:
1293: setupForCurrentConfig();
1294:
1295: return( err );
1296: }
1297:
1298: IOReturn IOFramebuffer::extGetInformationForDisplayMode(
1299: IODisplayModeID mode, IODisplayModeInformation * info )
1300: {
1301: UInt32 flags = 0;
1302: IOReturn err;
1303:
1304: err = getInformationForDisplayMode( mode, info );
1305: if( kIOReturnSuccess == err) {
1306: err = IODisplayWrangler::getFlagsForDisplayMode( this, mode, &flags);
1307: if( kIOReturnSuccess == err) {
1308: info->flags &= ~kDisplayModeSafetyFlags;
1309: info->flags |= flags;
1310: }
1311: }
1312:
1313: return( err );
1314: }
1315:
1316: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1317:
1318: bool IOFramebuffer::setNumber( OSDictionary * dict, const char * key,
1319: UInt32 value )
1320: {
1321: OSNumber * num;
1322: bool ok;
1323:
1324: num = OSNumber::withNumber( value, 32 );
1325: if( !num)
1326: return( false );
1327:
1328: ok = dict->setObject( key, num );
1329: num->release();
1330:
1331: return( ok );
1332: }
1333:
1334: bool IOFramebuffer::serializeInfo( OSSerialize * s )
1335: {
1336: IOReturn err;
1337: IODisplayModeInformation info;
1338: IOPixelInformation pixelInfo;
1339: IODisplayModeID * modeIDs;
1340: IOItemCount modeCount, modeNum, aperture;
1341: IOIndex depthNum;
1342: OSDictionary * infoDict;
1343: OSDictionary * modeDict;
1344: OSDictionary * pixelDict;
1345: char keyBuf[12];
1346: bool ok = true;
1347:
1348: modeCount = getDisplayModeCount();
1349: modeIDs = IONew( IODisplayModeID, modeCount );
1350: if( !modeIDs)
1351: return( false );
1352:
1353: err = getDisplayModes( modeIDs );
1354: if( err)
1355: return( false );
1356:
1357: infoDict = OSDictionary::withCapacity( 10 );
1358: if( !infoDict)
1359: return( false );
1360:
1361: for( modeNum = 0; modeNum < modeCount; modeNum++ ) {
1362:
1363: err = getInformationForDisplayMode( modeIDs[ modeNum ], &info );
1364: if( err)
1365: continue;
1366:
1367: modeDict = OSDictionary::withCapacity( 10 );
1368: if( !modeDict)
1369: break;
1370:
1371: ok = setNumber( modeDict, kIOFBWidthKey,
1372: info.nominalWidth )
1373: && setNumber( modeDict, kIOFBHeightKey,
1374: info.nominalHeight )
1375: && setNumber( modeDict, kIOFBRefreshRateKey,
1376: info.refreshRate )
1377: && setNumber( modeDict, kIOFBFlagsKey,
1378: info.flags );
1379: if( !ok)
1380: break;
1381:
1382: for( depthNum = 0; depthNum < info.maxDepthIndex; depthNum++ ) {
1383:
1384: for( aperture = 0; ; aperture++ ) {
1385:
1386: err = getPixelInformation( modeIDs[ modeNum ], depthNum,
1387: aperture, &pixelInfo );
1388: if( err)
1389: break;
1390:
1391: pixelDict = OSDictionary::withCapacity( 10 );
1392: if( !pixelDict)
1393: continue;
1394:
1395: ok = setNumber( pixelDict, kIOFBBytesPerRowKey,
1396: pixelInfo.bytesPerRow )
1397: && setNumber( pixelDict, kIOFBBytesPerPlaneKey,
1398: pixelInfo.bytesPerPlane )
1399: && setNumber( pixelDict, kIOFBBitsPerPixelKey,
1400: pixelInfo.bitsPerPixel )
1401: && setNumber( pixelDict, kIOFBComponentCountKey,
1402: pixelInfo.componentCount )
1403: && setNumber( pixelDict, kIOFBBitsPerComponentKey,
1404: pixelInfo.bitsPerComponent )
1405: && setNumber( pixelDict, kIOFBFlagsKey,
1406: pixelInfo.flags )
1407: && setNumber( pixelDict, kIOFBWidthKey,
1408: pixelInfo.activeWidth )
1409: && setNumber( pixelDict, kIOFBHeightKey,
1410: pixelInfo.activeHeight );
1411: if( !ok)
1412: break;
1413:
1414: sprintf( keyBuf, "%lx", depthNum + (aperture << 16) );
1415: modeDict->setObject( keyBuf, pixelDict );
1416: pixelDict->release();
1417: }
1418: }
1419:
1420: sprintf( keyBuf, "%lx", modeIDs[ modeNum ] );
1421: infoDict->setObject( keyBuf, modeDict );
1422: modeDict->release();
1423: }
1424:
1425: IODelete( modeIDs, IODisplayModeID, modeCount );
1426:
1427: ok &= infoDict->serialize( s );
1428: infoDict->release();
1429:
1430: return( ok );
1431: }
1432:
1433: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1434:
1435: OSDefineMetaClassAndStructors(_IOFramebufferNotifier, IONotifier)
1436: #define LOCKNOTIFY()
1437: #define UNLOCKNOTIFY()
1438:
1439: void _IOFramebufferNotifier::remove()
1440: {
1441: LOCKNOTIFY();
1442:
1443: if( whence) {
1444: whence->removeObject( (OSObject *) this );
1445: whence = 0;
1446: }
1447:
1448: fEnable = false;
1449:
1450: UNLOCKNOTIFY();
1451:
1452: release();
1453: }
1454:
1455: bool _IOFramebufferNotifier::disable()
1456: {
1457: bool ret;
1458:
1459: LOCKNOTIFY();
1460: ret = fEnable;
1461: fEnable = false;
1462: UNLOCKNOTIFY();
1463:
1464: return( ret );
1465: }
1466:
1467: void _IOFramebufferNotifier::enable( bool was )
1468: {
1469: LOCKNOTIFY();
1470: fEnable = was;
1471: UNLOCKNOTIFY();
1472: }
1473:
1474: IONotifier * IOFramebuffer::addFramebufferNotification(
1475: IOFramebufferNotificationHandler handler,
1476: OSObject * self, void * ref)
1477: {
1478: _IOFramebufferNotifier * notify = 0;
1479:
1480: notify = new _IOFramebufferNotifier;
1481: if( notify && !notify->init()) {
1482: notify->release();
1483: notify = 0;
1484: }
1485:
1486: if( notify) {
1487: notify->handler = handler;
1488: notify->self = self;
1489: notify->ref = ref;
1490: notify->fEnable = true;
1491:
1492: if( 0 == fbNotifications)
1493: fbNotifications = OSSet::withCapacity(1);
1494:
1495: notify->whence = fbNotifications;
1496: if( fbNotifications)
1497: fbNotifications->setObject( notify );
1498: }
1499:
1500: return( notify );
1501: }
1502:
1503: IOReturn IOFramebuffer::deliverFramebufferNotification(
1504: IOIndex event, void * info = 0 )
1505: {
1506: OSIterator * iter;
1507: _IOFramebufferNotifier * notify;
1508: IOReturn ret = kIOReturnSuccess;
1509: IOReturn r;
1510:
1511: LOCKNOTIFY();
1512:
1513: iter = OSCollectionIterator::withCollection( fbNotifications );
1514:
1515: if( iter) {
1516: while( (notify = (_IOFramebufferNotifier *) iter->getNextObject())) {
1517:
1518: if( notify->fEnable) {
1519: r = (*notify->handler)( notify->self, notify->ref, this,
1520: event, info );
1521: if( kIOReturnSuccess != ret)
1522: ret = r;
1523: }
1524: }
1525: iter->release();
1526: }
1527:
1528: UNLOCKNOTIFY();
1529:
1530: return( ret );
1531: }
1532:
1533: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1534:
1535: // Some stubs
1536:
1537: IOReturn IOFramebuffer::enableController ( void )
1538: {
1539: return( kIOReturnSuccess );
1540: }
1541:
1542: bool IOFramebuffer::isConsoleDevice( void )
1543: {
1544: return( false );
1545: }
1546:
1547: // Set display mode and depth
1548: IOReturn IOFramebuffer::setDisplayMode( IODisplayModeID /* displayMode */,
1549: IOIndex /* depth */ )
1550: {
1551: return( kIOReturnUnsupported);
1552: }
1553:
1554: // For pages
1555: IOReturn IOFramebuffer::setApertureEnable(
1556: IOPixelAperture /* aperture */, IOOptionBits /* enable */ )
1557: {
1558: return( kIOReturnUnsupported);
1559: }
1560:
1561: // Display mode and depth for startup
1562: IOReturn IOFramebuffer::setStartupDisplayMode(
1563: IODisplayModeID /* displayMode */, IOIndex /* depth */ )
1564: {
1565: return( kIOReturnUnsupported);
1566: }
1567:
1568: IOReturn IOFramebuffer::getStartupDisplayMode(
1569: IODisplayModeID * /* displayMode */, IOIndex * /* depth */ )
1570: {
1571: return( kIOReturnUnsupported);
1572: }
1573:
1574: //// CLUTs
1575:
1576: IOReturn IOFramebuffer::setCLUTWithEntries(
1577: IOColorEntry * /* colors */, UInt32 /* index */,
1578: UInt32 /* numEntries */, IOOptionBits /* options */ )
1579: {
1580: return( kIOReturnUnsupported);
1581: }
1582:
1583: //// Gamma
1584:
1585: IOReturn IOFramebuffer::setGammaTable( UInt32 /* channelCount */,
1586: UInt32 /* dataCount */, UInt32 /* dataWidth */, void * /* data */ )
1587: {
1588: return( kIOReturnUnsupported);
1589: }
1590:
1591: //// Controller attributes
1592:
1593: IOReturn IOFramebuffer::setAttribute( IOSelect /* attribute */, UInt32 /* value */ )
1594: {
1595: return( kIOReturnUnsupported);
1596: }
1597:
1598: IOReturn IOFramebuffer::getAttribute( IOSelect /* attribute */,
1599: UInt32 * /* value */ )
1600: {
1601: return( kIOReturnUnsupported);
1602: }
1603:
1604: //// Display mode timing information
1605:
1606: IOReturn IOFramebuffer::getTimingInfoForDisplayMode(
1607: IODisplayModeID /* displayMode */,
1608: IOTimingInformation * /* info */ )
1609: {
1610: return( kIOReturnUnsupported);
1611: }
1612:
1613: //// Connections
1614:
1615: IOItemCount IOFramebuffer::getConnectionCount( void )
1616: {
1617: return( 1);
1618: }
1619:
1620: IOReturn IOFramebuffer::setAttributeForConnection( IOIndex /* connectIndex */,
1621: IOSelect /* attribute */, UInt32 /* value */ )
1622: {
1623: return( kIOReturnUnsupported);
1624: }
1625:
1626: IOReturn IOFramebuffer::getAttributeForConnection( IOIndex /* connectIndex */,
1627: IOSelect /* attribute */, UInt32 * /* value */ )
1628: {
1629: return( kIOReturnUnsupported);
1630: }
1631:
1632: //// HW Cursors
1633:
1634: IOReturn IOFramebuffer::setCursorImage( void * cursorImage )
1635: {
1636: return( kIOReturnUnsupported);
1637: }
1638:
1639: IOReturn IOFramebuffer::setCursorState( SInt32 x, SInt32 y, bool visible )
1640: {
1641: return( kIOReturnUnsupported);
1642: }
1643:
1644: void IOFramebuffer::flushCursor( void )
1645: {
1646: }
1647:
1648: //// Interrupts
1649:
1650: IOReturn IOFramebuffer::registerForInterruptType( IOSelect interruptType,
1651: IOFBInterruptProc proc, OSObject * target, void * ref,
1652: void ** interruptRef )
1653: {
1654: return( kIOReturnUnsupported);
1655: }
1656:
1657: IOReturn IOFramebuffer::unregisterInterrupt( void * interruptRef )
1658: {
1659: return( kIOReturnUnsupported);
1660: }
1661:
1662: IOReturn IOFramebuffer::setInterruptState( void * interruptRef, UInt32 state )
1663: {
1664: return( kIOReturnUnsupported);
1665: }
1666:
1667: // Apple sensing
1668:
1669: IOReturn IOFramebuffer::getAppleSense(
1670: IOIndex /* connectIndex */,
1671: UInt32 * /* senseType */,
1672: UInt32 * /* primary */,
1673: UInt32 * /* extended */,
1674: UInt32 * /* displayType */ )
1675: {
1676: return( kIOReturnUnsupported);
1677: }
1678:
1679: IOReturn IOFramebuffer::connectFlags( IOIndex /* connectIndex */,
1680: IODisplayModeID /* displayMode */, IOOptionBits * /* flags */ )
1681: {
1682: return( kIOReturnUnsupported);
1683: }
1684:
1685: //// IOLowLevelDDCSense
1686:
1687: void IOFramebuffer::setDDCClock( IOIndex /* connectIndex */, UInt32 /* value */ )
1688: {
1689: }
1690:
1691: void IOFramebuffer::setDDCData( IOIndex /* connectIndex */, UInt32 /* value */ )
1692: {
1693: }
1694:
1695: bool IOFramebuffer::readDDCClock( IOIndex /* connectIndex */ )
1696: {
1697: return( false);
1698: }
1699:
1700: bool IOFramebuffer::readDDCData( IOIndex /* connectIndex */ )
1701: {
1702: return( false);
1703: }
1704:
1705: IOReturn IOFramebuffer::enableDDCRaster( bool /* enable */ )
1706: {
1707: return( kIOReturnUnsupported);
1708: }
1709:
1710:
1711: //// IOHighLevelDDCSense
1712:
1713: bool IOFramebuffer::hasDDCConnect( IOIndex /* connectIndex */ )
1714: {
1715: return( kIOReturnUnsupported);
1716: }
1717:
1718: IOReturn IOFramebuffer::getDDCBlock( IOIndex /* connectIndex */, UInt32 /* blockNumber */,
1719: IOSelect /* blockType */, IOOptionBits /* options */,
1720: UInt8 * /* data */, IOByteCount * /* length */ )
1721: {
1722: return( kIOReturnUnsupported);
1723: }
1724:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.