]>
git.saurik.com Git - apple/bootx.git/blob - bootx.tproj/sl.subproj/display.c
a4bc44bf3e18ecc6ba4814c6dd76a65adedfc607
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
23 * display.c - Functions to manage and find display.
25 * Copyright (c) 1998-2002 Apple Computer, Inc.
33 #include "appleboot.h"
34 #include "failedboot.h"
48 typedef struct DisplayInfo DisplayInfo
, *DisplayInfoPtr
;
51 static long FindDisplays(void);
52 static long OpenDisplays(void);
53 static long OpenDisplay(long displayNum
);
54 static long InitDisplay(long displayNum
);
55 static long LookUpCLUTIndex(long index
, long depth
);
57 static long gNumDisplays
;
58 static long gMainDisplayNum
;
59 static DisplayInfo gDisplays
[16];
61 static unsigned char *gAppleBoot
;
62 static unsigned char *gNetBoot
;
63 static unsigned char *gFailedBoot
;
67 long InitDisplays(void)
76 long DrawSplashScreen(long stage
)
78 DisplayInfoPtr display
;
79 short *appleBoot16
, *netBoot16
;
80 long *appleBoot32
, *netBoot32
;
81 long cnt
, x
, y
, pixelSize
;
83 if (gMainDisplayNum
== -1) return 0;
85 display
= &gDisplays
[gMainDisplayNum
];
89 // Make sure the boot display is marked.
90 SetProp(display
->screenPH
, "AAPL,boot-display", NULL
, 0);
92 switch (display
->depth
) {
95 AllocateBootXMemory(kAppleBootWidth
* kAppleBootHeight
* 2);
96 for (cnt
= 0; cnt
< (kAppleBootWidth
* kAppleBootHeight
); cnt
++)
97 appleBoot16
[cnt
] = LookUpCLUTIndex(gAppleBootPict
[cnt
], 16);
98 gAppleBoot
= (char *)appleBoot16
;
103 AllocateBootXMemory(kAppleBootWidth
* kAppleBootHeight
* 4);
104 for (cnt
= 0; cnt
< (kAppleBootWidth
* kAppleBootHeight
); cnt
++)
105 appleBoot32
[cnt
] = LookUpCLUTIndex(gAppleBootPict
[cnt
], 32);
106 gAppleBoot
= (char *)appleBoot32
;
110 gAppleBoot
= (unsigned char *)gAppleBootPict
;
114 x
= (display
->width
- kAppleBootWidth
) / 2;
115 y
= (display
->height
- kAppleBootHeight
) / 2 + kAppleBootOffset
;
117 CallMethod(5, 0, display
->screenIH
, "draw-rectangle", (long)gAppleBoot
,
118 x
, y
, kAppleBootWidth
, kAppleBootHeight
);
120 if (gBootFileType
!= kNetworkDeviceType
) {
121 SpinInit(0, 0, NULL
, 0, 0, 0, 0, 0, 0, 0);
123 switch (display
->depth
) {
127 AllocateBootXMemory(kNetBootWidth
* kNetBootHeight
* kNetBootFrames
* 2);
128 for (cnt
= 0; cnt
< (kNetBootWidth
* kNetBootHeight
* kNetBootFrames
); cnt
++)
129 netBoot16
[cnt
] = LookUpCLUTIndex(gNetBootPict
[cnt
], 16);
130 gNetBoot
= (char *)netBoot16
;
136 AllocateBootXMemory(kNetBootWidth
* kNetBootHeight
* kNetBootFrames
* 4);
137 for (cnt
= 0; cnt
< (kNetBootWidth
* kNetBootHeight
* kNetBootFrames
); cnt
++)
138 netBoot32
[cnt
] = LookUpCLUTIndex(gNetBootPict
[cnt
], 32);
139 gNetBoot
= (char *)netBoot32
;
144 gNetBoot
= (unsigned char *)gNetBootPict
;
148 x
= (display
->width
- kNetBootWidth
) / 2;
149 y
= (display
->height
- kNetBootHeight
) / 2 + kNetBootOffset
;
151 CallMethod(5, 0, display
->screenIH
, "draw-rectangle", (long)gNetBoot
,
152 x
, y
, kNetBootWidth
, kNetBootHeight
);
154 // Set up the spin cursor.
155 SpinInit(display
->screenIH
, gNetBoot
,
157 kNetBootWidth
, kNetBootHeight
,
158 kNetBootFrames
, kNetBootFPS
, pixelSize
, 0);
163 x
= (display
->width
- kAppleBootWidth
) / 2;
164 y
= (display
->height
- kAppleBootHeight
) / 2 + kAppleBootOffset
;
166 CallMethod(5, 0, display
->screenIH
, "draw-rectangle", (long)gAppleBoot
,
167 x
, y
, kAppleBootWidth
, kAppleBootHeight
);
169 if (gBootFileType
== kNetworkDeviceType
) {
170 x
= (display
->width
- kNetBootWidth
) / 2;
171 y
= (display
->height
- kNetBootHeight
) / 2 + kNetBootOffset
;
173 // Erase the netboot picture with 75% grey.
174 CallMethod(5, 0, display
->screenIH
, "fill-rectangle",
175 LookUpCLUTIndex(0x01, display
->depth
),
176 x
, y
, kNetBootWidth
, kNetBootHeight
);
189 long DrawFailedBootPicture(void)
193 long *failedBoot32
, posX
, posY
;
194 DisplayInfoPtr display
= &gDisplays
[gMainDisplayNum
];
196 switch (display
->depth
) {
198 failedBoot16
= AllocateBootXMemory(32 * 32 * 2);
199 for (cnt
= 0; cnt
< (32 * 32); cnt
++)
200 failedBoot16
[cnt
] = LookUpCLUTIndex(gFailedBootPict
[cnt
], 16);
201 gFailedBoot
= (char *)failedBoot16
;
205 failedBoot32
= AllocateBootXMemory(32 * 32 * 4);
206 for (cnt
= 0; cnt
< (32 * 32); cnt
++)
207 failedBoot32
[cnt
] = LookUpCLUTIndex(gFailedBootPict
[cnt
], 32);
208 gFailedBoot
= (char *)failedBoot32
;
212 gFailedBoot
= (unsigned char *)gFailedBootPict
;
216 // Erase the newboot picture with 75% grey.
217 posX
= (display
->width
- kNetBootWidth
) / 2;
218 posY
= (display
->height
- kNetBootHeight
) / 2 + kNetBootOffset
;
219 CallMethod(5, 0, display
->screenIH
, "fill-rectangle",
220 LookUpCLUTIndex(0x01, display
->depth
),
221 posX
, posY
, kNetBootWidth
, kNetBootHeight
);
223 // Draw the failed boot picture.
224 posX
= (display
->width
- kFailedBootWidth
) / 2;
225 posY
= ((display
->height
- kFailedBootHeight
)) / 2 + kFailedBootOffset
;
226 CallMethod(5, 0, display
->screenIH
, "draw-rectangle",
227 (long)gFailedBoot
, posX
, posY
,
228 kFailedBootWidth
, kFailedBootHeight
);
234 void GetMainScreenPH(Boot_Video_Ptr video
)
236 DisplayInfoPtr display
;
239 if (gMainDisplayNum
== -1) {
240 // No display, set it to zero.
241 video
->v_baseAddr
= 0;
242 video
->v_rowBytes
= 0;
247 display
= &gDisplays
[gMainDisplayNum
];
249 video
->v_baseAddr
= display
->address
;
250 video
->v_rowBytes
= display
->linebytes
;
251 video
->v_width
= display
->width
;
252 video
->v_height
= display
->height
;
253 video
->v_depth
= display
->depth
;
256 // Allocate memory and a range for the CLUT.
258 address
= AllocateKernelMemory(size
);
259 AllocateMemoryRange("BootCLUT", address
, size
);
260 bcopy((char *)gClut
, (char *)address
, size
);
262 // Allocate memory and a range for the failed boot picture.
263 size
= 32 + kFailedBootWidth
* kFailedBootHeight
;
264 address
= AllocateKernelMemory(size
);
265 AllocateMemoryRange("Pict-FailedBoot", address
, size
);
266 ((long *)address
)[0] = kFailedBootWidth
;
267 ((long *)address
)[1] = kFailedBootHeight
;
268 ((long *)address
)[2] = kFailedBootOffset
;
269 bcopy((char *)gFailedBootPict
, (char *)(address
+ 32), size
- 32);
275 static long FindDisplays(void)
277 CICell screenPH
, controlPH
;
280 // Find all the screens in the system.
283 screenPH
= SearchForNode(screenPH
, 1, "device_type", "display");
284 if (screenPH
!= 0) gDisplays
[gNumDisplays
++].screenPH
= screenPH
;
288 // Find /chaos/control, and
289 // invalidate gStdOutPH if equal (since new OF was downloaded).
290 controlPH
= FindDevice("/chaos/control");
291 if (gStdOutPH
== controlPH
) gStdOutPH
= 0;
293 // Find the main screen using the screen alias or chaos/control.
294 gMainDisplayNum
= -1;
295 screenPH
= FindDevice("screen");
296 if (screenPH
== -1) screenPH
= controlPH
;
297 for (cnt
= 0; cnt
< gNumDisplays
; cnt
++)
298 if (gDisplays
[cnt
].screenPH
== screenPH
) gMainDisplayNum
= cnt
;
304 static long OpenDisplays(void)
308 // Open the main screen or
309 // look for a main screen if we don't have one.
310 if ((gMainDisplayNum
== -1) || !OpenDisplay(gMainDisplayNum
)) {
311 gMainDisplayNum
= -1;
312 for (cnt
= 0; cnt
< gNumDisplays
; cnt
++) {
313 if (OpenDisplay(cnt
)) {
314 gMainDisplayNum
= cnt
;
320 // Open the rest of the displays
321 if (gOFVersion
>= kOFVersion3x
) {
322 for (cnt
= 0; cnt
< gNumDisplays
; cnt
++) {
331 static long OpenDisplay(long displayNum
)
333 char screenPath
[258], displayType
[32];
334 CICell screenPH
, screenIH
;
337 // Only try to open a screen once.
338 if (gDisplays
[displayNum
].triedToOpen
) {
339 return gDisplays
[displayNum
].screenIH
!= 0;
341 gDisplays
[displayNum
].triedToOpen
= -1;
344 screenPH
= gDisplays
[displayNum
].screenPH
;
346 // Try to use mac-boot's ihandle.
347 Interpret(0, 1, "\" _screen-ihandle\" $find if execute else 0 then",
349 if ((screenIH
!= 0) && (InstanceToPackage(screenIH
) != screenPH
)) {
353 // Try to use stdout as the screen's ihandle
354 if ((screenIH
== 0) && (gStdOutPH
== screenPH
)) {
355 screenIH
= gStdOutIH
;
358 // Try to open the display.
360 screenPath
[255] = '\0';
361 ret
= PackageToPath(screenPH
, screenPath
, 255);
363 strcat(screenPath
, ":0");
364 screenIH
= Open(screenPath
);
368 // Find out what type of display is attached.
369 size
= GetProp(screenPH
, "display-type", displayType
, 31);
371 displayType
[size
] = '\0';
372 // If the display-type is NONE, don't use the display.
373 if (!strcmp(displayType
, "NONE")) screenIH
= 0;
376 // Save the ihandle for later use.
377 gDisplays
[displayNum
].screenIH
= screenIH
;
379 // Initialize the display.
380 if (screenIH
!= 0) InitDisplay(displayNum
);
382 return screenIH
!= 0;
386 static long InitDisplay(long displayNum
)
388 DisplayInfoPtr display
= &gDisplays
[displayNum
];
389 CICell screenPH
= display
->screenPH
;
390 CICell screenIH
= display
->screenIH
;
392 // Get the vital info for this screen.
393 GetProp(screenPH
, "address", (char *)&(display
->address
), 4);
394 GetProp(screenPH
, "width", (char *)&(display
->width
), 4);
395 GetProp(screenPH
, "height", (char *)&(display
->height
), 4);
396 GetProp(screenPH
, "depth", (char *)&(display
->depth
), 4);
397 GetProp(screenPH
, "linebytes", (char *)&(display
->linebytes
), 4);
399 // Replace some of the drivers words.
404 " frame-buffer-adr value this-frame-buffer-adr"
406 " : rect-setup" // ( adr|index x y w h -- w adr|index xy-adr h )
407 " >r >r rowbytes * swap depthbytes * + this-frame-buffer-adr +"
408 " r> depthbytes * -rot r>"
411 " : DRAW-RECTANGLE" // ( adr x y w h -- )
412 " rect-setup" // ( w adr xy-adr h )
413 " 0 ?do" // ( w adr xy-adr )
415 " 2 pick rowbytes d+"
420 " : FILL-RECTANGLE" // ( index x y w h -- )
421 " rect-setup rot depthbytes case"
422 " 1 of dup 8 << or dup 10 << or endof"
423 " 2 of dup 10 << or endof"
424 " endcase -rot 0 ?do"
425 " dup 3 pick 3 pick filll"
431 " : READ-RECTANGLE" // ( adr x y w h -- )
432 " rect-setup >r swap r> 0 ?do"
434 " rowbytes 3 pick d+"
439 " this-frame-buffer-adr"
440 " 0 to active-package"
441 , display
->screenPH
, display
->linebytes
,
442 display
->depth
/ 8, &display
->address
);
444 // Set the CLUT for 8 bit displays.
445 if (display
->depth
== 8) {
446 CallMethod(3, 0, screenIH
, "set-colors", (long)gClut
, 0, 256);
449 // Set the screen to 75% grey.
450 CallMethod(5, 0, screenIH
, "fill-rectangle",
451 LookUpCLUTIndex(0x01, display
->depth
),
452 0, 0, display
->width
, display
->height
);
458 static long LookUpCLUTIndex(long index
, long depth
)
460 long result
, red
, green
, blue
;
462 red
= gClut
[index
* 3 + 0];
463 green
= gClut
[index
* 3 + 1];
464 blue
= gClut
[index
* 3 + 2];
468 result
= ((red
& 0xF8) << 7)|((green
& 0xF8) << 2)|((blue
& 0xF8) >> 3);
472 result
= (red
<< 16) | (green
<< 8) | blue
;
485 static void DumpDisplaysInfo(void);
487 static void DumpDisplaysInfo(void)
492 printf("gNumDisplays: %x, gMainDisplayNum: %x\n",
493 gNumDisplays
, gMainDisplayNum
);
495 for (cnt
= 0; cnt
< gNumDisplays
; cnt
++) {
496 printf("Display: %x, screenPH: %x, screenIH: %x\n",
497 cnt
, gDisplays
[cnt
].screenPH
, gDisplays
[cnt
].screenIH
);
499 if (gDisplays
[cnt
].screenPH
) {
500 length
= PackageToPath(gDisplays
[cnt
].screenPH
, tmpStr
, 511);
501 tmpStr
[length
] = '\0';
502 printf("PHandle Path: %s\n", tmpStr
);
505 if (gDisplays
[cnt
].screenIH
) {
506 length
= InstanceToPath(gDisplays
[cnt
].screenIH
, tmpStr
, 511);
507 tmpStr
[length
] = '\0';
508 printf("IHandle Path: %s\n", tmpStr
);
511 printf("address = %x\n", gDisplays
[cnt
].address
);
512 printf("linebytes = %x\n", gDisplays
[cnt
].linebytes
);
513 printf("width = %x\n", gDisplays
[cnt
].width
);
514 printf("height = %x\n", gDisplays
[cnt
].height
);
515 printf("depth = %x\n", gDisplays
[cnt
].depth
);