--- a/sdlterm/src/sdlterm.cc Tue Jan 08 23:59:55 2013 +0100
+++ b/sdlterm/src/sdlterm.cc Wed Jan 09 22:32:15 2013 +0100
@@ -115,12 +115,18 @@
}
-SDL_Surface *GlyphRenderer::render_cell(Uint32 ch, Uint32 attr)
+SDL_Surface *GlyphRenderer::render_cell(Uint32 ch, Uint32 attr, bool blink_state)
{
SDL_Surface *cell_surface;
TTF_Font *font;
SDL_Color fgcolor, bgcolor;
+ // blink affects cache lookup, must be processed first
+ if ((attr & Style::BLINK) && !blink_state)
+ {
+ ch = ' ';
+ }
+
// try cache
Uint64 id = (Uint64)ch | (Uint64)attr << 32;
cell_surface = _cache.lookup_glyph(id);
@@ -132,9 +138,8 @@
// load attributes
_colormap.index_to_rgb((attr & 0x000000FF), fgcolor);
_colormap.index_to_rgb((attr & 0x0000FF00) >> 8, bgcolor);
- int style = (attr & 0xFF000000) >> 24;
- font = (style & Style::BOLD) ? _font_bold : _font_regular;
- if (style & Style::STANDOUT)
+ font = (attr & Style::BOLD) ? _font_bold : _font_regular;
+ if (attr & Style::STANDOUT)
{
std::swap(fgcolor, bgcolor);
}
@@ -154,7 +159,7 @@
if (ch)
{
// when glyph is not provided by BOLD font but is provided by REGULAR font, use that (better than nothing)
- if ((style & Style::BOLD) && !TTF_GlyphIsProvided(font, ch) && TTF_GlyphIsProvided(_font_regular, ch))
+ if ((attr & Style::BOLD) && !TTF_GlyphIsProvided(font, ch) && TTF_GlyphIsProvided(_font_regular, ch))
{
// use bold style of regular font instead of bold font
TTF_SetFontStyle(_font_regular, TTF_STYLE_BOLD);
@@ -166,7 +171,7 @@
// normal case
_render_glyph(cell_surface, font, ch, fgcolor, bgcolor);
}
- if (style & Style::UNDERLINE)
+ if (attr & Style::UNDERLINE)
{
// draw underline
SDL_LockSurface(cell_surface);
@@ -244,7 +249,7 @@
void TerminalScreen::toggle_cursor(int x, int y)
{
TerminalCell &cell = _cells_front[y * _width + x];
- cell.attr ^= (Style::STANDOUT << 24);
+ cell.attr ^= Style::STANDOUT;
}
@@ -262,7 +267,7 @@
{
dst_rect.x = x * _cell_width;
dst_rect.y = y * _cell_height;
- cell_surface = _render.render_cell(front_iter->ch, front_iter->attr);
+ cell_surface = _render.render_cell(front_iter->ch, front_iter->attr, _blink_state);
SDL_BlitSurface(cell_surface, NULL, _screen_surface, &dst_rect);
*back_iter = *front_iter;
}
@@ -301,6 +306,33 @@
}
+void TerminalScreen::_draw_blink()
+{
+ // Use back buffer which contains commited changes.
+ // This is called from timer while application may draw into front_buffer.
+ auto back_iter = _cells_back.begin();
+ SDL_Surface *cell_surface;
+ SDL_Rect dst_rect;
+ for (int y = 0; y < _height; y++)
+ {
+ for (int x = 0; x < _width; x++)
+ {
+ // draw only blinking characters
+ if (back_iter->attr & Style::BLINK)
+ {
+ dst_rect.x = x * _cell_width;
+ dst_rect.y = y * _cell_height;
+ cell_surface = _render.render_cell(back_iter->ch, back_iter->attr, _blink_state);
+ SDL_BlitSurface(cell_surface, NULL, _screen_surface, &dst_rect);
+ }
+ back_iter++;
+ }
+ }
+
+ SDL_UpdateRect(_screen_surface, 0, 0, 0, 0);
+}
+
+
Terminal::Terminal()
: _screen(), _attr(7), _cursor_x(0), _cursor_y(0), _cursor_visible(false),
_mousemove_last_x(-1), _mousemove_last_y(-1)
@@ -312,6 +344,7 @@
SDL_EnableUNICODE(1);
SDL_EnableKeyRepeat(250, SDL_DEFAULT_REPEAT_INTERVAL);
SDL_WM_SetCaption("terminal", NULL);
+ SDL_AddTimer(500, _blink_toggle_callback, NULL);
}
@@ -362,6 +395,13 @@
}
switch (sdl_event.type)
{
+ case SDL_USEREVENT:
+ // toggle blink
+ if (sdl_event.user.code == 2)
+ {
+ _screen.toggle_blink();
+ }
+ break; // continue loop
case SDL_QUIT:
event.type = Event::QUIT;
return true;
@@ -482,3 +522,13 @@
return 0;
}
+
+Uint32 Terminal::_blink_toggle_callback(Uint32 interval, void *param)
+{
+ SDL_Event event;
+ event.type = SDL_USEREVENT;
+ event.user.code = 2;
+ SDL_PushEvent(&event);
+ return interval;
+}
+