# HG changeset patch # User Radek Brich # Date 1357767135 -3600 # Node ID fccca2a60492e65162799f3571177c3583b7697f # Parent 729fcdfe6b57ee53f64e44f5af20b62c95f9baf0 DriverSDL: Implement blink attribute. diff -r 729fcdfe6b57 -r fccca2a60492 demo_colors.py --- a/demo_colors.py Tue Jan 08 23:59:55 2013 +0100 +++ b/demo_colors.py Wed Jan 09 22:32:15 2013 +0100 @@ -4,7 +4,7 @@ import locale locale.setlocale(locale.LC_ALL, '') -from tuikit import Application, Label, VerticalLayout +from tuikit import Application, Window, Label, VerticalLayout class MyApplication(Application): @@ -12,6 +12,10 @@ Application.__init__(self) self.top.add_handler('keypress', self.on_top_keypress) + win = Window() + self.top.add(win) + win.layout = VerticalLayout() + for attr in ['blink', 'bold', 'standout', 'underline']: label = Label(attr) label.color = 'test-' + attr diff -r 729fcdfe6b57 -r fccca2a60492 sdlterm/src/sdlterm.cc --- 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; +} + diff -r 729fcdfe6b57 -r fccca2a60492 sdlterm/src/sdlterm.h --- a/sdlterm/src/sdlterm.h Tue Jan 08 23:59:55 2013 +0100 +++ b/sdlterm/src/sdlterm.h Wed Jan 09 22:32:15 2013 +0100 @@ -10,10 +10,10 @@ namespace Style { enum { - BOLD = 1 << 0, // bold font - UNDERLINE = 1 << 1, // underline text - STANDOUT = 1 << 2, // inverse bg/fg - BLINK = 1 << 3, // blinking + BOLD = 1 << 24, // bold font + UNDERLINE = 1 << 25, // underline text + STANDOUT = 1 << 26, // inverse bg/fg + BLINK = 1 << 27, // blinking }; }; @@ -76,7 +76,7 @@ void close_font(); // do not free surface returned! - SDL_Surface *render_cell(Uint32 ch, Uint32 attr); + SDL_Surface *render_cell(Uint32 ch, Uint32 attr, bool blink_state); int get_cell_width() const { return _cell_width; }; int get_cell_height() const { return _cell_height; }; @@ -124,7 +124,7 @@ TerminalScreen(): _screen_surface(NULL), _cells_front(0), _cells_back(0), _render(), _pixel_width(0), _pixel_height(0), _width(0), _height(0), - _cell_width(0), _cell_height(0) {}; + _cell_width(0), _cell_height(0), _blink_state(1) {}; ~TerminalScreen() {}; void select_font(const char *fname_regular, const char *fname_bold, int ptsize); @@ -133,6 +133,7 @@ void erase(); void putch(int x, int y, Uint32 ch, Uint32 attr); void toggle_cursor(int x, int y); + void toggle_blink() { _blink_state = !_blink_state; _draw_blink(); }; void commit(); // force full redraw on next commit() @@ -156,7 +157,10 @@ int _cell_width; // character cell width in pixels int _cell_height; + int _blink_state; // 0 - blink chars hidden, 1 - visible + void _reset_cells(); + void _draw_blink(); }; @@ -223,6 +227,7 @@ const char *_translate_keyname(SDLKey sym); static Uint32 _wait_event_callback(Uint32 interval, void *param); + static Uint32 _blink_toggle_callback(Uint32 interval, void *param); };