2022-04-08 21:40:41 +02:00
|
|
|
#include "HyprError.hpp"
|
|
|
|
#include "../Compositor.hpp"
|
|
|
|
|
|
|
|
void CHyprError::queueCreate(std::string message, const CColor& color) {
|
|
|
|
m_szQueued = message;
|
2022-12-16 18:17:31 +01:00
|
|
|
m_cQueued = color;
|
2022-04-08 21:40:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void CHyprError::createQueued() {
|
|
|
|
if (m_bIsCreated) {
|
|
|
|
m_bQueuedDestroy = false;
|
|
|
|
m_tTexture.destroyTexture();
|
|
|
|
}
|
|
|
|
|
2022-06-30 15:44:26 +02:00
|
|
|
const auto PMONITOR = g_pCompositor->m_vMonitors.front().get();
|
2022-04-08 21:40:41 +02:00
|
|
|
|
2022-08-16 16:25:53 +02:00
|
|
|
const auto FONTSIZE = std::clamp((int)(10.f * (PMONITOR->vecPixelSize.x / 1920.f)), 8, 40);
|
|
|
|
|
2022-07-07 18:45:01 +02:00
|
|
|
const auto CAIROSURFACE = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y);
|
2022-04-08 21:40:41 +02:00
|
|
|
|
|
|
|
const auto CAIRO = cairo_create(CAIROSURFACE);
|
|
|
|
|
|
|
|
// clear the pixmap
|
|
|
|
cairo_save(CAIRO);
|
|
|
|
cairo_set_operator(CAIRO, CAIRO_OPERATOR_CLEAR);
|
|
|
|
cairo_paint(CAIRO);
|
|
|
|
cairo_restore(CAIRO);
|
|
|
|
|
|
|
|
const auto LINECOUNT = 1 + std::count(m_szQueued.begin(), m_szQueued.end(), '\n');
|
|
|
|
|
2023-01-05 19:25:45 +01:00
|
|
|
cairo_set_source_rgba(CAIRO, m_cQueued.r, m_cQueued.g, m_cQueued.b, m_cQueued.a);
|
2022-08-16 16:25:53 +02:00
|
|
|
cairo_rectangle(CAIRO, 0, 0, PMONITOR->vecPixelSize.x, (FONTSIZE + 2 * (FONTSIZE / 10.f)) * LINECOUNT);
|
2022-04-08 21:40:41 +02:00
|
|
|
|
|
|
|
// outline
|
2022-12-16 18:17:31 +01:00
|
|
|
cairo_rectangle(CAIRO, 0, 0, 1, PMONITOR->vecPixelSize.y); // left
|
|
|
|
cairo_rectangle(CAIRO, PMONITOR->vecPixelSize.x - 1, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y); // right
|
|
|
|
cairo_rectangle(CAIRO, 0, PMONITOR->vecPixelSize.y - 1, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y); // bottom
|
2022-04-08 21:40:41 +02:00
|
|
|
|
|
|
|
cairo_fill(CAIRO);
|
|
|
|
|
|
|
|
// draw the text with a common font
|
2023-01-05 19:25:45 +01:00
|
|
|
const CColor textColor = m_cQueued.r * m_cQueued.g * m_cQueued.b < 0.5f ? CColor(1.0, 1.0, 1.0, 1.0) : CColor(0, 0, 0, 1.0);
|
2022-04-08 21:40:41 +02:00
|
|
|
|
|
|
|
cairo_select_font_face(CAIRO, "Noto Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
|
2022-08-16 16:25:53 +02:00
|
|
|
cairo_set_font_size(CAIRO, FONTSIZE);
|
2023-01-05 19:25:45 +01:00
|
|
|
cairo_set_source_rgba(CAIRO, textColor.r, textColor.g, textColor.b, textColor.a);
|
2022-04-08 21:40:41 +02:00
|
|
|
|
2022-08-16 16:25:53 +02:00
|
|
|
float yoffset = FONTSIZE;
|
2022-12-16 18:17:31 +01:00
|
|
|
while (m_szQueued != "") {
|
2022-04-08 21:40:41 +02:00
|
|
|
std::string current = m_szQueued.substr(0, m_szQueued.find('\n'));
|
|
|
|
if (const auto NEWLPOS = m_szQueued.find('\n'); NEWLPOS != std::string::npos)
|
|
|
|
m_szQueued = m_szQueued.substr(NEWLPOS + 1);
|
|
|
|
else
|
|
|
|
m_szQueued = "";
|
|
|
|
cairo_move_to(CAIRO, 0, yoffset);
|
|
|
|
cairo_show_text(CAIRO, current.c_str());
|
2022-08-16 16:25:53 +02:00
|
|
|
yoffset += FONTSIZE + (FONTSIZE / 10.f);
|
2022-04-08 21:40:41 +02:00
|
|
|
}
|
2022-09-25 20:07:48 +02:00
|
|
|
|
2022-04-08 21:40:41 +02:00
|
|
|
cairo_surface_flush(CAIROSURFACE);
|
|
|
|
|
|
|
|
// copy the data to an OpenGL texture we have
|
|
|
|
const auto DATA = cairo_image_surface_get_data(CAIROSURFACE);
|
|
|
|
m_tTexture.allocate();
|
|
|
|
glBindTexture(GL_TEXTURE_2D, m_tTexture.m_iTexID);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
2022-09-25 20:07:48 +02:00
|
|
|
|
2022-11-07 21:31:56 +01:00
|
|
|
#ifndef GLES2
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
|
|
|
#endif
|
2022-09-25 20:07:48 +02:00
|
|
|
|
2022-07-07 18:45:01 +02:00
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
|
2022-04-08 21:40:41 +02:00
|
|
|
|
|
|
|
// delete cairo
|
|
|
|
cairo_destroy(CAIRO);
|
|
|
|
cairo_surface_destroy(CAIROSURFACE);
|
|
|
|
|
|
|
|
m_bIsCreated = true;
|
2022-12-16 18:17:31 +01:00
|
|
|
m_szQueued = "";
|
|
|
|
m_cQueued = CColor();
|
2022-05-12 12:46:38 +02:00
|
|
|
|
|
|
|
g_pHyprRenderer->damageMonitor(PMONITOR);
|
2022-04-08 21:40:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void CHyprError::draw() {
|
2022-04-09 22:49:07 +02:00
|
|
|
if (!m_bIsCreated || m_szQueued != "") {
|
2022-04-08 21:40:41 +02:00
|
|
|
if (m_szQueued != "")
|
|
|
|
createQueued();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_bQueuedDestroy) {
|
|
|
|
m_bQueuedDestroy = false;
|
|
|
|
m_tTexture.destroyTexture();
|
|
|
|
m_bIsCreated = false;
|
2022-12-16 18:17:31 +01:00
|
|
|
m_szQueued = "";
|
2022-06-30 15:44:26 +02:00
|
|
|
g_pHyprRenderer->damageMonitor(g_pCompositor->m_vMonitors.front().get());
|
2022-04-08 21:40:41 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-06-30 15:44:26 +02:00
|
|
|
const auto PMONITOR = g_pCompositor->m_vMonitors.front().get();
|
2022-04-08 21:40:41 +02:00
|
|
|
|
|
|
|
if (g_pHyprOpenGL->m_RenderData.pMonitor != PMONITOR)
|
|
|
|
return; // wrong mon
|
|
|
|
|
2022-07-07 18:45:01 +02:00
|
|
|
wlr_box windowBox = {0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y};
|
2022-04-08 21:40:41 +02:00
|
|
|
|
2023-01-05 19:25:45 +01:00
|
|
|
g_pHyprOpenGL->renderTexture(m_tTexture, &windowBox, 1.f, 0);
|
2022-04-08 21:40:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void CHyprError::destroy() {
|
2022-05-12 12:46:38 +02:00
|
|
|
if (m_bIsCreated)
|
|
|
|
m_bQueuedDestroy = true;
|
2022-09-25 20:07:48 +02:00
|
|
|
}
|