mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-08-11 06:14:18 +00:00
.github
.vscode
Architecture
Core
Execute
FileSystem
Files
GUI
GUITools.cpp
GraphicalUserInterface.cpp
Icons.cpp
WidgetEvents.cpp
Widgets.cpp
Window.cpp
WindowEvents.cpp
icons.hpp
Library
Network
Profiling
Recovery
SystemCalls
Tasking
Tests
include
.gitignore
DAPI.hpp
Doxyfile
Fex.hpp
KConfig.cpp
KThread.cpp
Kernel.cpp
LICENSE
Makefile
README.md
dump.sh
ipc.h
kernel.h
syscalls.h
650 lines
25 KiB
C++
650 lines
25 KiB
C++
#include <gui.hpp>
|
|
#include <driver.hpp>
|
|
#include <task.hpp>
|
|
#include <debug.h>
|
|
|
|
#include "icons.hpp"
|
|
#include "../kernel.h"
|
|
#include "../DAPI.hpp"
|
|
#include "../Fex.hpp"
|
|
|
|
extern uintptr_t _binary_Files_tamsyn_font_1_11_Tamsyn7x14r_psf_start;
|
|
extern uintptr_t _binary_Files_tamsyn_font_1_11_Tamsyn7x14r_psf_end;
|
|
extern uintptr_t _binary_Files_tamsyn_font_1_11_Tamsyn7x14r_psf_size;
|
|
|
|
#ifdef DEBUG
|
|
uint64_t FIi = 0, PDi = 0, PWi = 0, PWWi = 0, PCi = 0, mmi = 0;
|
|
#endif
|
|
|
|
namespace GraphicalUserInterface
|
|
{
|
|
void GUI::FetchInputs()
|
|
{
|
|
MouseData Mouse;
|
|
bool FoundMouseDriver = false;
|
|
if (likely(DriverManager->GetDrivers().size() > 0))
|
|
{
|
|
foreach (auto Driver in DriverManager->GetDrivers())
|
|
{
|
|
if (((FexExtended *)((uintptr_t)Driver.Address + EXTENDED_SECTION_ADDRESS))->Driver.Type == FexDriverType::FexDriverType_Input &&
|
|
((FexExtended *)((uintptr_t)Driver.Address + EXTENDED_SECTION_ADDRESS))->Driver.TypeFlags & FexDriverInputTypes::FexDriverInputTypes_Mouse)
|
|
{
|
|
#ifdef DEBUG
|
|
static int once = 0;
|
|
if (!once++)
|
|
debug("Found mouse driver %ld", Driver.DriverUID);
|
|
#endif
|
|
KernelCallback callback;
|
|
callback.Reason = FetchReason;
|
|
DriverManager->IOCB(Driver.DriverUID, (void *)&callback);
|
|
Mouse.X = callback.InputCallback.Mouse.X;
|
|
Mouse.Y = callback.InputCallback.Mouse.Y;
|
|
Mouse.Z = callback.InputCallback.Mouse.Z;
|
|
Mouse.Left = callback.InputCallback.Mouse.Buttons.Left;
|
|
Mouse.Right = callback.InputCallback.Mouse.Buttons.Right;
|
|
Mouse.Middle = callback.InputCallback.Mouse.Buttons.Middle;
|
|
FoundMouseDriver = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (unlikely(!FoundMouseDriver))
|
|
{
|
|
debug("No mouse driver found.");
|
|
Mouse.X = Display->GetBuffer(200)->Width / 2;
|
|
Mouse.Y = Display->GetBuffer(200)->Height / 2;
|
|
Mouse.Z = 0;
|
|
Mouse.Left = false;
|
|
Mouse.Right = false;
|
|
Mouse.Middle = false;
|
|
}
|
|
|
|
Event eTemplate;
|
|
memset(&eTemplate, 0, sizeof(Event));
|
|
foreach (auto wnd in this->Windows)
|
|
{
|
|
/* On mouse down event */
|
|
if (unlikely((!MouseArray[1].Left || !MouseArray[1].Right || !MouseArray[1].Middle) &&
|
|
(Mouse.Left || Mouse.Right || Mouse.Middle)))
|
|
{
|
|
eTemplate.MouseDown.X = Mouse.X;
|
|
eTemplate.MouseDown.Y = Mouse.Y;
|
|
eTemplate.MouseDown.Left = Mouse.Left;
|
|
eTemplate.MouseDown.Right = Mouse.Right;
|
|
eTemplate.MouseDown.Middle = Mouse.Middle;
|
|
wnd->OnMouseDown(&eTemplate);
|
|
}
|
|
|
|
/* On mouse up event */
|
|
if (unlikely((MouseArray[1].Left || MouseArray[1].Right || MouseArray[1].Middle) &&
|
|
(!Mouse.Left || !Mouse.Right || !Mouse.Middle)))
|
|
{
|
|
eTemplate.MouseUp.X = Mouse.X;
|
|
eTemplate.MouseUp.Y = Mouse.Y;
|
|
eTemplate.MouseUp.Left = Mouse.Left;
|
|
eTemplate.MouseUp.Right = Mouse.Right;
|
|
eTemplate.MouseUp.Middle = Mouse.Middle;
|
|
wnd->OnMouseUp(&eTemplate);
|
|
}
|
|
|
|
static int Idle = 0;
|
|
|
|
if (likely(Mouse.X != MouseArray[1].X || Mouse.Y != MouseArray[1].Y))
|
|
{
|
|
Idle = 0;
|
|
Rect TopBarPos = wnd->GetPosition();
|
|
TopBarPos.Top -= 20;
|
|
TopBarPos.Height = 20;
|
|
TopBarPos.Width -= 60; /* buttons */
|
|
if (unlikely(TopBarPos.Top < 0))
|
|
{
|
|
TopBarPos.Top = 0;
|
|
wnd->GetPositionPtr()->Top = 20;
|
|
}
|
|
|
|
Rect ResizeHintPos = wnd->GetPosition();
|
|
ResizeHintPos.Left += ResizeHintPos.Width - 20;
|
|
ResizeHintPos.Top += ResizeHintPos.Height - 20;
|
|
ResizeHintPos.Width = 20;
|
|
ResizeHintPos.Height = 20;
|
|
|
|
if (unlikely(TopBarPos.Contains(Mouse.X, Mouse.Y) ||
|
|
TopBarPos.Contains(MouseArray[0].X, MouseArray[0].Y) ||
|
|
TopBarPos.Contains(MouseArray[1].X, MouseArray[1].Y)))
|
|
{
|
|
if (likely(Mouse.Left))
|
|
{
|
|
if (likely(MouseArray[1].Left))
|
|
{
|
|
wnd->GetPositionPtr()->Left += Mouse.X - MouseArray[0].X;
|
|
wnd->GetPositionPtr()->Top += Mouse.Y - MouseArray[0].Y;
|
|
OverlayBufferRepaint = true;
|
|
OverlayFullRepaint = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (ResizeHintPos.Contains(Mouse.X, Mouse.Y) ||
|
|
ResizeHintPos.Contains(MouseArray[0].X, MouseArray[0].Y) ||
|
|
ResizeHintPos.Contains(MouseArray[1].X, MouseArray[1].Y))
|
|
{
|
|
if (Mouse.Left)
|
|
{
|
|
if (MouseArray[1].Left)
|
|
{
|
|
wnd->GetPositionPtr()->Width += Mouse.X - MouseArray[0].X;
|
|
wnd->GetPositionPtr()->Height += Mouse.Y - MouseArray[0].Y;
|
|
|
|
if (wnd->GetPositionPtr()->Width < 200)
|
|
{
|
|
wnd->GetPositionPtr()->Width = 200;
|
|
Mouse.X = MouseArray[0].X;
|
|
}
|
|
|
|
if (wnd->GetPositionPtr()->Height < 100)
|
|
{
|
|
wnd->GetPositionPtr()->Height = 100;
|
|
Mouse.Y = MouseArray[0].Y;
|
|
}
|
|
|
|
OverlayBufferRepaint = true;
|
|
OverlayFullRepaint = true;
|
|
eTemplate.Resize.Width = wnd->GetPosition().Width;
|
|
eTemplate.Resize.Height = wnd->GetPosition().Height;
|
|
|
|
wnd->OnResize(&eTemplate);
|
|
}
|
|
}
|
|
|
|
if (unlikely(Cursor != CursorType::ResizeAll))
|
|
{
|
|
Cursor = CursorType::ResizeAll;
|
|
CursorBufferRepaint = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (unlikely(Cursor != CursorType::Arrow))
|
|
{
|
|
Cursor = CursorType::Arrow;
|
|
CursorBufferRepaint = true;
|
|
}
|
|
}
|
|
|
|
eTemplate.MouseMove.X = Mouse.X;
|
|
eTemplate.MouseMove.Y = Mouse.Y;
|
|
eTemplate.MouseMove.Left = Mouse.Left;
|
|
eTemplate.MouseMove.Right = Mouse.Right;
|
|
eTemplate.MouseMove.Middle = Mouse.Middle;
|
|
wnd->OnMouseMove(&eTemplate);
|
|
}
|
|
else
|
|
{
|
|
if (unlikely(Idle > 1000))
|
|
CPU::Pause();
|
|
else
|
|
Idle++;
|
|
}
|
|
}
|
|
|
|
foreach (auto wdg in this->Widgets)
|
|
{
|
|
// TODO: Implement mouse events for widgets
|
|
UNUSED(wdg);
|
|
}
|
|
|
|
memmove(MouseArray + 1, MouseArray, sizeof(MouseArray) - sizeof(MouseArray[1]));
|
|
MouseArray[0] = Mouse;
|
|
|
|
LastCursor = Cursor;
|
|
}
|
|
|
|
void GUI::PaintDesktop()
|
|
{
|
|
if (DesktopBufferRepaint)
|
|
{
|
|
// PutRect(this->DesktopBuffer, this->Desktop, 0x404040);
|
|
memset(this->DesktopBuffer->Data, 0x404040, this->DesktopBuffer->Size);
|
|
DesktopBufferRepaint = false;
|
|
}
|
|
// Well... I have to do some code optimization on DrawOverBitmap. It's too slow and it's not even using SIMD
|
|
memcpy(this->BackBuffer->Data, this->DesktopBuffer->Data, this->DesktopBuffer->Size);
|
|
}
|
|
|
|
void GUI::PaintWidgets()
|
|
{
|
|
Event eTemplate;
|
|
memset(&eTemplate, 0, sizeof(Event));
|
|
foreach (auto wdg in this->Widgets)
|
|
wdg->OnPaint(nullptr);
|
|
}
|
|
|
|
void GUI::PaintWindows()
|
|
{
|
|
foreach (auto wnd in this->Windows)
|
|
{
|
|
ScreenBitmap *wndBuffer = wnd->GetBuffer();
|
|
if (unlikely(wndBuffer == nullptr)) // I think "unlikely" is not needed here
|
|
continue;
|
|
|
|
Rect WndPos = wnd->GetPosition();
|
|
|
|
// Draw window content
|
|
DrawOverBitmap(this->BackBuffer,
|
|
wndBuffer,
|
|
WndPos.Top,
|
|
WndPos.Left);
|
|
|
|
/* We can't use memcpy because the window buffer
|
|
is not the same size as the screen buffer
|
|
https://i.imgur.com/OHfaYnS.png */
|
|
// memcpy(this->BackBuffer->Data + wnd->GetPositionPtr()->Top * this->BackBuffer->Width + wnd->GetPositionPtr()->Left, wndBuffer->Data, wndBuffer->Size);
|
|
|
|
Rect TopBarPos = WndPos;
|
|
TopBarPos.Top -= 20;
|
|
TopBarPos.Height = 20;
|
|
if (TopBarPos.Top < 0)
|
|
{
|
|
TopBarPos.Top = 0;
|
|
wnd->GetPositionPtr()->Top = 20;
|
|
}
|
|
|
|
Rect CloseButtonPos;
|
|
Rect MinimizeButtonPos;
|
|
|
|
CloseButtonPos.Left = TopBarPos.Left + TopBarPos.Width - 20;
|
|
CloseButtonPos.Top = TopBarPos.Top;
|
|
CloseButtonPos.Width = 20;
|
|
CloseButtonPos.Height = 20;
|
|
|
|
MinimizeButtonPos.Left = TopBarPos.Left + TopBarPos.Width - 60;
|
|
|
|
if (unlikely(MouseArray[0].X >= MinimizeButtonPos.Left &&
|
|
MouseArray[0].X <= CloseButtonPos.Left + CloseButtonPos.Width &&
|
|
MouseArray[0].Y >= CloseButtonPos.Top &&
|
|
MouseArray[0].Y <= CloseButtonPos.Top + CloseButtonPos.Height))
|
|
{
|
|
OverlayBufferRepaint = true;
|
|
}
|
|
|
|
// Title bar
|
|
if (unlikely(OverlayBufferRepaint))
|
|
{
|
|
if (OverlayFullRepaint)
|
|
{
|
|
memset(this->OverlayBuffer->Data, 0, this->OverlayBuffer->Size);
|
|
OverlayFullRepaint = false;
|
|
}
|
|
|
|
static bool RepaintNeeded = false;
|
|
DrawShadow(this->OverlayBuffer, wnd->GetPosition());
|
|
|
|
Rect MaximizeButtonPos;
|
|
MaximizeButtonPos.Left = TopBarPos.Left + TopBarPos.Width - 40;
|
|
MaximizeButtonPos.Top = TopBarPos.Top;
|
|
MaximizeButtonPos.Width = 20;
|
|
MaximizeButtonPos.Height = 20;
|
|
|
|
MinimizeButtonPos.Top = TopBarPos.Top;
|
|
MinimizeButtonPos.Width = 20;
|
|
MinimizeButtonPos.Height = 20;
|
|
|
|
PutRect(this->OverlayBuffer, TopBarPos, 0x282828);
|
|
// Title bar buttons (close, minimize, maximize) on the right
|
|
if (MouseArray[0].X >= CloseButtonPos.Left &&
|
|
MouseArray[0].X <= CloseButtonPos.Left + CloseButtonPos.Width &&
|
|
MouseArray[0].Y >= CloseButtonPos.Top &&
|
|
MouseArray[0].Y <= CloseButtonPos.Top + CloseButtonPos.Height)
|
|
{
|
|
PutRect(this->OverlayBuffer, CloseButtonPos, MouseArray[0].Left ? 0xFF5500 : 0xFF0000);
|
|
RepaintNeeded = true;
|
|
}
|
|
else
|
|
{
|
|
PutRect(this->OverlayBuffer, MaximizeButtonPos, 0x282828);
|
|
}
|
|
|
|
if (MouseArray[0].X >= MaximizeButtonPos.Left &&
|
|
MouseArray[0].X <= MaximizeButtonPos.Left + MaximizeButtonPos.Width &&
|
|
MouseArray[0].Y >= MaximizeButtonPos.Top &&
|
|
MouseArray[0].Y <= MaximizeButtonPos.Top + MaximizeButtonPos.Height)
|
|
{
|
|
PutRect(this->OverlayBuffer, MaximizeButtonPos, MouseArray[0].Left ? 0x454545 : 0x404040);
|
|
RepaintNeeded = true;
|
|
}
|
|
else
|
|
{
|
|
PutRect(this->OverlayBuffer, MaximizeButtonPos, 0x282828);
|
|
}
|
|
|
|
if (MouseArray[0].X >= MinimizeButtonPos.Left &&
|
|
MouseArray[0].X <= MinimizeButtonPos.Left + MinimizeButtonPos.Width &&
|
|
MouseArray[0].Y >= MinimizeButtonPos.Top &&
|
|
MouseArray[0].Y <= MinimizeButtonPos.Top + MinimizeButtonPos.Height)
|
|
{
|
|
PutRect(this->OverlayBuffer, MinimizeButtonPos, MouseArray[0].Left ? 0x454545 : 0x404040);
|
|
RepaintNeeded = true;
|
|
}
|
|
else
|
|
{
|
|
PutRect(this->OverlayBuffer, MinimizeButtonPos, 0x282828);
|
|
}
|
|
|
|
// Title bar icons (close, minimize, maximize) on the right
|
|
for (short i = 0; i < 20; i++)
|
|
{
|
|
for (short j = 0; j < 20; j++)
|
|
{
|
|
if (CloseButton[i * 20 + j] == 1)
|
|
SetPixel(this->OverlayBuffer,
|
|
CloseButtonPos.Left + j,
|
|
CloseButtonPos.Top + i,
|
|
0xFFFFFF);
|
|
|
|
if ((MaximizeButtonMaximized[i * 20 + j] == 1) && !wnd->IsMaximized())
|
|
SetPixel(this->OverlayBuffer,
|
|
MaximizeButtonPos.Left + j,
|
|
MaximizeButtonPos.Top + i,
|
|
0xFFFFFF);
|
|
else if ((MaximizeButtonNormal[i * 20 + j] == 1) && wnd->IsMaximized())
|
|
SetPixel(this->OverlayBuffer,
|
|
MaximizeButtonPos.Left + j,
|
|
MaximizeButtonPos.Top + i,
|
|
0xFFFFFF);
|
|
|
|
if (MinimizeButton[i * 20 + j] == 1)
|
|
SetPixel(this->OverlayBuffer,
|
|
MinimizeButtonPos.Left + j,
|
|
MinimizeButtonPos.Top + i,
|
|
0xFFFFFF);
|
|
}
|
|
}
|
|
|
|
Rect wndPos = wnd->GetPosition();
|
|
|
|
// Resize hint
|
|
for (short i = 0; i < 20; i++)
|
|
for (short j = 0; j < 20; j++)
|
|
if (ResizeHint[i * 20 + j] == 1)
|
|
SetPixel(this->OverlayBuffer, wndPos.Left + wndPos.Width - 20 + j, wndPos.Top + wndPos.Height - 20 + i, 0xFFFFFF);
|
|
|
|
// Title bar border
|
|
PutBorder(this->OverlayBuffer, TopBarPos, 0xFF000000);
|
|
// Window border
|
|
PutBorder(this->OverlayBuffer, wndPos, 0xFF000000);
|
|
|
|
Rect TopBarTextPos = TopBarPos;
|
|
TopBarTextPos.Left += 4;
|
|
TopBarTextPos.Top += 4;
|
|
|
|
// Title bar text
|
|
long CharCursorX = TopBarTextPos.Left;
|
|
long CharCursorY = TopBarTextPos.Top;
|
|
for (uint64_t i = 0; i < strlen(wnd->GetTitle()); i++)
|
|
PaintChar(this->CurrentFont, this->OverlayBuffer, wnd->GetTitle()[i], 0xFFFFFF, &CharCursorX, &CharCursorY);
|
|
|
|
if (!RepaintNeeded)
|
|
{
|
|
OverlayBufferRepaint = false;
|
|
RepaintNeeded = false;
|
|
}
|
|
}
|
|
wnd->OnPaint(nullptr);
|
|
}
|
|
DrawOverBitmap(this->BackBuffer, this->OverlayBuffer, 0, 0);
|
|
}
|
|
|
|
/*
|
|
"* 2" to increase the size of the cursor
|
|
"/ 2" to decrease the size of the cursor
|
|
*/
|
|
#define ICON_SIZE
|
|
|
|
void GUI::PaintCursor()
|
|
{
|
|
uint32_t CursorColorInner = 0xFFFFFFFF;
|
|
uint32_t CursorColorOuter = 0xFF000000;
|
|
|
|
if (MouseArray[0].X != MouseArray[1].X ||
|
|
MouseArray[0].Y != MouseArray[1].Y ||
|
|
MouseArray[0].Z != MouseArray[1].Z ||
|
|
Cursor != LastCursor)
|
|
CursorBufferRepaint = true;
|
|
|
|
if (CursorBufferRepaint)
|
|
{
|
|
memset(this->CursorBuffer->Data, 0, this->CursorBuffer->Size);
|
|
switch (this->Cursor)
|
|
{
|
|
case CursorType::Visible:
|
|
{
|
|
CursorVisible = true;
|
|
break;
|
|
}
|
|
case CursorType::Hidden:
|
|
{
|
|
CursorVisible = false;
|
|
break;
|
|
}
|
|
default:
|
|
fixme("Unknown cursor type %d", this->Cursor);
|
|
[[fallthrough]];
|
|
case CursorType::Arrow:
|
|
{
|
|
if (CursorVisible)
|
|
for (int i = 0; i < 19; i++)
|
|
{
|
|
for (int j = 0; j < 12; j++)
|
|
{
|
|
if (CursorArrow[i * 12 + j] == 1)
|
|
{
|
|
SetPixel(this->CursorBuffer, j ICON_SIZE, i ICON_SIZE, CursorColorOuter);
|
|
}
|
|
else if (CursorArrow[i * 12 + j] == 2)
|
|
{
|
|
SetPixel(this->CursorBuffer, j ICON_SIZE, i ICON_SIZE, CursorColorInner);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case CursorType::Hand:
|
|
{
|
|
if (CursorVisible)
|
|
for (int i = 0; i < 24; i++)
|
|
{
|
|
for (int j = 0; j < 17; j++)
|
|
{
|
|
if (CursorHand[i * 17 + j] == 1)
|
|
{
|
|
SetPixel(this->CursorBuffer, j ICON_SIZE, i ICON_SIZE, CursorColorOuter);
|
|
}
|
|
else if (CursorHand[i * 17 + j] == 2)
|
|
{
|
|
SetPixel(this->CursorBuffer, j ICON_SIZE, i ICON_SIZE, CursorColorInner);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case CursorType::Wait:
|
|
{
|
|
if (CursorVisible)
|
|
for (int i = 0; i < 22; i++)
|
|
{
|
|
for (int j = 0; j < 13; j++)
|
|
{
|
|
if (CursorWait[i * 13 + j] == 1)
|
|
{
|
|
SetPixel(this->CursorBuffer, j ICON_SIZE, i ICON_SIZE, CursorColorOuter);
|
|
}
|
|
else if (CursorWait[i * 13 + j] == 2)
|
|
{
|
|
SetPixel(this->CursorBuffer, j ICON_SIZE, i ICON_SIZE, CursorColorInner);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case CursorType::IBeam:
|
|
{
|
|
if (CursorVisible)
|
|
for (int i = 0; i < 22; i++)
|
|
{
|
|
for (int j = 0; j < 13; j++)
|
|
{
|
|
if (CursorIBeam[i * 13 + j] == 1)
|
|
{
|
|
SetPixel(this->CursorBuffer, j ICON_SIZE, i ICON_SIZE, CursorColorOuter);
|
|
}
|
|
else if (CursorIBeam[i * 13 + j] == 2)
|
|
{
|
|
SetPixel(this->CursorBuffer, j ICON_SIZE, i ICON_SIZE, CursorColorInner);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case CursorType::ResizeAll:
|
|
{
|
|
if (CursorVisible)
|
|
for (int i = 0; i < 23; i++)
|
|
{
|
|
for (int j = 0; j < 23; j++)
|
|
{
|
|
if (CursorResizeAll[i * 23 + j] == 1)
|
|
{
|
|
SetPixel(this->CursorBuffer, j ICON_SIZE, i ICON_SIZE, CursorColorOuter);
|
|
}
|
|
else if (CursorResizeAll[i * 23 + j] == 2)
|
|
{
|
|
SetPixel(this->CursorBuffer, j ICON_SIZE, i ICON_SIZE, CursorColorInner);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
CursorBufferRepaint = false;
|
|
}
|
|
DrawOverBitmap(this->BackBuffer, this->CursorBuffer, MouseArray[0].Y, MouseArray[0].X);
|
|
}
|
|
|
|
void GUI::Loop()
|
|
{
|
|
/*
|
|
Because we do not use a gpu to do the rendering, we need to do it manually.
|
|
This is why the mouse is slow when we have to draw a bunch of things.
|
|
*/
|
|
while (IsRunning)
|
|
{
|
|
#ifdef DEBUG
|
|
FIi = CPU::Counter();
|
|
#endif
|
|
FetchInputs();
|
|
#ifdef DEBUG
|
|
FIi = CPU::Counter() - FIi;
|
|
PDi = CPU::Counter();
|
|
#endif
|
|
PaintDesktop();
|
|
#ifdef DEBUG
|
|
PDi = CPU::Counter() - PDi;
|
|
PWi = CPU::Counter();
|
|
#endif
|
|
PaintWidgets();
|
|
#ifdef DEBUG
|
|
PWi = CPU::Counter() - PWi;
|
|
PWWi = CPU::Counter();
|
|
#endif
|
|
PaintWindows();
|
|
#ifdef DEBUG
|
|
PWWi = CPU::Counter() - PWWi;
|
|
PCi = CPU::Counter();
|
|
#endif
|
|
PaintCursor();
|
|
#ifdef DEBUG
|
|
PCi = CPU::Counter() - PCi;
|
|
mmi = CPU::Counter();
|
|
#endif
|
|
memcpy(Display->GetBuffer(200)->Buffer, this->BackBuffer->Data, this->BackBuffer->Size);
|
|
Display->SetBuffer(200);
|
|
#ifdef DEBUG
|
|
mmi = CPU::Counter() - mmi;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void GUI::AddWindow(Window *window)
|
|
{
|
|
this->Windows.push_back(window);
|
|
}
|
|
|
|
void GUI::AddWidget(WidgetCollection *widget)
|
|
{
|
|
this->Widgets.push_back(widget);
|
|
}
|
|
|
|
GUI::GUI()
|
|
{
|
|
Display->CreateBuffer(0, 0, 200);
|
|
this->CurrentFont = new Video::Font(&_binary_Files_tamsyn_font_1_11_Tamsyn7x14r_psf_start, &_binary_Files_tamsyn_font_1_11_Tamsyn7x14r_psf_end, Video::FontType::PCScreenFont2);
|
|
this->mem = new Memory::MemMgr;
|
|
this->Desktop.Top = 0;
|
|
this->Desktop.Left = 0;
|
|
this->Desktop.Width = Display->GetBuffer(200)->Width;
|
|
this->Desktop.Height = Display->GetBuffer(200)->Height;
|
|
|
|
this->BackBuffer = new ScreenBitmap;
|
|
this->BackBuffer->Width = this->Desktop.Width;
|
|
this->BackBuffer->Height = this->Desktop.Height;
|
|
this->BackBuffer->BitsPerPixel = Display->GetBitsPerPixel();
|
|
this->BackBuffer->Pitch = Display->GetPitch();
|
|
this->BackBuffer->Size = Display->GetBuffer(200)->Size;
|
|
this->BackBuffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->BackBuffer->Size));
|
|
memset(this->BackBuffer->Data, 0, this->BackBuffer->Size);
|
|
|
|
this->DesktopBuffer = new ScreenBitmap;
|
|
this->DesktopBuffer->Width = this->Desktop.Width;
|
|
this->DesktopBuffer->Height = this->Desktop.Height;
|
|
this->DesktopBuffer->BitsPerPixel = Display->GetBitsPerPixel();
|
|
this->DesktopBuffer->Pitch = Display->GetPitch();
|
|
this->DesktopBuffer->Size = Display->GetBuffer(200)->Size;
|
|
this->DesktopBuffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->DesktopBuffer->Size));
|
|
memset(this->DesktopBuffer->Data, 0, this->DesktopBuffer->Size);
|
|
|
|
this->OverlayBuffer = new ScreenBitmap;
|
|
this->OverlayBuffer->Width = this->Desktop.Width;
|
|
this->OverlayBuffer->Height = this->Desktop.Height;
|
|
this->OverlayBuffer->BitsPerPixel = Display->GetBitsPerPixel();
|
|
this->OverlayBuffer->Pitch = Display->GetPitch();
|
|
this->OverlayBuffer->Size = Display->GetBuffer(200)->Size;
|
|
this->OverlayBuffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->OverlayBuffer->Size));
|
|
memset(this->OverlayBuffer->Data, 0, this->OverlayBuffer->Size);
|
|
|
|
this->CursorBuffer = new ScreenBitmap;
|
|
this->CursorBuffer->Width = 25;
|
|
this->CursorBuffer->Height = 25;
|
|
this->CursorBuffer->BitsPerPixel = Display->GetBitsPerPixel();
|
|
this->CursorBuffer->Pitch = Display->GetPitch();
|
|
this->CursorBuffer->Size = this->CursorBuffer->Width * this->CursorBuffer->Height * (this->CursorBuffer->BitsPerPixel / 8);
|
|
this->CursorBuffer->Data = (uint8_t *)this->mem->RequestPages(TO_PAGES(this->CursorBuffer->Size));
|
|
memset(this->CursorBuffer->Data, 0, this->CursorBuffer->Size);
|
|
|
|
this->IsRunning = true;
|
|
}
|
|
|
|
GUI::~GUI()
|
|
{
|
|
debug("Destructor called");
|
|
delete this->mem, this->mem = nullptr;
|
|
delete this->BackBuffer, this->BackBuffer = nullptr;
|
|
delete this->DesktopBuffer, this->DesktopBuffer = nullptr;
|
|
delete this->OverlayBuffer, this->OverlayBuffer = nullptr;
|
|
delete this->CursorBuffer, this->CursorBuffer = nullptr;
|
|
Display->DeleteBuffer(200);
|
|
for (size_t i = 0; i < this->Windows.size(); i++)
|
|
this->Windows.remove(i);
|
|
}
|
|
}
|