22 #include "modules/Module.h" 23 #include "modules/system/config/Config.h" 24 #include "pedigree/kernel/BootstrapInfo.h" 25 #include "pedigree/kernel/LockGuard.h" 26 #include "pedigree/kernel/Log.h" 27 #include "pedigree/kernel/Service.h" 28 #include "pedigree/kernel/ServiceFeatures.h" 29 #include "pedigree/kernel/ServiceManager.h" 30 #include "pedigree/kernel/core/BootIO.h" 31 #include "pedigree/kernel/graphics/Graphics.h" 32 #include "pedigree/kernel/graphics/GraphicsService.h" 33 #include "pedigree/kernel/machine/Display.h" 34 #include "pedigree/kernel/machine/Framebuffer.h" 35 #include "pedigree/kernel/machine/InputManager.h" 36 #include "pedigree/kernel/process/Mutex.h" 37 #include "pedigree/kernel/processor/types.h" 38 #include "pedigree/kernel/utilities/Cord.h" 39 #include "pedigree/kernel/utilities/StaticString.h" 40 #include "pedigree/kernel/utilities/String.h" 41 #include "pedigree/kernel/utilities/Vector.h" 42 #include "pedigree/kernel/utilities/assert.h" 43 #include "pedigree/kernel/utilities/utility.h" 47 static uint8_t *g_pBuffer = 0;
49 static size_t g_Width = 0;
50 static size_t g_Height = 0;
52 static uint32_t g_BackgroundColour = 0x000000;
53 static uint32_t g_ForegroundColour = 0xFFFFFF;
54 static uint32_t g_ProgressBorderColour = 0x965000;
55 static uint32_t g_ProgressColour = 0x966400;
57 static Graphics::PixelFormat g_ColorFormat = Graphics::Bits24_Rgb;
59 static size_t g_ProgressX, g_ProgressY;
60 static size_t g_ProgressW, g_ProgressH;
61 static size_t g_LogBoxX, g_LogBoxY;
62 static size_t g_LogX, g_LogY;
63 static size_t g_LogW, g_LogH;
67 static size_t g_Previous = 0;
68 static bool g_LogMode =
false;
70 static bool g_NoGraphics =
false;
72 static Mutex g_PrintLock(
false);
74 static void printChar(
char c,
size_t x,
size_t y)
82 g_pFont, 0, c * FONT_HEIGHT, x, y, FONT_WIDTH, FONT_HEIGHT);
85 static void printChar(
char c)
96 g_LogX = (g_LogX + 8) & ~7;
104 g_pFramebuffer->
redraw(g_LogBoxX, g_LogBoxY, g_LogW, g_LogH,
true);
108 g_pFramebuffer->
blit(
109 g_pFont, 0, c * FONT_HEIGHT, g_LogBoxX + (g_LogX * FONT_WIDTH),
110 g_LogBoxY + (g_LogY * FONT_HEIGHT), FONT_WIDTH, FONT_HEIGHT);
114 if (g_LogX >= g_LogW / FONT_WIDTH)
119 g_pFramebuffer->
redraw(g_LogBoxX, g_LogBoxY, g_LogW, g_LogH,
true);
123 if (g_LogY >= (g_LogH / FONT_HEIGHT))
126 size_t diff = g_LogY - (g_LogH / FONT_HEIGHT) + 1;
129 g_pFramebuffer->
copy(
130 g_LogBoxX, g_LogBoxY + (diff * FONT_HEIGHT), g_LogBoxX, g_LogBoxY,
131 g_LogW - g_LogBoxX, ((g_LogH / FONT_HEIGHT) - diff) * FONT_HEIGHT);
132 g_pFramebuffer->
rect(
134 g_LogBoxY + ((g_LogH / FONT_HEIGHT) - diff) * FONT_HEIGHT,
135 g_LogW - g_LogBoxX, diff * FONT_HEIGHT, g_BackgroundColour,
138 g_LogY = (g_LogH / FONT_HEIGHT) - diff;
140 g_pFramebuffer->
redraw(g_LogBoxX, g_LogBoxY, g_LogW, g_LogH,
true);
144 static void printString(
const char *str,
size_t len=0)
150 len = StringLength(str);
155 for (
size_t i = 0; i < len; i++)
166 if (s.length() >= 79)
175 else if (str[1] ==
'E' || str[1] ==
'F')
177 else if (str[1] ==
'D')
178 c = BootIO::DarkGrey;
180 bootIO.
write(s, c, BootIO::Black);
185 static void printStringAt(
const char *str,
size_t x,
size_t y)
188 for (
size_t i = 0; i < StringLength(str); i++)
190 printChar(str[i], x, y);
195 static void centerStringAt(
const char *str,
size_t midX,
size_t midY)
198 size_t stringWidth = StringLength(str) * FONT_WIDTH;
199 size_t stringHeight = FONT_HEIGHT;
201 size_t x = midX - (stringWidth / 2);
202 size_t y = midY - (stringHeight / 2);
203 printStringAt(str, x, y);
219 printString(cord.toString(), cord.length());
225 StreamingScreenLogger::~StreamingScreenLogger() =
default;
234 uint64_t key = note.data.key.key;
247 g_LogY += (g_LogBoxY / FONT_HEIGHT);
248 g_LogX = (g_LogBoxX / FONT_WIDTH);
249 g_LogBoxX = g_LogBoxY = 0;
256 static void progress(
const char *text)
261 if (g_BootProgressTotal == 0)
264 bool bFinished =
false;
265 if ((g_BootProgressCurrent + 1) >= g_BootProgressTotal)
279 if (g_LogMode && (g_LogH == g_Height))
287 for (
size_t i = 0; i < (80 / 2) - 11; ++i)
289 bootIO.
write(s, BootIO::Black, BootIO::Black);
294 size_t pos = (20 * g_BootProgressCurrent) / g_BootProgressTotal;
295 for (
size_t i = 0; i < 20; ++i)
303 bootIO.
write(s, BootIO::White, BootIO::Black);
305 else if (g_pFramebuffer)
307 size_t w = (g_ProgressW * g_BootProgressCurrent) / g_BootProgressTotal;
308 if (g_Previous <= g_BootProgressCurrent)
309 g_pFramebuffer->
rect(
310 g_ProgressX, g_ProgressY, w, g_ProgressH, g_ProgressColour,
313 g_pFramebuffer->
rect(
314 g_ProgressX + w, g_ProgressY, g_ProgressW - w, g_ProgressH,
315 g_BackgroundColour, g_ColorFormat);
316 g_Previous = g_BootProgressCurrent;
320 buf,
"%d%%", ((g_BootProgressCurrent * 100) / g_BootProgressTotal));
322 buf, g_ProgressX + (g_ProgressW / 2), g_ProgressY - FONT_HEIGHT);
325 g_ProgressX, g_ProgressY - (FONT_HEIGHT * 2), g_ProgressW,
326 g_ProgressH + (FONT_HEIGHT * 2),
true);
331 NOTICE(
"splash: destroying font pixel buffer");
333 NOTICE(
"splash: destroying font heap buffer");
337 NOTICE(
"splash: destroying framebuffer");
338 Graphics::destroyFramebuffer(g_pFramebuffer);
339 NOTICE(
"splash: destroyed framebuffer");
343 g_BootProgressUpdate = 0;
348 static void getColor(
const char *colorName, uint32_t &color)
354 sQuery +=
"select r,g,b from 'colour_scheme' where name='";
364 ERROR(
"Splash: Error looking up '" << colorName <<
"' colour.");
371 "Splash: Error looking up '" 372 << colorName <<
"' colour: " << pResult->
errorMessage());
378 color = Graphics::createRgb(
387 getDesiredMode(
size_t &modeWidth,
size_t &modeHeight,
size_t &modeBpp)
391 "select width,height,bpp from 'desired_display_mode';");
404 modeWidth = pResult->
getNum(0,
"width");
405 modeHeight = pResult->
getNum(0,
"height");
406 modeBpp = pResult->
getNum(0,
"bpp");
412 static bool handleNoSplash()
416 const String title(
"Pedigree is Loading...\n");
422 for (
size_t i = 0; i < 2; ++i)
424 bootIO.
write(s, BootIO::Black, BootIO::Black);
429 for (
size_t i = 0; i < (80 / 2) - (title.length() / 2); ++i)
431 bootIO.
write(s, BootIO::Black, BootIO::Black);
436 bootIO.
write(s, BootIO::White, BootIO::Black);
438 g_BootProgressUpdate = &progress;
443 static bool handleSplash()
445 g_NoGraphics =
false;
447 getColor(
"splash-background", g_BackgroundColour);
448 getColor(
"splash-foreground", g_ForegroundColour);
449 getColor(
"border", g_ProgressBorderColour);
450 getColor(
"fill", g_ProgressColour);
453 g_GraphicsParams.wantTextMode =
false;
462 bool bSuccess =
false;
465 bSuccess = pService->
serve(
467 reinterpret_cast<void *>(&g_GraphicsParams),
468 sizeof(g_GraphicsParams));
470 if (!(bSuccess && g_GraphicsParams.providerFound))
472 NOTICE(
"splash: this system does not support graphics, using fallback " 474 return handleNoSplash();
477 Display *pDisplay = g_GraphicsParams.providerResult.pDisplay;
480 size_t nDesiredWidth = 0, nDesiredHeight = 0, nDesiredBpp = 0;
481 getDesiredMode(nDesiredWidth, nDesiredHeight, nDesiredBpp);
484 if (!(nDesiredWidth && nDesiredHeight && nDesiredBpp) ||
485 !pDisplay->
setScreenMode(nDesiredWidth, nDesiredHeight, nDesiredBpp))
487 bool bModeFound =
true;
490 NOTICE(
"splash: Falling back to 1024x768x24");
494 NOTICE(
"splash: Falling back to 800x600x24");
498 NOTICE(
"splash: Falling back to 640x480x24");
509 NOTICE(
"splash: Falling back to 1024x768x16");
513 NOTICE(
"splash: Falling back to 800x600x16");
517 NOTICE(
"splash: Falling back to 640x480x16");
520 ERROR(
"splash: Couldn't find a suitable display mode " 521 "for this system (tried: 1024x768, 800x600, " 532 NOTICE(
"splash: this system does not support graphics, using fallback " 534 return handleNoSplash();
538 g_GraphicsParams.providerResult.pFramebuffer;
540 g_Width = pParentFramebuffer->getWidth();
541 g_Height = pParentFramebuffer->getHeight();
543 g_pFramebuffer = Graphics::createFramebuffer(
544 pParentFramebuffer, 0, 0, g_Width, g_Height);
545 g_ColorFormat = g_pFramebuffer->getFormat();
547 g_pFramebuffer->
rect(
548 0, 0, g_Width, g_Height, g_BackgroundColour, g_ColorFormat);
551 uint8_t *data = header_data;
552 g_pBuffer =
new uint8_t[width * height * 3];
553 for (
size_t i = 0; i < (width * height); i++)
554 HEADER_PIXEL(data, &g_pBuffer[i * 3]);
556 size_t origx = (g_Width - width) / 2;
557 size_t origy = (g_Height - height) / 3;
559 g_pFramebuffer->
draw(
560 g_pBuffer, 0, 0, origx, origy, width, height, Graphics::Bits24_Bgr);
565 g_pBuffer =
new uint8_t[(FONT_WIDTH * FONT_HEIGHT * 3) * 256];
566 ByteSet(g_pBuffer, 0, (FONT_WIDTH * FONT_HEIGHT * 3) * 256);
570 for (
size_t character = 0; character < 255; character++)
573 for (
size_t row = 0; row < FONT_HEIGHT; row++)
576 for (
size_t col = 0; col <= FONT_WIDTH; col++)
579 size_t fontRow = (character * FONT_HEIGHT) + row;
580 if (font_data[fontRow] & (1 << (FONT_WIDTH - col)))
584 size_t bytesPerPixel = 3;
585 size_t bytesPerLine = FONT_WIDTH * bytesPerPixel;
587 (fontRow * bytesPerLine) + (col * bytesPerPixel);
588 size_t bufferOffset = pixelOffset;
590 uint32_t *p =
reinterpret_cast<uint32_t *
>(
591 adjust_pointer(g_pBuffer, bufferOffset));
592 *p = g_ForegroundColour;
599 g_pBuffer, Graphics::Bits24_Rgb, FONT_WIDTH, FONT_HEIGHT * 256);
601 g_ProgressX = (g_Width / 2) - 200;
603 g_ProgressY = (g_Height / 3) * 2;
607 g_LogBoxY = (g_Height / 4) * 3;
609 g_LogH = g_Height - g_LogBoxY;
614 "Please wait, Pedigree is loading...", g_Width / 2,
615 g_ProgressY - (FONT_HEIGHT * 3));
620 "< Kernel Log >", g_LogW / 2,
621 g_LogBoxY - 2 - (FONT_HEIGHT / 2) - FONT_HEIGHT);
623 "(you can push ESCAPE to view the kernel log, and again to make the " 624 "log fill the screen)",
625 g_LogW / 2, g_LogBoxY - 2 - (FONT_HEIGHT / 2));
630 g_pFramebuffer->
rect(
631 g_ProgressX - 2, g_ProgressY - 2, g_ProgressW + 4, g_ProgressH + 4,
632 g_ProgressBorderColour, g_ColorFormat);
633 g_pFramebuffer->
rect(
634 g_ProgressX - 1, g_ProgressY - 1, g_ProgressW + 2, g_ProgressH + 2,
635 g_BackgroundColour, g_ColorFormat);
637 g_pFramebuffer->
redraw(0, 0, g_Width, g_Height,
true);
641 g_BootProgressUpdate = &progress;
654 g_NoGraphics =
false;
655 char *cmdline = g_pBootstrapInfo->getCommandLine();
659 for (
auto it = cmds.
begin(); it != cmds.
end(); it++)
672 return handleNoSplash();
676 return handleSplash();
680 static void destroy()
693 g_BootProgressUpdate = 0;
696 MODULE_INFO(
"splash", &init, &destroy,
"config");
699 MODULE_OPTIONAL_DEPENDS(
"gfx-deps");
virtual void copy(size_t srcx, size_t srcy, size_t destx, size_t desty, size_t w, size_t h, bool bLowestCall=true)
virtual void blit(Graphics::Buffer *pBuffer, size_t srcx, size_t srcy, size_t destx, size_t desty, size_t width, size_t height, bool bLowestCall=true)
A vector / dynamic array.
EXPORTED_PUBLIC void write(T &str, Colour foreColour, Colour backColour)
virtual void destroyBuffer(Graphics::Buffer *pBuffer)
virtual bool provides(Type service)
virtual void rect(size_t x, size_t y, size_t width, size_t height, uint32_t colour, Graphics::PixelFormat format=Graphics::Bits32_Argb, bool bLowestCall=true)
void redraw(size_t x=~0UL, size_t y=~0UL, size_t w=~0UL, size_t h=~0UL, bool bChild=false)
size_t getNum(size_t row, size_t col)
Returns the value in column 'col' of the result, in number form.
Result * query(const char *sql)
bool succeeded()
Returns true if the result is valid, false if there was an error.
EXPORTED_PUBLIC void removeCallback(LogCallback *pCallback)
virtual void draw(void *pBuffer, size_t srcx, size_t srcy, size_t destx, size_t desty, size_t width, size_t height, Graphics::PixelFormat format=Graphics::Bits32_Argb, bool bLowestCall=true)
Abstracts the system's framebuffer offering.
static EXPORTED_PUBLIC Log & instance()
Service * getService(const String &serviceName)
virtual bool serve(ServiceFeatures::Type type, void *pData, size_t dataLen)=0
std::string errorMessage(size_t buffSz=256)
Returns the error message.
ServiceFeatures * enumerateOperations(const String &serviceName)
virtual Graphics::Buffer * createBuffer(const void *srcData, Graphics::PixelFormat srcFormat, size_t width, size_t height, uint32_t *pPalette=0)
EXPORTED_PUBLIC void installCallback(LogCallback *pCallback, bool bSkipBacklog=false)
void callback(const LogCord &cord)
virtual bool setScreenMode(ScreenMode sm)