38 bool bKeyPressed =
false;
39 bool bRunning =
false;
41 cairo_t *pCairo =
nullptr;
42 cairo_surface_t *pSurface =
nullptr;
44 Font *pNormalFont =
nullptr;
45 Font *pBoldFont =
nullptr;
49 : m_LocalData(nullptr), m_pWidget(nullptr), m_pRedrawer(pRedrawer)
61 delete m_LocalData->pTerminal;
62 delete m_LocalData->pBoldFont;
63 delete m_LocalData->pNormalFont;
65 cairo_surface_destroy(m_LocalData->pSurface);
66 cairo_destroy(m_LocalData->pCairo);
73 m_LocalData->nWidth = width;
74 m_LocalData->nHeight = height;
76 if (!m_LocalData->pCairo)
78 klog(LOG_ALERT,
"TUI: cairo instance is not yet valid!");
82 cairo_set_line_cap(m_LocalData->pCairo, CAIRO_LINE_CAP_SQUARE);
83 cairo_set_line_join(m_LocalData->pCairo, CAIRO_LINE_JOIN_MITER);
84 cairo_set_antialias(m_LocalData->pCairo, CAIRO_ANTIALIAS_NONE);
85 cairo_set_line_width(m_LocalData->pCairo, 1.0);
87 cairo_set_operator(m_LocalData->pCairo, CAIRO_OPERATOR_SOURCE);
88 cairo_set_source_rgba(m_LocalData->pCairo, 0, 0, 0, 1.0);
89 cairo_paint(m_LocalData->pCairo);
91 if (!m_LocalData->pNormalFont)
93 m_LocalData->pNormalFont =
94 new Font(m_LocalData->pCairo, 14,
"DejaVu Sans Mono 10",
true, 0);
95 if (!m_LocalData->pNormalFont)
97 klog(LOG_EMERG,
"Error: Normal font not loaded!");
102 if (!m_LocalData->pBoldFont)
104 m_LocalData->pBoldFont =
new Font(
105 m_LocalData->pCairo, 14,
"DejaVu Sans Mono Bold 10",
true, 0);
106 if (!m_LocalData->pBoldFont)
108 klog(LOG_EMERG,
"Error: Bold font not loaded!");
113 if (m_LocalData->pTerminal)
115 delete m_LocalData->pTerminal;
118 char newTermName[256];
119 sprintf(newTermName,
"Console%d", getpid());
123 m_LocalData->pTerminal =
new Terminal(
124 newTermName, m_LocalData->nWidth, m_LocalData->nHeight, 0, 0, 0,
125 m_LocalData->pCairo, m_pWidget,
this, m_LocalData->pNormalFont,
126 m_LocalData->pBoldFont);
127 m_LocalData->pTerminal->setCairo(
128 m_LocalData->pCairo, m_LocalData->pSurface);
131 delete m_LocalData->pTerminal;
132 m_LocalData->pTerminal =
nullptr;
136 m_LocalData->pTerminal->setActive(
true, rect);
137 m_LocalData->pTerminal->redrawAll(rect);
141 rect.point(m_LocalData->nWidth, m_LocalData->nHeight);
143 if (!m_LocalData->pTerminal)
147 "TUI: couldn't start up a terminal - failing gracefully...");
148 m_LocalData->pBoldFont->render(
149 "There are no pseudo-terminals available.", 5, 5, 0xFFFFFF,
151 m_LocalData->pBoldFont->render(
152 "Press any key to close this window.", 5,
153 m_LocalData->pBoldFont->getHeight() + 5, 0xFFFFFF, 0x000000,
false);
157 m_LocalData->bKeyPressed =
false;
158 while (!m_LocalData->bKeyPressed)
180 if (m_LocalData->pTerminal)
183 m_LocalData->pTerminal->setCursorStyle(filled);
184 m_LocalData->pTerminal->showCursor(dirty);
191 if (!(m_LocalData->nWidth && m_LocalData->nHeight))
197 if (m_LocalData->pSurface)
199 cairo_surface_destroy(m_LocalData->pSurface);
200 cairo_destroy(m_LocalData->pCairo);
205 cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, m_LocalData->nWidth);
206 memset(fb, 0, m_LocalData->nHeight * stride);
208 m_LocalData->pSurface = cairo_image_surface_create_for_data(
209 (uint8_t *) fb, CAIRO_FORMAT_ARGB32, m_LocalData->nWidth,
210 m_LocalData->nHeight, stride);
211 m_LocalData->pCairo = cairo_create(m_LocalData->pSurface);
213 if (m_LocalData->pTerminal)
215 m_LocalData->pTerminal->setCairo(
216 m_LocalData->pCairo, m_LocalData->pSurface);
219 if (m_LocalData->pNormalFont)
221 m_LocalData->pNormalFont->updateCairo(m_LocalData->pCairo);
224 if (m_LocalData->pBoldFont)
226 m_LocalData->pBoldFont->updateCairo(m_LocalData->pCairo);
232 m_LocalData->nWidth = newWidth;
233 m_LocalData->nHeight = newHeight;
235 if (!(m_LocalData->pTerminal && m_LocalData->pCairo))
242 cairo_set_operator(m_LocalData->pCairo, CAIRO_OPERATOR_SOURCE);
243 cairo_set_source_rgba(m_LocalData->pCairo, 0, 0, 0, 0.8);
245 m_LocalData->pCairo, 0, 0, m_LocalData->nWidth, m_LocalData->nHeight);
246 cairo_fill(m_LocalData->pCairo);
248 if (m_LocalData->pTerminal)
250 m_LocalData->pTerminal->
renewBuffer(newWidth, newHeight);
253 m_LocalData->pTerminal->redrawAll(rect);
254 m_LocalData->pTerminal->showCursor(rect);
257 kill(m_LocalData->pTerminal->getPid(), SIGWINCH);
263 size_t maxBuffSz = 32768;
266 m_LocalData->bRunning =
true;
267 while (m_LocalData->bRunning)
280 if (m_LocalData->pTerminal)
282 if (!m_LocalData->pTerminal->
isAlive())
284 m_LocalData->bRunning =
false;
294 if (!m_LocalData->bRunning)
299 int nReady = select(n + 1, &fds, NULL, NULL, 0);
308 if (FD_ISSET(m_pWidget->
getSocket(), &fds))
322 bool bShouldRedraw =
false;
325 if (m_LocalData->pTerminal)
328 if (FD_ISSET(fd, &fds))
331 ssize_t len = read(fd, buffer, maxBuffSz);
335 m_LocalData->pTerminal->
write(buffer, dirtyRect);
336 bShouldRedraw =
true;
347 klog(LOG_INFO,
"TUI shutting down cleanly.");
352 m_LocalData->bRunning =
false;
357 if (!m_LocalData->pTerminal)
361 if ((key & Keyboard::Ctrl) && !(key & Keyboard::Special))
371 if (rect.getX() == ~0UL && rect.getY() == ~0UL && rect.getX2() == 0 &&
378 rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
379 if (m_LocalData->pSurface)
381 cairo_surface_flush(m_LocalData->pSurface);
388 else if (m_pRedrawer)
391 rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
void processKey(uint64_t key)
void run()
Runs the TUI main loop.
void write(const char *pStr, DirtyRectangle &rect)
void recreateSurfaces(void *fb)
Re-create rendering surfaces from the newest framebuffer.
void setCursorStyle(bool filled)
Set the cursor fill state (e.g. box outline vs shaded box)
void keyInput(uint64_t key)
Handles a key press with all Pedigree input special flags.
bool initialise(size_t width, size_t height)
(Re-)initialise the terminal
void renewBuffer(size_t nWidth, size_t nHeight)
void redraw(DirtyRectangle &rect)
Performs a redraw.
void resize(size_t newWidth, size_t newHeight)
Handle a resize of the terminal.
void stop()
Stops the TUI main loop.
Tui(TuiRedrawer *pRedrawer)
Default constructor which builds without using a widget.