Kernel/GUI/GraphicalUserInterface.cpp
2022-12-26 08:41:01 +02:00

335 lines
12 KiB
C++

#include <gui.hpp>
#include <driver.hpp>
#include <task.hpp>
#include <debug.h>
#include "../kernel.h"
#include "../DAPI.hpp"
#include "../Fex.hpp"
namespace GraphicalUserInterface
{
char CursorArrow[] = {
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 12x19
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, //
1, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, //
1, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, //
1, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, //
1, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, //
1, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, //
1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, //
1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, //
1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, //
1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, //
1, 2, 2, 2, 1, 2, 2, 1, 0, 0, 0, 0, //
1, 2, 2, 1, 0, 1, 2, 2, 1, 0, 0, 0, //
1, 2, 1, 0, 0, 1, 2, 2, 1, 0, 0, 0, //
1, 1, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0, //
1, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0, //
0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, //
};
char CursorHand[] = {
0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 17x24
0, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
0, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
0, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
0, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
0, 0, 0, 0, 1, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, //
0, 0, 0, 0, 1, 2, 2, 1, 2, 2, 1, 1, 1, 0, 0, 0, 0, //
0, 0, 0, 0, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 1, 0, 0, //
0, 0, 0, 0, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 1, 0, //
0, 0, 0, 0, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, //
1, 1, 1, 0, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, //
1, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, //
1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, //
0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, //
0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, //
0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, //
0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, //
0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, //
0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, //
0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, //
0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, //
0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, //
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, //
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //
};
char CursorWait[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 13x22
1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, //
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //
0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, //
0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, //
0, 1, 2, 2, 1, 2, 1, 2, 1, 2, 2, 1, 0, //
0, 1, 2, 2, 2, 1, 2, 1, 2, 2, 2, 1, 0, //
0, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, 1, 0, //
0, 0, 1, 1, 2, 2, 2, 2, 2, 1, 1, 0, 0, //
0, 0, 0, 1, 1, 2, 1, 2, 1, 1, 0, 0, 0, //
0, 0, 0, 0, 1, 1, 2, 1, 1, 0, 0, 0, 0, //
0, 0, 0, 0, 1, 1, 2, 1, 1, 0, 0, 0, 0, //
0, 0, 0, 1, 1, 2, 2, 2, 1, 1, 0, 0, 0, //
0, 0, 1, 1, 2, 2, 1, 2, 2, 1, 1, 0, 0, //
0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0, //
0, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 0, //
0, 1, 2, 2, 2, 1, 2, 1, 2, 2, 2, 1, 0, //
0, 1, 2, 2, 1, 2, 1, 2, 1, 2, 2, 1, 0, //
0, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 0, //
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //
1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, //
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //
};
char CursorIBeam[] = {
1, 1, 1, 0, 1, 1, 1, // 7x17
0, 0, 0, 1, 0, 0, 0, //
0, 0, 0, 1, 0, 0, 0, //
0, 0, 0, 1, 0, 0, 0, //
0, 0, 0, 1, 0, 0, 0, //
0, 0, 0, 1, 0, 0, 0, //
0, 0, 0, 1, 0, 0, 0, //
0, 0, 0, 1, 0, 0, 0, //
0, 0, 0, 1, 0, 0, 0, //
0, 0, 0, 1, 0, 0, 0, //
0, 0, 0, 1, 0, 0, 0, //
0, 0, 0, 1, 0, 0, 0, //
0, 0, 0, 1, 0, 0, 0, //
0, 0, 0, 1, 0, 0, 0, //
0, 0, 0, 1, 0, 0, 0, //
0, 0, 0, 1, 0, 0, 0, //
1, 1, 1, 0, 1, 1, 1, //
};
char CursorResizeAll[] ={
0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, // 23x23
0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0, //
0,0,0,0,0,0,0,0,0,1,2,2,2,1,0,0,0,0,0,0,0,0,0, //
0,0,0,0,0,0,0,0,1,2,2,2,2,2,1,0,0,0,0,0,0,0,0, //
0,0,0,0,0,0,0,1,1,1,1,2,1,1,1,1,0,0,0,0,0,0,0, //
0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0, //
0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0, //
0,0,0,0,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,0,0,0,0, //
0,0,0,1,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,0,0,0, //
0,0,1,2,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,2,1,0,0, //
0,1,2,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,2,1,0, //
1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1, //
0,1,2,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,2,1,0, //
0,0,1,2,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,2,1,0,0, //
0,0,0,1,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,0,0,0, //
0,0,0,0,1,0,0,0,0,0,1,2,1,0,0,0,0,0,1,0,0,0,0, //
0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0, //
0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0, //
0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, //
0,0,0,0,0,0,0,0,1,2,2,2,2,2,1,0,0,0,0,0,0,0,0, //
0,0,0,0,0,0,0,0,0,1,2,2,2,1,0,0,0,0,0,0,0,0,0, //
0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0, //
0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, //
};
void GUI::PaintDesktop()
{
PutRect(0, 0, Display->GetBuffer(200)->Width, Display->GetBuffer(200)->Height, 0x282828);
}
void GUI::PaintWindows()
{
foreach (auto wnd in this->Windows)
wnd->Paint();
}
void GUI::PaintCursor()
{
KernelCallback callback;
if (DriverManager->GetDrivers().size() > 0)
{
foreach (auto Driver in DriverManager->GetDrivers())
{
if (((FexExtended *)((uintptr_t)Driver->Address + EXTENDED_SECTION_ADDRESS))->Driver.Type == FexDriverType::FexDriverType_Input)
{
memset(&callback, 0, sizeof(KernelCallback));
callback.Reason = FetchReason;
DriverManager->IOCB(Driver->DriverUID, (void *)&callback);
// TODO: I think I should check somehow what driver is the one that is mouse and not keyboard
Mouse.X = (callback.InputCallback.Mouse.X * Display->GetBuffer(200)->Width) / 0xFFFF; // VMWARE mouse
Mouse.Y = (callback.InputCallback.Mouse.Y * Display->GetBuffer(200)->Height) / 0xFFFF; // VMWARE mouse
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;
break;
}
}
}
uint32_t CursorColorInner = 0xFFFFFFFF;
uint32_t CursorColorOuter = 0x00000000;
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)
{
Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorOuter, 200);
}
else if (CursorArrow[i * 12 + j] == 2)
{
Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorInner, 200);
}
}
}
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)
{
Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorOuter, 200);
}
else if (CursorHand[i * 17 + j] == 2)
{
Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorInner, 200);
}
}
}
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)
{
Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorOuter, 200);
}
else if (CursorWait[i * 13 + j] == 2)
{
Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorInner, 200);
}
}
}
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)
{
Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorOuter, 200);
}
else if (CursorIBeam[i * 13 + j] == 2)
{
Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorInner, 200);
}
}
}
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)
{
Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorOuter, 200);
}
else if (CursorResizeAll[i * 23 + j] == 2)
{
Display->SetPixel(Mouse.X + j, Mouse.Y + i, CursorColorInner, 200);
}
}
}
break;
}
}
foreach (auto wnd in this->Windows)
{
Event ev;
ev.Type = EventType::MouseEvent;
ev.Mouse.X = Mouse.X;
ev.Mouse.Y = Mouse.Y;
ev.Mouse.Z = Mouse.Z;
ev.Mouse.Left = Mouse.Left;
ev.Mouse.Right = Mouse.Right;
ev.Mouse.Middle = Mouse.Middle;
ev.LastMouse.X = LastMouse.X;
ev.LastMouse.Y = LastMouse.Y;
ev.LastMouse.Z = LastMouse.Z;
ev.LastMouse.Left = LastMouse.Left;
ev.LastMouse.Right = LastMouse.Right;
ev.LastMouse.Middle = LastMouse.Middle;
wnd->HandleEvent(&ev);
}
LastMouse = Mouse;
}
void GUI::Loop()
{
while (IsRunning)
{
PaintDesktop();
PaintWindows();
PaintCursor();
Display->SetBuffer(200);
}
}
void GUI::AddWindow(Window *window)
{
this->Windows.push_back(window);
}
GUI::GUI()
{
this->mem = new Memory::MemMgr;
Display->CreateBuffer(0, 0, 200);
this->IsRunning = true;
}
GUI::~GUI()
{
delete this->mem;
Display->DeleteBuffer(200);
for (size_t i = 0; i < this->Windows.size(); i++)
this->Windows.remove(i);
}
}