]>
git.saurik.com Git - apple/bootx.git/blob - bootx.tproj/sl.subproj/display.c
997de211b9b623ba177f90749bf90e4a13f356c8
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * display.c - Functions to manage and find display.
28 * Copyright (c) 1998-2002 Apple Computer, Inc.
36 #include "appleboot.h"
37 #include "failedboot.h"
51 typedef struct DisplayInfo DisplayInfo
, *DisplayInfoPtr
;
54 static long FindDisplays(void);
55 static long OpenDisplays(void);
56 static long OpenDisplay(long displayNum
);
57 static long InitDisplay(long displayNum
);
58 static long LookUpCLUTIndex(long index
, long depth
);
60 static long gNumDisplays
;
61 static long gMainDisplayNum
;
62 static DisplayInfo gDisplays
[16];
64 static unsigned char *gAppleBoot
;
65 static unsigned char *gNetBoot
;
66 static unsigned char *gFailedBoot
;
70 long InitDisplays(void)
79 long DrawSplashScreen(long stage
)
81 DisplayInfoPtr display
;
82 short *appleBoot16
, *netBoot16
;
83 long *appleBoot32
, *netBoot32
;
84 long cnt
, x
, y
, pixelSize
;
86 if (gMainDisplayNum
== -1) return 0;
88 display
= &gDisplays
[gMainDisplayNum
];
92 // Make sure the boot display is marked.
93 SetProp(display
->screenPH
, "AAPL,boot-display", NULL
, 0);
95 switch (display
->depth
) {
98 AllocateBootXMemory(kAppleBootWidth
* kAppleBootHeight
* 2);
99 for (cnt
= 0; cnt
< (kAppleBootWidth
* kAppleBootHeight
); cnt
++)
100 appleBoot16
[cnt
] = LookUpCLUTIndex(gAppleBootPict
[cnt
], 16);
101 gAppleBoot
= (char *)appleBoot16
;
106 AllocateBootXMemory(kAppleBootWidth
* kAppleBootHeight
* 4);
107 for (cnt
= 0; cnt
< (kAppleBootWidth
* kAppleBootHeight
); cnt
++)
108 appleBoot32
[cnt
] = LookUpCLUTIndex(gAppleBootPict
[cnt
], 32);
109 gAppleBoot
= (char *)appleBoot32
;
113 gAppleBoot
= (unsigned char *)gAppleBootPict
;
117 x
= (display
->width
- kAppleBootWidth
) / 2;
118 y
= (display
->height
- kAppleBootHeight
) / 2 + kAppleBootOffset
;
120 CallMethod(5, 0, display
->screenIH
, "draw-rectangle", (long)gAppleBoot
,
121 x
, y
, kAppleBootWidth
, kAppleBootHeight
);
123 if (gBootFileType
!= kNetworkDeviceType
) {
124 SpinInit(0, 0, NULL
, 0, 0, 0, 0, 0, 0, 0);
126 switch (display
->depth
) {
130 AllocateBootXMemory(kNetBootWidth
* kNetBootHeight
* kNetBootFrames
* 2);
131 for (cnt
= 0; cnt
< (kNetBootWidth
* kNetBootHeight
* kNetBootFrames
); cnt
++)
132 netBoot16
[cnt
] = LookUpCLUTIndex(gNetBootPict
[cnt
], 16);
133 gNetBoot
= (char *)netBoot16
;
139 AllocateBootXMemory(kNetBootWidth
* kNetBootHeight
* kNetBootFrames
* 4);
140 for (cnt
= 0; cnt
< (kNetBootWidth
* kNetBootHeight
* kNetBootFrames
); cnt
++)
141 netBoot32
[cnt
] = LookUpCLUTIndex(gNetBootPict
[cnt
], 32);
142 gNetBoot
= (char *)netBoot32
;
147 gNetBoot
= (unsigned char *)gNetBootPict
;
151 x
= (display
->width
- kNetBootWidth
) / 2;
152 y
= (display
->height
- kNetBootHeight
) / 2 + kNetBootOffset
;
154 CallMethod(5, 0, display
->screenIH
, "draw-rectangle", (long)gNetBoot
,
155 x
, y
, kNetBootWidth
, kNetBootHeight
);
157 // Set up the spin cursor.
158 SpinInit(display
->screenIH
, gNetBoot
,
160 kNetBootWidth
, kNetBootHeight
,
161 kNetBootFrames
, kNetBootFPS
, pixelSize
, 0);
166 x
= (display
->width
- kAppleBootWidth
) / 2;
167 y
= (display
->height
- kAppleBootHeight
) / 2 + kAppleBootOffset
;
169 CallMethod(5, 0, display
->screenIH
, "draw-rectangle", (long)gAppleBoot
,
170 x
, y
, kAppleBootWidth
, kAppleBootHeight
);
172 if (gBootFileType
== kNetworkDeviceType
) {
173 x
= (display
->width
- kNetBootWidth
) / 2;
174 y
= (display
->height
- kNetBootHeight
) / 2 + kNetBootOffset
;
176 // Erase the netboot picture with 75% grey.
177 CallMethod(5, 0, display
->screenIH
, "fill-rectangle",
178 LookUpCLUTIndex(0x01, display
->depth
),
179 x
, y
, kNetBootWidth
, kNetBootHeight
);
192 long DrawFailedBootPicture(void)
196 long *failedBoot32
, posX
, posY
;
197 DisplayInfoPtr display
= &gDisplays
[gMainDisplayNum
];
199 switch (display
->depth
) {
201 failedBoot16
= AllocateBootXMemory(32 * 32 * 2);
202 for (cnt
= 0; cnt
< (32 * 32); cnt
++)
203 failedBoot16
[cnt
] = LookUpCLUTIndex(gFailedBootPict
[cnt
], 16);
204 gFailedBoot
= (char *)failedBoot16
;
208 failedBoot32
= AllocateBootXMemory(32 * 32 * 4);
209 for (cnt
= 0; cnt
< (32 * 32); cnt
++)
210 failedBoot32
[cnt
] = LookUpCLUTIndex(gFailedBootPict
[cnt
], 32);
211 gFailedBoot
= (char *)failedBoot32
;
215 gFailedBoot
= (unsigned char *)gFailedBootPict
;
219 // Erase the newboot picture with 75% grey.
220 posX
= (display
->width
- kNetBootWidth
) / 2;
221 posY
= (display
->height
- kNetBootHeight
) / 2 + kNetBootOffset
;
222 CallMethod(5, 0, display
->screenIH
, "fill-rectangle",
223 LookUpCLUTIndex(0x01, display
->depth
),
224 posX
, posY
, kNetBootWidth
, kNetBootHeight
);
226 // Draw the failed boot picture.
227 posX
= (display
->width
- kFailedBootWidth
) / 2;
228 posY
= ((display
->height
- kFailedBootHeight
)) / 2 + kFailedBootOffset
;
229 CallMethod(5, 0, display
->screenIH
, "draw-rectangle",
230 (long)gFailedBoot
, posX
, posY
,
231 kFailedBootWidth
, kFailedBootHeight
);
237 void GetMainScreenPH(Boot_Video_Ptr video
)
239 DisplayInfoPtr display
;
242 if (gMainDisplayNum
== -1) {
243 // No display, set it to zero.
244 video
->v_baseAddr
= 0;
245 video
->v_rowBytes
= 0;
250 display
= &gDisplays
[gMainDisplayNum
];
252 video
->v_baseAddr
= display
->address
;
253 video
->v_rowBytes
= display
->linebytes
;
254 video
->v_width
= display
->width
;
255 video
->v_height
= display
->height
;
256 video
->v_depth
= display
->depth
;
259 // Allocate memory and a range for the CLUT.
261 address
= AllocateKernelMemory(size
);
262 AllocateMemoryRange("BootCLUT", address
, size
);
263 bcopy((char *)gClut
, (char *)address
, size
);
265 // Allocate memory and a range for the failed boot picture.
266 size
= 32 + kFailedBootWidth
* kFailedBootHeight
;
267 address
= AllocateKernelMemory(size
);
268 AllocateMemoryRange("Pict-FailedBoot", address
, size
);
269 ((long *)address
)[0] = kFailedBootWidth
;
270 ((long *)address
)[1] = kFailedBootHeight
;
271 ((long *)address
)[2] = kFailedBootOffset
;
272 bcopy((char *)gFailedBootPict
, (char *)(address
+ 32), size
- 32);
278 static long FindDisplays(void)
280 CICell screenPH
, controlPH
;
283 // Find all the screens in the system.
286 screenPH
= SearchForNode(screenPH
, 1, "device_type", "display");
287 if (screenPH
!= 0) gDisplays
[gNumDisplays
++].screenPH
= screenPH
;
291 // Find /chaos/control, and
292 // invalidate gStdOutPH if equal (since new OF was downloaded).
293 controlPH
= FindDevice("/chaos/control");
294 if (gStdOutPH
== controlPH
) gStdOutPH
= 0;
296 // Find the main screen using the screen alias or chaos/control.
297 gMainDisplayNum
= -1;
298 screenPH
= FindDevice("screen");
299 if (screenPH
== -1) screenPH
= controlPH
;
300 for (cnt
= 0; cnt
< gNumDisplays
; cnt
++)
301 if (gDisplays
[cnt
].screenPH
== screenPH
) gMainDisplayNum
= cnt
;
307 static long OpenDisplays(void)
311 // Open the main screen or
312 // look for a main screen if we don't have one.
313 if ((gMainDisplayNum
== -1) || !OpenDisplay(gMainDisplayNum
)) {
314 gMainDisplayNum
= -1;
315 for (cnt
= 0; cnt
< gNumDisplays
; cnt
++) {
316 if (OpenDisplay(cnt
)) {
317 gMainDisplayNum
= cnt
;
323 // Open the rest of the displays
324 if (gOFVersion
>= kOFVersion3x
) {
325 for (cnt
= 0; cnt
< gNumDisplays
; cnt
++) {
334 static long OpenDisplay(long displayNum
)
336 char screenPath
[258], displayType
[32];
337 CICell screenPH
, screenIH
;
340 // Only try to open a screen once.
341 if (gDisplays
[displayNum
].triedToOpen
) {
342 return gDisplays
[displayNum
].screenIH
!= 0;
344 gDisplays
[displayNum
].triedToOpen
= -1;
347 screenPH
= gDisplays
[displayNum
].screenPH
;
349 // Try to use mac-boot's ihandle.
350 Interpret(0, 1, "\" _screen-ihandle\" $find if execute else 0 then",
352 if ((screenIH
!= 0) && (InstanceToPackage(screenIH
) != screenPH
)) {
356 // Try to use stdout as the screen's ihandle
357 if ((screenIH
== 0) && (gStdOutPH
== screenPH
)) {
358 screenIH
= gStdOutIH
;
361 // Try to open the display.
363 screenPath
[255] = '\0';
364 ret
= PackageToPath(screenPH
, screenPath
, 255);
366 strcat(screenPath
, ":0");
367 screenIH
= Open(screenPath
);
371 // Find out what type of display is attached.
372 size
= GetProp(screenPH
, "display-type", displayType
, 31);
374 displayType
[size
] = '\0';
375 // If the display-type is NONE, don't use the display.
376 if (!strcmp(displayType
, "NONE")) screenIH
= 0;
379 // Save the ihandle for later use.
380 gDisplays
[displayNum
].screenIH
= screenIH
;
382 // Initialize the display.
383 if (screenIH
!= 0) InitDisplay(displayNum
);
385 return screenIH
!= 0;
389 static long InitDisplay(long displayNum
)
391 DisplayInfoPtr display
= &gDisplays
[displayNum
];
392 CICell screenPH
= display
->screenPH
;
393 CICell screenIH
= display
->screenIH
;
395 // Get the vital info for this screen.
396 GetProp(screenPH
, "address", (char *)&(display
->address
), 4);
397 GetProp(screenPH
, "width", (char *)&(display
->width
), 4);
398 GetProp(screenPH
, "height", (char *)&(display
->height
), 4);
399 GetProp(screenPH
, "depth", (char *)&(display
->depth
), 4);
400 GetProp(screenPH
, "linebytes", (char *)&(display
->linebytes
), 4);
402 // Replace some of the drivers words.
407 " frame-buffer-adr value this-frame-buffer-adr"
409 " : rect-setup" // ( adr|index x y w h -- w adr|index xy-adr h )
410 " >r >r rowbytes * swap depthbytes * + this-frame-buffer-adr +"
411 " r> depthbytes * -rot r>"
414 " : DRAW-RECTANGLE" // ( adr x y w h -- )
415 " rect-setup" // ( w adr xy-adr h )
416 " 0 ?do" // ( w adr xy-adr )
418 " 2 pick rowbytes d+"
423 " : FILL-RECTANGLE" // ( index x y w h -- )
424 " rect-setup rot depthbytes case"
425 " 1 of dup 8 << or dup 10 << or endof"
426 " 2 of dup 10 << or endof"
427 " endcase -rot 0 ?do"
428 " dup 3 pick 3 pick filll"
434 " : READ-RECTANGLE" // ( adr x y w h -- )
435 " rect-setup >r swap r> 0 ?do"
437 " rowbytes 3 pick d+"
442 " this-frame-buffer-adr"
443 " 0 to active-package"
444 , display
->screenPH
, display
->linebytes
,
445 display
->depth
/ 8, &display
->address
);
447 // Set the CLUT for 8 bit displays.
448 if (display
->depth
== 8) {
449 CallMethod(3, 0, screenIH
, "set-colors", (long)gClut
, 0, 256);
452 // Set the screen to 75% grey.
453 CallMethod(5, 0, screenIH
, "fill-rectangle",
454 LookUpCLUTIndex(0x01, display
->depth
),
455 0, 0, display
->width
, display
->height
);
461 static long LookUpCLUTIndex(long index
, long depth
)
463 long result
, red
, green
, blue
;
465 red
= gClut
[index
* 3 + 0];
466 green
= gClut
[index
* 3 + 1];
467 blue
= gClut
[index
* 3 + 2];
471 result
= ((red
& 0xF8) << 7)|((green
& 0xF8) << 2)|((blue
& 0xF8) >> 3);
475 result
= (red
<< 16) | (green
<< 8) | blue
;
488 static void DumpDisplaysInfo(void);
490 static void DumpDisplaysInfo(void)
495 printf("gNumDisplays: %x, gMainDisplayNum: %x\n",
496 gNumDisplays
, gMainDisplayNum
);
498 for (cnt
= 0; cnt
< gNumDisplays
; cnt
++) {
499 printf("Display: %x, screenPH: %x, screenIH: %x\n",
500 cnt
, gDisplays
[cnt
].screenPH
, gDisplays
[cnt
].screenIH
);
502 if (gDisplays
[cnt
].screenPH
) {
503 length
= PackageToPath(gDisplays
[cnt
].screenPH
, tmpStr
, 511);
504 tmpStr
[length
] = '\0';
505 printf("PHandle Path: %s\n", tmpStr
);
508 if (gDisplays
[cnt
].screenIH
) {
509 length
= InstanceToPath(gDisplays
[cnt
].screenIH
, tmpStr
, 511);
510 tmpStr
[length
] = '\0';
511 printf("IHandle Path: %s\n", tmpStr
);
514 printf("address = %x\n", gDisplays
[cnt
].address
);
515 printf("linebytes = %x\n", gDisplays
[cnt
].linebytes
);
516 printf("width = %x\n", gDisplays
[cnt
].width
);
517 printf("height = %x\n", gDisplays
[cnt
].height
);
518 printf("depth = %x\n", gDisplays
[cnt
].depth
);