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