]>
Commit | Line | Data |
---|---|---|
04fee52e A |
1 | /* |
2 | * Copyright (c) 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 | * display.c - Functions to manage and find displays. | |
24 | * | |
25 | * Copyright (c) 1998-2000 Apple Computer, Inc. | |
26 | * | |
27 | * DRI: Josh de Cesare | |
28 | */ | |
29 | ||
30 | #include <sl.h> | |
31 | ||
32 | #include "clut.h" | |
33 | ||
34 | #include "bad_system.h" | |
35 | ||
36 | #if kMacOSXServer | |
37 | #include "images.h" | |
38 | #else | |
39 | #include "happy_mac.h" | |
40 | #include "happy_foot.h" | |
41 | #endif | |
42 | ||
43 | struct DisplayInfo { | |
44 | CICell screenPH; | |
45 | CICell screenIH; | |
46 | CICell address; | |
47 | CICell width; | |
48 | CICell height; | |
49 | CICell depth; | |
50 | CICell linebytes; | |
51 | }; | |
52 | ||
53 | typedef struct DisplayInfo DisplayInfo, *DisplayInfoPtr; | |
54 | ||
55 | // The Driver Description | |
56 | enum { | |
57 | kInitialDriverDescriptor = 0, | |
58 | kVersionOneDriverDescriptor = 1, | |
59 | kTheDescriptionSignature = 'mtej', | |
60 | kDriverDescriptionSignature = 'pdes' | |
61 | }; | |
62 | ||
63 | struct DriverType { | |
64 | unsigned char nameInfoStr[32]; // Driver Name/Info String | |
65 | unsigned long version; // Driver Version Number - really NumVersion | |
66 | }; | |
67 | typedef struct DriverType DriverType; | |
68 | ||
69 | struct DriverDescription { | |
70 | unsigned long driverDescSignature; // Signature field of this structure | |
71 | unsigned long driverDescVersion; // Version of this data structure | |
72 | DriverType driverType; // Type of Driver | |
73 | char otherStuff[512]; | |
74 | }; | |
75 | typedef struct DriverDescription DriverDescription; | |
76 | ||
77 | #define kNumNetDrivers (7) | |
78 | ||
79 | char *gNetDriverFileNames[kNumNetDrivers] = { | |
80 | "ATYRagePro_ndrv", | |
81 | "Spinnaker_ndrv", | |
82 | "ATYLT-G_ndrv", | |
83 | "ATYLTPro_ndrv", | |
84 | "chips65550_ndrv", | |
85 | "control_ndrv", | |
86 | "ATYRage_ndrv" | |
87 | }; | |
88 | ||
89 | char *gNetDriverMatchNames[kNumNetDrivers] = { | |
90 | "ATY,mach64_3DUPro", | |
91 | "ATY,mach64", | |
92 | "ATY,264LT-G", | |
93 | "ATY,RageLTPro", | |
94 | "chips65550", | |
95 | "control", | |
96 | "ATY,mach64_3DU" | |
97 | }; | |
98 | ||
99 | static long FindDisplays(void); | |
100 | static long OpenDisplays(void); | |
101 | static void DumpDisplaysInfo(void); | |
102 | static long OpenDisplay(long displayNum); | |
103 | static long InitDisplay(long displayNum); | |
104 | static long NetLoadDrivers(void); | |
105 | static long DiskLoadDrivers(void); | |
106 | static long LoadDisplayDriver(char *fileSpec); | |
107 | static long LookUpCLUTIndex(long index, long depth); | |
108 | ||
109 | static long gNumDisplays; | |
110 | static long gMainDisplayNum; | |
111 | static DisplayInfo gDisplays[16]; | |
112 | ||
113 | // Public Functions | |
114 | ||
115 | long InitDisplays(void) | |
116 | { | |
117 | FindDisplays(); | |
118 | OpenDisplays(); | |
119 | ||
120 | return 0; | |
121 | } | |
122 | ||
123 | ||
124 | long LoadDisplayDrivers(void) | |
125 | { | |
126 | long ret; | |
127 | ||
128 | // Don't bother if there are no displays. | |
129 | if (gNumDisplays == 0) return 0; | |
130 | ||
131 | ret = NetLoadDrivers(); | |
132 | ||
133 | #if 0 | |
134 | switch (gBootFileType) { | |
135 | case kNetworkDeviceType : | |
136 | ret = NetLoadDrivers(); | |
137 | break; | |
138 | ||
139 | case kBlockDeviceType : | |
140 | ret = DiskLoadDrivers(); | |
141 | break; | |
142 | ||
143 | case kUnknownDeviceType : | |
144 | ret = 0; | |
145 | } | |
146 | #endif | |
147 | ||
148 | return ret; | |
149 | } | |
150 | ||
151 | ||
152 | long DrawSplashScreen(void) | |
153 | { | |
154 | DisplayInfoPtr display; | |
155 | unsigned char *happyMac, *happyFoot; | |
156 | short *happyMac16, *happyFoot16; | |
157 | long *happyMac32, *happyFoot32; | |
158 | long cnt, x, y, pixelSize; | |
159 | ||
160 | if (gMainDisplayNum == -1) return 0; | |
161 | ||
162 | display = &gDisplays[gMainDisplayNum]; | |
163 | ||
164 | // Make sure the boot display is marked. | |
165 | SetProp(display->screenPH, "AAPL,boot-display", NULL, 0); | |
166 | ||
167 | #if kMacOSXServer | |
168 | x = (display->width - BIG_WIDTH) / 2; | |
169 | y = ((display->height - BIG_HEIGHT)) / 2 + BIG_DY; | |
170 | ||
171 | CallMethod_5_0(display->screenIH, "draw-rectangle", (long)bigImage, | |
172 | x, y, BIG_WIDTH, BIG_HEIGHT); | |
173 | ||
174 | x = (display->width - SPIN_WIDTH) / 2; | |
175 | y = ((display->height - SPIN_WIDTH) / 2) + 28; | |
176 | ||
177 | // Set up the spin cursor. | |
178 | SpinInit(0, display->screenIH, waitCursors, | |
179 | x, y, SPIN_WIDTH, SPIN_WIDTH); | |
180 | ||
181 | // Do a spin to start things off. | |
182 | Spin(); | |
183 | ||
184 | #else | |
185 | ||
186 | switch (display->depth) { | |
187 | case 16 : | |
188 | happyMac16 = malloc(kHappyMacWidth * kHappyMacHeight * 2); | |
189 | for (cnt = 0; cnt < (kHappyMacWidth * kHappyMacHeight); cnt++) | |
190 | happyMac16[cnt] = LookUpCLUTIndex(gHappyMacIcon[cnt], 16); | |
191 | happyMac = (char *)happyMac16; | |
192 | break; | |
193 | ||
194 | case 32 : | |
195 | happyMac32 = malloc(kHappyMacWidth * kHappyMacHeight * 4); | |
196 | for (cnt = 0; cnt < (kHappyMacWidth * kHappyMacHeight); cnt++) | |
197 | happyMac32[cnt] = LookUpCLUTIndex(gHappyMacIcon[cnt], 32); | |
198 | happyMac = (char *)happyMac32; | |
199 | break; | |
200 | ||
201 | default : | |
202 | happyMac = gHappyMacIcon; | |
203 | break; | |
204 | } | |
205 | ||
206 | x = (display->width - kHappyMacWidth) / 2; | |
207 | y = (display->height - kHappyMacHeight) / 2; | |
208 | ||
209 | CallMethod_5_0(display->screenIH, "draw-rectangle", (long)happyMac, | |
210 | x, y, kHappyMacWidth, kHappyMacHeight); | |
211 | ||
212 | if (gBootFileType != kNetworkDeviceType) { | |
213 | SpinInit(0, 0, NULL, 0, 0, 0, 0, 0); | |
214 | } else { | |
215 | Interpret_1_0("ms", 1000); | |
216 | ||
217 | switch (display->depth) { | |
218 | case 16 : | |
219 | pixelSize = 2; | |
220 | happyFoot16 = malloc(kHappyFootWidth * kHappyFootHeight * 2); | |
221 | for (cnt = 0; cnt < (kHappyFootWidth * kHappyFootHeight); cnt++) | |
222 | happyFoot16[cnt] = LookUpCLUTIndex(gHappyFootPict[cnt], 16); | |
223 | happyFoot = (char *)happyFoot16; | |
224 | break; | |
225 | ||
226 | case 32 : | |
227 | pixelSize = 4; | |
228 | happyFoot32 = malloc(kHappyFootWidth * kHappyFootHeight * 4); | |
229 | for (cnt = 0; cnt < (kHappyFootWidth * kHappyFootHeight); cnt++) | |
230 | happyFoot32[cnt] = LookUpCLUTIndex(gHappyFootPict[cnt], 32); | |
231 | happyFoot = (char *)happyFoot32; | |
232 | break; | |
233 | ||
234 | default : | |
235 | pixelSize = 1; | |
236 | happyFoot = gHappyFootPict; | |
237 | break; | |
238 | } | |
239 | ||
240 | for (cnt = 0; cnt < kHappyFootHeight - 1; cnt++) { | |
241 | ||
242 | CallMethod_5_0(display->screenIH, "draw-rectangle", (long)happyMac, | |
243 | x, y - cnt, kHappyMacWidth, kHappyMacHeight); | |
244 | ||
245 | CallMethod_5_0(display->screenIH, "draw-rectangle", | |
246 | (long)happyFoot + pixelSize * | |
247 | kHappyFootWidth * (kHappyFootHeight - cnt - 1), | |
248 | x + 6, y + kHappyMacHeight - 1 - cnt, | |
249 | kHappyFootWidth, cnt + 1); | |
250 | ||
251 | CallMethod_5_0(display->screenIH, "draw-rectangle", | |
252 | (long)happyFoot + pixelSize * | |
253 | kHappyFootWidth * (kHappyFootHeight - cnt - 1), | |
254 | x + 15, y + kHappyMacHeight - 1 - cnt, | |
255 | kHappyFootWidth, cnt + 1); | |
256 | ||
257 | Interpret_1_0("ms", 75); | |
258 | } | |
259 | ||
260 | // Set up the spin cursor. | |
261 | SpinInit(1, display->screenIH, happyFoot, | |
262 | x + 15, y + kHappyMacHeight - kHappyFootHeight + 1, | |
263 | kHappyFootWidth, kHappyFootHeight, pixelSize); | |
264 | } | |
265 | #endif | |
266 | ||
267 | return 0; | |
268 | } | |
269 | ||
270 | ||
271 | long DrawBrokenSystemFolder(void) | |
272 | { | |
273 | long cnt; | |
274 | unsigned char *iconPtr, tmpIcon[1024]; | |
275 | short *icon16; | |
276 | long *icon32; | |
277 | DisplayInfoPtr display = &gDisplays[gMainDisplayNum]; | |
278 | ||
279 | long x, y; | |
280 | ||
281 | #if kMacOSXServer | |
282 | // Set the screen to Medium Blue | |
283 | CallMethod_5_0(display->screenIH, "fill-rectangle", 128, 0, 0, | |
284 | display->width, display->height); | |
285 | ||
286 | // Use the default icon. | |
287 | iconPtr = gBrokenSystemFolderIcon; | |
288 | #else | |
289 | // Set the screen to Medium Grey | |
290 | CallMethod_5_0(display->screenIH, "fill-rectangle", | |
291 | LookUpCLUTIndex(0xF9, display->depth), | |
292 | 0, 0, display->width, display->height); | |
293 | ||
294 | // Convert the default icon. | |
295 | for (cnt = 0; cnt < 1024; cnt++) { | |
296 | tmpIcon[cnt] = gBrokenSystemFolderIcon[cnt]; | |
297 | if (tmpIcon[cnt] == 0x80) tmpIcon[cnt] = 0xF9; | |
298 | } | |
299 | iconPtr = tmpIcon; | |
300 | #endif | |
301 | ||
302 | switch (display->depth) { | |
303 | case 16 : | |
304 | icon16 = malloc(32 * 32 * 2); | |
305 | for (cnt = 0; cnt < (32 * 32); cnt++) | |
306 | icon16[cnt] = LookUpCLUTIndex(iconPtr[cnt], 16); | |
307 | iconPtr = (char *)icon16; | |
308 | break; | |
309 | ||
310 | case 32 : | |
311 | icon32 = malloc(32 * 32 * 4); | |
312 | for (cnt = 0; cnt < (32 * 32); cnt++) | |
313 | icon32[cnt] = LookUpCLUTIndex(iconPtr[cnt], 32); | |
314 | iconPtr = (char *)icon32; | |
315 | break; | |
316 | ||
317 | default : | |
318 | break; | |
319 | } | |
320 | ||
321 | // Draw the broken system folder. | |
322 | x = (display->width - 32) / 2; | |
323 | y = ((display->height - 32)) / 2; | |
324 | CallMethod_5_0(display->screenIH, "draw-rectangle", | |
325 | (long)iconPtr, x, y, 32, 32); | |
326 | ||
327 | return 0; | |
328 | } | |
329 | ||
330 | ||
331 | void GetMainScreenPH(Boot_Video_Ptr video) | |
332 | { | |
333 | DisplayInfoPtr display; | |
334 | ||
335 | if (gMainDisplayNum == -1) { | |
336 | // No display, set it to zero. | |
337 | video->v_baseAddr = 0; | |
338 | video->v_rowBytes = 0; | |
339 | video->v_width = 0; | |
340 | video->v_height = 0; | |
341 | video->v_depth = 0; | |
342 | } else { | |
343 | display = &gDisplays[gMainDisplayNum]; | |
344 | ||
345 | video->v_baseAddr = display->address; | |
346 | video->v_rowBytes = display->linebytes; | |
347 | video->v_width = display->width; | |
348 | video->v_height = display->height; | |
349 | video->v_depth = display->depth; | |
350 | } | |
351 | } | |
352 | ||
353 | // Private Functions | |
354 | ||
355 | static long FindDisplays(void) | |
356 | { | |
357 | CICell screenPH, controlPH; | |
358 | long cnt; | |
359 | ||
360 | // Find all the screens in the system. | |
361 | screenPH = 0; | |
362 | while (1) { | |
363 | screenPH = SearchForNode(screenPH, 1, "device_type", "display"); | |
364 | if (screenPH != 0) gDisplays[gNumDisplays++].screenPH = screenPH; | |
365 | else break; | |
366 | } | |
367 | ||
368 | // Find /chaos/control, and | |
369 | // invalidate gStdOutPH if equal (since new OF was downloaded). | |
370 | controlPH = FindDevice("/chaos/control"); | |
371 | if (gStdOutPH == controlPH) gStdOutPH = 0; | |
372 | ||
373 | // Find the main screen using the screen alias or chaos/control. | |
374 | gMainDisplayNum = -1; | |
375 | screenPH = FindDevice("screen"); | |
376 | if (screenPH == -1) screenPH = controlPH; | |
377 | for (cnt = 0; cnt < gNumDisplays; cnt++) | |
378 | if (gDisplays[cnt].screenPH == screenPH) gMainDisplayNum = cnt; | |
379 | ||
380 | return 0; | |
381 | } | |
382 | ||
383 | ||
384 | static long OpenDisplays(void) | |
385 | { | |
386 | long cnt; | |
387 | ||
388 | // Open the main screen or | |
389 | // look for a main screen if we don't have one. | |
390 | if ((gMainDisplayNum == -1) || !OpenDisplay(gMainDisplayNum)) { | |
391 | gMainDisplayNum = -1; | |
392 | for (cnt = 0; cnt < gNumDisplays; cnt++) { | |
393 | if (OpenDisplay(cnt)) { | |
394 | gMainDisplayNum = cnt; | |
395 | break; | |
396 | } | |
397 | } | |
398 | } | |
399 | ||
400 | return 0; | |
401 | } | |
402 | ||
403 | static void DumpDisplaysInfo(void) | |
404 | { | |
405 | long cnt, length; | |
406 | char tmpStr[512]; | |
407 | ||
408 | printf("gNumDisplays: %x, gMainDisplayNum: %x\n", | |
409 | gNumDisplays, gMainDisplayNum); | |
410 | ||
411 | for (cnt = 0; cnt < gNumDisplays; cnt++) { | |
412 | printf("Display: %x, screenPH: %x, screenIH: %x\n", | |
413 | cnt, gDisplays[cnt].screenPH, gDisplays[cnt].screenIH); | |
414 | ||
415 | if (gDisplays[cnt].screenPH) { | |
416 | length = PackageToPath(gDisplays[cnt].screenPH, tmpStr, 511); | |
417 | tmpStr[length] = '\0'; | |
418 | printf("PHandle Path: %s\n", tmpStr); | |
419 | } | |
420 | ||
421 | if (gDisplays[cnt].screenIH) { | |
422 | length = InstanceToPath(gDisplays[cnt].screenIH, tmpStr, 511); | |
423 | tmpStr[length] = '\0'; | |
424 | printf("IHandle Path: %s\n", tmpStr); | |
425 | } | |
426 | ||
427 | printf("address = %x\n", gDisplays[cnt].address); | |
428 | printf("linebytes = %x\n", gDisplays[cnt].linebytes); | |
429 | printf("width = %x\n", gDisplays[cnt].width); | |
430 | printf("height = %x\n", gDisplays[cnt].height); | |
431 | printf("depth = %x\n", gDisplays[cnt].depth); | |
432 | printf("\n"); | |
433 | } | |
434 | } | |
435 | ||
436 | ||
437 | static long OpenDisplay(long displayNum) | |
438 | { | |
439 | char screenPath[256]; | |
440 | CICell screenIH; | |
441 | long ret; | |
442 | ||
443 | // Try to use mac-boot's ihandle. | |
444 | Interpret_0_1("\" _screen-ihandle\" $find if execute else 0 then", | |
445 | &screenIH); | |
446 | ||
447 | // Try to use stdout as the screen's ihandle | |
448 | if (gStdOutPH == gDisplays[displayNum].screenPH) screenIH = gStdOutIH; | |
449 | ||
450 | // Try to open the display. | |
451 | if (screenIH == 0) { | |
452 | screenPath[255] = '\0'; | |
453 | ret = PackageToPath(gDisplays[displayNum].screenPH, screenPath, 255); | |
454 | if (ret != -1) { | |
455 | screenIH = Open(screenPath); | |
456 | } | |
457 | } | |
458 | ||
459 | // Save the ihandle for later use. | |
460 | gDisplays[displayNum].screenIH = screenIH; | |
461 | ||
462 | // Initialize the display. | |
463 | if (screenIH != 0) InitDisplay(displayNum); | |
464 | ||
465 | return screenIH != 0; | |
466 | } | |
467 | ||
468 | ||
469 | static long InitDisplay(long displayNum) | |
470 | { | |
471 | DisplayInfoPtr display = &gDisplays[displayNum]; | |
472 | CICell screenPH = display->screenPH; | |
473 | CICell screenIH = display->screenIH; | |
474 | ||
475 | // Get the vital info for this screen. | |
476 | GetProp(screenPH, "address", (char *)&(display->address), 4); | |
477 | GetProp(screenPH, "width", (char *)&(display->width), 4); | |
478 | GetProp(screenPH, "height", (char *)&(display->height), 4); | |
479 | GetProp(screenPH, "depth", (char *)&(display->depth), 4); | |
480 | GetProp(screenPH, "linebytes", (char *)&(display->linebytes), 4); | |
481 | ||
482 | // Replace some of the drivers words. | |
483 | Interpret_3_1( | |
484 | " to active-package" | |
485 | " value rowbytes" | |
486 | " value depthbytes" | |
487 | ||
488 | " : rect-setup" // ( adr|index x y w h -- w adr|index xy-adr h ) | |
489 | " >r >r rowbytes * swap depthbytes * + frame-buffer-adr +" | |
490 | " r> depthbytes * -rot r>" | |
491 | " ;" | |
492 | ||
493 | " : DRAW-RECTANGLE" // ( adr x y w h -- ) | |
494 | " rect-setup" // ( w adr xy-adr h ) | |
495 | " 0 ?do" // ( w adr xy-adr ) | |
496 | " 2dup 4 pick move" | |
497 | " 2 pick rowbytes d+" | |
498 | " loop" | |
499 | " 3drop" | |
500 | " ;" | |
501 | ||
502 | " : FILL-RECTANGLE" // ( index x y w h -- ) | |
503 | " rect-setup rot depthbytes case" | |
504 | " 1 of dup 8 << or dup 10 << or endof" | |
505 | " 2 of dup 10 << or endof" | |
506 | " endcase -rot 0 ?do" | |
507 | " dup 3 pick 3 pick filll" | |
508 | " rowbytes +" | |
509 | " loop" | |
510 | " 3drop" | |
511 | " ;" | |
512 | ||
513 | " : READ-RECTANGLE" // ( adr x y w h -- ) | |
514 | " rect-setup >r swap r> 0 ?do" | |
515 | " 2dup 4 pick move" | |
516 | " rowbytes 3 pick d+" | |
517 | " loop" | |
518 | " 3drop" | |
519 | " ;" | |
520 | ||
521 | " frame-buffer-adr" | |
522 | " 0 to active-package" | |
523 | , display->screenPH, display->linebytes, | |
524 | display->depth / 8, &display->address); | |
525 | ||
526 | // Set the CLUT for 8 bit displays | |
527 | if (display->depth == 8) { | |
528 | CallMethod_3_0(screenIH, "set-colors", (long)gClut, 0, 256); | |
529 | } | |
530 | ||
531 | #if kMacOSXServer | |
532 | // Set the screen to Medium Blue | |
533 | CallMethod_5_0(screenIH, "fill-rectangle", 128, 0, 0, | |
534 | display->width, display->height); | |
535 | #else | |
536 | // Set the screen to Medium Grey | |
537 | CallMethod_5_0(screenIH, "fill-rectangle", | |
538 | LookUpCLUTIndex(0xF9, display->depth), | |
539 | 0, 0, display->width, display->height); | |
540 | #endif | |
541 | ||
542 | return 0; | |
543 | } | |
544 | ||
545 | ||
546 | static long NetLoadDrivers(void) | |
547 | { | |
548 | long ret, cnt, curDisplay; | |
549 | CICell screenPH; | |
550 | char fileSpec[512]; | |
551 | ||
552 | for (cnt = 0; cnt < kNumNetDrivers; cnt++) { | |
553 | ||
554 | // See if there is a display for this driver. | |
555 | for (curDisplay = 0; curDisplay < gNumDisplays; curDisplay++) { | |
556 | screenPH = gDisplays[curDisplay].screenPH; | |
557 | if (MatchThis(screenPH, gNetDriverMatchNames[cnt]) == 0) break; | |
558 | } | |
559 | ||
560 | if (curDisplay == gNumDisplays) continue; | |
561 | ||
562 | sprintf(fileSpec, "%s%sDrivers\\ppc\\IONDRV.config\\%s", | |
563 | gRootDir, | |
564 | (gBootFileType == kNetworkDeviceType) ? "" : "private\\", | |
565 | gNetDriverFileNames[cnt]); | |
566 | ||
567 | ret = LoadDisplayDriver(fileSpec); | |
568 | } | |
569 | ||
570 | return 0; | |
571 | } | |
572 | ||
573 | static long DiskLoadDrivers(void) | |
574 | { | |
575 | long ret, flags, index, time; | |
576 | char dirSpec[512], *name; | |
577 | ||
578 | index = 0; | |
579 | while (1) { | |
580 | sprintf(dirSpec, "%sprivate\\Drivers\\ppc\\IONDRV.config\\", gRootDir); | |
581 | ||
582 | ret = GetDirEntry(dirSpec, &index, &name, &flags, &time); | |
583 | if (ret == -1) break; | |
584 | ||
585 | if (flags != kFlatFileType) continue; | |
586 | ||
587 | strcat(dirSpec, name); | |
588 | ret = LoadDisplayDriver(dirSpec); | |
589 | ||
590 | if (ret == -1) return -1; | |
591 | } | |
592 | ||
593 | return 0; | |
594 | } | |
595 | ||
596 | static long LoadDisplayDriver(char *fileSpec) | |
597 | { | |
598 | char *pef, *currentPef, *buffer; | |
599 | long pefLen, currentPefLen, ndrvUsed; | |
600 | long curDisplay; | |
601 | char descripName[] = " TheDriverDescription"; | |
602 | long err; | |
603 | DriverDescription descrip; | |
604 | DriverDescription curDesc; | |
605 | char matchName[40]; | |
606 | unsigned long newVersion; | |
607 | unsigned long curVersion; | |
608 | CICell screenPH; | |
609 | ||
610 | pefLen = LoadFile(fileSpec); | |
611 | if (pefLen == -1) return -1; | |
612 | if (pefLen == 0) return 0; | |
613 | ||
614 | pef = (char *)kLoadAddr; | |
615 | ||
616 | descripName[0] = strlen(descripName + 1); | |
617 | err = GetSymbolFromPEF(descripName, pef, &descrip, sizeof(descrip)); | |
618 | if(err != 0) { | |
619 | printf("\nGetSymbolFromPEF returns %d\n",err); | |
620 | return -1; | |
621 | } | |
622 | if((descrip.driverDescSignature != kTheDescriptionSignature) || | |
623 | (descrip.driverDescVersion != kInitialDriverDescriptor)) | |
624 | return 0; | |
625 | ||
626 | strncpy(matchName, descrip.driverType.nameInfoStr + 1, | |
627 | descrip.driverType.nameInfoStr[0]); | |
628 | newVersion = descrip.driverType.version; | |
629 | ||
630 | if((newVersion & 0xffff) == 0x8000) // final stage, release rev | |
631 | newVersion |= 0xff; | |
632 | ||
633 | ndrvUsed = 0; | |
634 | buffer = (char *)malloc(pefLen); | |
635 | if (buffer == NULL) { | |
636 | printf("No space for the NDRV\n"); | |
637 | return -1; | |
638 | } | |
639 | bcopy(pef, buffer, pefLen); | |
640 | ||
641 | for (curDisplay = 0; curDisplay < gNumDisplays; curDisplay++) { | |
642 | screenPH = gDisplays[curDisplay].screenPH; | |
643 | ||
644 | if (MatchThis(screenPH, matchName) != 0) continue; | |
645 | ||
646 | err = GetPackageProperty(screenPH, "driver,AAPL,MacOS,PowerPC", | |
647 | ¤tPef, ¤tPefLen); | |
648 | ||
649 | if (err == 0) { | |
650 | err = GetSymbolFromPEF(descripName,currentPef,&curDesc,sizeof(curDesc)); | |
651 | if (err != 0) { | |
652 | if((curDesc.driverDescSignature == kTheDescriptionSignature) && | |
653 | (curDesc.driverDescVersion == kInitialDriverDescriptor)) { | |
654 | curVersion = curDesc.driverType.version; | |
655 | if((curVersion & 0xffff) == 0x8000) // final stage, release rev | |
656 | curVersion |= 0xff; | |
657 | ||
658 | if( newVersion <= curVersion) | |
659 | pefLen = 0; | |
660 | } | |
661 | } | |
662 | } | |
663 | ||
664 | if(pefLen == 0) continue; | |
665 | ||
666 | printf("Installing patch driver\n"); | |
667 | ||
668 | SetProp(screenPH, "driver,AAPL,MacOS,PowerPC", buffer, pefLen); | |
669 | ndrvUsed = 1; | |
670 | } | |
671 | ||
672 | if (ndrvUsed == 0) free(buffer); | |
673 | ||
674 | return 0; | |
675 | } | |
676 | ||
677 | ||
678 | static long LookUpCLUTIndex(long index, long depth) | |
679 | { | |
680 | long result, red, green, blue; | |
681 | ||
682 | red = gClut[index * 3 + 0]; | |
683 | green = gClut[index * 3 + 1]; | |
684 | blue = gClut[index * 3 + 2]; | |
685 | ||
686 | switch (depth) { | |
687 | case 16 : | |
688 | result = ((red & 0xF8) << 7)|((green & 0xF8) << 2)|((blue & 0xF8) >> 3); | |
689 | break; | |
690 | ||
691 | case 32 : | |
692 | result = (red << 16) | (green << 8) | blue; | |
693 | break; | |
694 | ||
695 | default : | |
696 | result = index; | |
697 | break; | |
698 | } | |
699 | ||
700 | return result; | |
701 | } |