]> git.saurik.com Git - apple/bootx.git/blobdiff - bootx.tproj/sl.subproj/display.c
BootX-75.tar.gz
[apple/bootx.git] / bootx.tproj / sl.subproj / display.c
index a4bc44bf3e18ecc6ba4814c6dd76a65adedfc607..3d48faee9dc31075785499245bf10cba1e7494eb 100644 (file)
@@ -28,6 +28,7 @@
  */
 
 #include <sl.h>
+#include <IOKit/IOHibernatePrivate.h>
 
 #include "clut.h"
 #include "appleboot.h"
@@ -48,10 +49,10 @@ struct DisplayInfo {
 typedef struct DisplayInfo DisplayInfo, *DisplayInfoPtr;
 
 
-static long FindDisplays(void);
-static long OpenDisplays(void);
-static long OpenDisplay(long displayNum);
-static long InitDisplay(long displayNum);
+static long FindDisplays();
+static long OpenDisplays(int fill);
+static long OpenDisplay(long displayNum, int fill);
+static long InitDisplay(long displayNum, int fill);
 static long LookUpCLUTIndex(long index, long depth);
 
 static long        gNumDisplays;
@@ -64,14 +65,22 @@ static unsigned char *gFailedBoot;
 
 // Public Functions
 
-long InitDisplays(void)
+long InitDisplays(int fill)
 {
   FindDisplays();
-  OpenDisplays();
+  OpenDisplays(fill);
   
   return 0;
 }
 
+void CloseDisplays(void)
+{
+  int cnt;
+  for (cnt = 0; cnt < gNumDisplays; cnt++) {
+    if (gDisplays[cnt].screenIH)
+      Close(gDisplays[cnt].screenIH);
+  }
+}
 
 long DrawSplashScreen(long stage)
 {
@@ -185,6 +194,140 @@ long DrawSplashScreen(long stage)
   return 0;
 }
 
+DECLARE_IOHIBERNATEPROGRESSALPHA
+
+void SplashPreview(void *src, uint8_t * saveunder, uint32_t savelen)
+{
+  DisplayInfoPtr display;
+  uint8_t *  screen;
+  uint32_t   rowBytes, pixelShift;
+  uint32_t   x, y;
+  int32_t    blob;
+  uint32_t   alpha, in, color, result;
+  uint8_t *  out;
+  uint32_t   saveindex[kIOHibernateProgressCount] = { 0 };
+  
+  if (InitDisplays(0) != 0)  return;
+  if (gMainDisplayNum == -1) return;
+
+  display = &gDisplays[gMainDisplayNum];
+  screen = (uint8_t *) display->address;
+  rowBytes = display->linebytes;
+  if (!src || !DecompressData(src, (void *) screen, 
+                    display->width, display->height,
+                    display->depth >> 3, rowBytes))
+  {
+    // Set the screen to 75% grey.
+    CallMethod(5, 0, display->screenIH, "fill-rectangle",
+            LookUpCLUTIndex(0x01, display->depth),
+            0, 0, display->width, display->height);
+    DrawSplashScreen(0);
+  }
+
+  pixelShift = display->depth >> 4;
+  if (pixelShift < 1) return;
+
+  screen += ((display->width 
+          - kIOHibernateProgressCount * (kIOHibernateProgressWidth + kIOHibernateProgressSpacing)) << (pixelShift - 1))
+              + (display->height - kIOHibernateProgressOriginY - kIOHibernateProgressHeight) * rowBytes;
+  
+  for (y = 0; y < kIOHibernateProgressHeight; y++)
+  {
+    out = screen + y * rowBytes;
+    for (blob = 0; blob < kIOHibernateProgressCount; blob++)
+    {
+      color = blob ? kIOHibernateProgressDarkGray : kIOHibernateProgressMidGray;
+      for (x = 0; x < kIOHibernateProgressWidth; x++)
+      {
+        alpha  = gIOHibernateProgressAlpha[y][x];
+        result = color;
+        if (alpha)
+        {
+          if (0xff != alpha)
+          {
+            if (1 == pixelShift)
+            {
+              in = *((uint16_t *)out) & 0x1f;  // 16
+              in = (in << 3) | (in >> 2);
+            }
+            else
+                in = *((uint32_t *)out) & 0xff;        // 32
+            saveunder[blob * kIOHibernateProgressSaveUnderSize + saveindex[blob]++] = in;
+            result = ((255 - alpha) * in + alpha * result + 0xff) >> 8;
+          }
+          if (1 == pixelShift)
+          {
+            result >>= 3;
+            *((uint16_t *)out) = (result << 10) | (result << 5) | result;      // 16
+          }
+          else
+            *((uint32_t *)out) = (result << 16) | (result << 8) | result;      // 32
+        }
+        out += (1 << pixelShift);
+      }
+      out += (kIOHibernateProgressSpacing << pixelShift);
+    }
+  }
+}
+
+void SplashProgress(uint8_t * saveunder, int32_t firstBlob, int32_t select)
+{
+  DisplayInfoPtr display;
+  uint8_t * screen;
+  uint32_t  rowBytes, pixelShift;
+  uint32_t  x, y;
+  int32_t   blob, lastBlob;
+  uint32_t  alpha, in, color, result;
+  uint8_t * out;
+  uint32_t  saveindex[kIOHibernateProgressCount] = { 0 };
+
+  if (gMainDisplayNum == -1) return;
+
+  display = &gDisplays[gMainDisplayNum];
+  pixelShift = display->depth >> 4;
+  if (pixelShift < 1) return;
+  screen = (uint8_t *) display->address;
+  rowBytes = display->linebytes;
+
+  screen += ((display->width 
+          - kIOHibernateProgressCount * (kIOHibernateProgressWidth + kIOHibernateProgressSpacing)) << (pixelShift - 1))
+              + (display->height - kIOHibernateProgressOriginY - kIOHibernateProgressHeight) * rowBytes;
+
+  lastBlob  = (select < kIOHibernateProgressCount) ? select : (kIOHibernateProgressCount - 1);
+
+  screen += (firstBlob * (kIOHibernateProgressWidth + kIOHibernateProgressSpacing)) << pixelShift;
+
+  for (y = 0; y < kIOHibernateProgressHeight; y++)
+  {
+    out = screen + y * rowBytes;
+    for (blob = firstBlob; blob <= lastBlob; blob++)
+    {
+      color = (blob < select) ? kIOHibernateProgressLightGray : kIOHibernateProgressMidGray;
+      for (x = 0; x < kIOHibernateProgressWidth; x++)
+      {
+        alpha  = gIOHibernateProgressAlpha[y][x];
+        result = color;
+        if (alpha)
+        {
+          if (0xff != alpha)
+          {
+            in = saveunder[blob * kIOHibernateProgressSaveUnderSize + saveindex[blob]++];
+            result = ((255 - alpha) * in + alpha * result + 0xff) / 255;
+          }
+          if (1 == pixelShift)
+          {
+            result >>= 3;
+            *((uint16_t *)out) = (result << 10) | (result << 5) | result;      // 16
+          }
+          else
+            *((uint32_t *)out) = (result << 16) | (result << 8) | result;      // 32
+        }
+        out += (1 << pixelShift);
+      }
+      out += (kIOHibernateProgressSpacing << pixelShift);
+    }
+  }
+}
 
 long DrawFailedBootPicture(void)
 {
@@ -231,7 +374,7 @@ long DrawFailedBootPicture(void)
 }
 
 
-void GetMainScreenPH(Boot_Video_Ptr video)
+void GetMainScreenPH(Boot_Video_Ptr video, int setProperties)
 {
   DisplayInfoPtr display;
   long           address, size;
@@ -252,9 +395,11 @@ void GetMainScreenPH(Boot_Video_Ptr video)
     video->v_height = display->height;
     video->v_depth = display->depth;
   }
-  
-  // Allocate memory and a range for the CLUT.
+
+  if (!setProperties) return;
+
   size = 256 * 3;
+  // Allocate memory and a range for the CLUT.
   address = AllocateKernelMemory(size);
   AllocateMemoryRange("BootCLUT", address, size);
   bcopy((char *)gClut, (char *)address, size);
@@ -293,6 +438,7 @@ static long FindDisplays(void)
   // Find the main screen using the screen alias or chaos/control.
   gMainDisplayNum = -1;
   screenPH = FindDevice("screen");
+  gDisplays[gNumDisplays++].screenPH = screenPH;
   if (screenPH == -1) screenPH = controlPH;
   for (cnt = 0; cnt < gNumDisplays; cnt++)
     if (gDisplays[cnt].screenPH == screenPH) gMainDisplayNum = cnt;
@@ -301,16 +447,16 @@ static long FindDisplays(void)
 }
 
 
-static long OpenDisplays(void)
+static long OpenDisplays(int fill)
 {
   long cnt;
   
   // Open the main screen or
   // look for a main screen if we don't have one.
-  if ((gMainDisplayNum == -1) || !OpenDisplay(gMainDisplayNum)) {
+  if ((gMainDisplayNum == -1) || !OpenDisplay(gMainDisplayNum, fill)) {
     gMainDisplayNum = -1;
     for (cnt = 0; cnt < gNumDisplays; cnt++) {
-      if (OpenDisplay(cnt)) {
+      if (OpenDisplay(cnt, fill)) {
        gMainDisplayNum = cnt;
        break;
       }
@@ -320,7 +466,7 @@ static long OpenDisplays(void)
   // Open the rest of the displays
   if (gOFVersion >= kOFVersion3x) {
     for (cnt = 0; cnt < gNumDisplays; cnt++) {
-      OpenDisplay(cnt);
+      OpenDisplay(cnt, 1);
     }
   }
   
@@ -328,7 +474,7 @@ static long OpenDisplays(void)
 }
 
 
-static long OpenDisplay(long displayNum)
+static long OpenDisplay(long displayNum, int fill)
 {
   char   screenPath[258], displayType[32];
   CICell screenPH, screenIH;
@@ -377,13 +523,13 @@ static long OpenDisplay(long displayNum)
   gDisplays[displayNum].screenIH = screenIH;
   
   // Initialize the display.
-  if (screenIH != 0) InitDisplay(displayNum);
+  if (screenIH != 0) InitDisplay(displayNum, fill);
   
   return screenIH != 0;
 }
 
 
-static long InitDisplay(long displayNum)
+static long InitDisplay(long displayNum, int fill)
 {
   DisplayInfoPtr display = &gDisplays[displayNum];
   CICell         screenPH = display->screenPH;
@@ -446,8 +592,9 @@ static long InitDisplay(long displayNum)
     CallMethod(3, 0, screenIH, "set-colors", (long)gClut, 0, 256);
   }
   
-  // Set the screen to 75% grey.
-  CallMethod(5, 0, screenIH, "fill-rectangle",
+  if (fill)
+    // Set the screen to 75% grey.
+    CallMethod(5, 0, screenIH, "fill-rectangle",
             LookUpCLUTIndex(0x01, display->depth),
             0, 0, display->width, display->height);