# HG changeset patch # User Radek Brich # Date 1357400850 -3600 # Node ID 1611c462c3e392e9f341363e3b92f857edd40cb7 # Parent 1f00e90fd72a5f94f8fd964fbf4a7f2e6f2be7cc Update sdlterm: Optimize commit() - use two cell buffers, redraw only dirty cells, not everything. Fix keypress event, filter mousemove. diff -r 1f00e90fd72a -r 1611c462c3e3 sdlterm/cython/sdlterm.pyx --- a/sdlterm/cython/sdlterm.pyx Sat Jan 05 12:40:32 2013 +0100 +++ b/sdlterm/cython/sdlterm.pyx Sat Jan 05 16:47:30 2013 +0100 @@ -3,7 +3,7 @@ # distutils: include_dirs = /usr/include/SDL src # distutils: libraries = SDL SDL_ttf # distutils: define_macros = _GNU_SOURCE=1 _REENTRANT -# distutils: extra_compile_args = --std=c++0x +# distutils: extra_compile_args = --std=c++11 # cython: language_level=3 from libcpp cimport bool @@ -35,8 +35,8 @@ cdef cppclass Terminal: Terminal() except + - void select_font(char *fname_regular, char *fname_bold, int ptsize) - void resize(int pxwidth, int pxheight) + void select_font(char *fname_regular, char *fname_bold, int ptsize) except + + void resize(int pxwidth, int pxheight) except + void erase() void putch(int x, int y, Py_UNICODE ch) @@ -56,6 +56,7 @@ cdef class SDLTerminal: cdef Terminal *thisptr # hold a C++ instance which we're wrapping + cdef Event event def __cinit__(self): self.thisptr = new Terminal() @@ -77,8 +78,8 @@ self.thisptr.commit() def get_next_event(self): - cdef Event event - self.thisptr.get_next_event(event) + self.thisptr.get_next_event(self.event) + event = self.event if event.type == event.MOUSEMOVE: return ('mousemove', event.mouse.x, event.mouse.y) if event.type == event.MOUSEDOWN: diff -r 1f00e90fd72a -r 1611c462c3e3 sdlterm/src/sdlterm.cc --- a/sdlterm/src/sdlterm.cc Sat Jan 05 12:40:32 2013 +0100 +++ b/sdlterm/src/sdlterm.cc Sat Jan 05 16:47:30 2013 +0100 @@ -1,6 +1,7 @@ #include "sdlterm.h" -#include +#include +#include SDL_Surface *GlyphCache::lookup_glyph(Uint16 ch) @@ -122,12 +123,7 @@ } TTF_Font *font = _font_regular; - SDL_Color color={0xff,0xff,0xff}, bgcolor={0,100,100}; - if (ch != 'W') - { - bgcolor.g = 0; - bgcolor.b = 0; - } + SDL_Color color={0xff,0xff,0xff}, bgcolor={0,0,0}; // create surface for whole cell and fill it with bg color cell_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, @@ -141,28 +137,29 @@ SDL_FillRect(cell_surface, &dst_rect, bgcolor_mapped); // render glyph, blit it onto cell surface - SDL_Surface *glyph_surface = TTF_RenderGlyph_Shaded(font, ch, color, bgcolor); - int minx, maxy; - TTF_GlyphMetrics(font, ch, &minx, NULL, NULL, &maxy, NULL); - dst_rect.x = minx; - dst_rect.y = TTF_FontAscent(font) - maxy; - SDL_BlitSurface(glyph_surface, NULL, cell_surface, &dst_rect); - SDL_FreeSurface(glyph_surface); + if (ch) + { + SDL_Surface *glyph_surface = TTF_RenderGlyph_Shaded(font, ch, color, bgcolor); + int minx, maxy; + TTF_GlyphMetrics(font, ch, &minx, NULL, NULL, &maxy, NULL); + dst_rect.x = minx; + dst_rect.y = TTF_FontAscent(font) - maxy; + SDL_BlitSurface(glyph_surface, NULL, cell_surface, &dst_rect); + SDL_FreeSurface(glyph_surface); + } + // convert to display format + SDL_Surface *tmp_surface = cell_surface; + cell_surface = SDL_DisplayFormat(tmp_surface); + SDL_FreeSurface(tmp_surface); + + // put to cache _cache.put_glyph(ch, cell_surface); + return cell_surface; } -TerminalScreen::~TerminalScreen() -{ - if (_cells) - { - delete[] _cells; - } -} - - void TerminalScreen::select_font(const char *fname_regular, const char *fname_bold, int ptsize) { _render.open_font(fname_regular, fname_bold, ptsize); @@ -171,7 +168,7 @@ void TerminalScreen::resize(int pxwidth, int pxheight) { - _screen_surface = SDL_SetVideoMode(pxwidth, pxheight, 32, SDL_HWSURFACE|SDL_RESIZABLE); + _screen_surface = SDL_SetVideoMode(pxwidth, pxheight, 0, SDL_SWSURFACE|SDL_ANYFORMAT|SDL_RESIZABLE); if (_screen_surface == NULL) { @@ -190,19 +187,13 @@ void TerminalScreen::erase() { - TerminalCell * cell = _cells; - for (int i = 0; i < _width * _height; i++) - { - cell->ch = ' '; - cell->attr = 0; - cell++; - } + std::fill(_cells_front.begin(), _cells_front.end(), TerminalCell()); } void TerminalScreen::putch(int x, int y, Uint16 ch, Uint16 attr) { - TerminalCell &cell = _cells[y * _width + x]; + TerminalCell &cell = _cells_front[y * _width + x]; cell.ch = ch; cell.attr = attr; } @@ -210,18 +201,24 @@ void TerminalScreen::commit() { - TerminalCell * cell = _cells; + auto front_iter = _cells_front.begin(); + auto back_iter = _cells_back.begin(); SDL_Surface *glyph_surface; SDL_Rect dst_rect; for (int y = 0; y < _height; y++) { for (int x = 0; x < _width; x++) { - dst_rect.x = x * _cell_width; - dst_rect.y = y * _cell_height; - glyph_surface = _render.render_glyph(cell->ch); - SDL_BlitSurface(glyph_surface, NULL, _screen_surface, &dst_rect); - cell++; + if (*front_iter != *back_iter) + { + dst_rect.x = x * _cell_width; + dst_rect.y = y * _cell_height; + glyph_surface = _render.render_glyph(front_iter->ch); + SDL_BlitSurface(glyph_surface, NULL, _screen_surface, &dst_rect); + *back_iter = *front_iter; + } + front_iter++; + back_iter++; } } @@ -231,24 +228,19 @@ void TerminalScreen::_reset_cells() { - if (_cells) - { - delete[] _cells; - _cells = NULL; - } - _cell_width = _render.get_cell_width(); _cell_height = _render.get_cell_height(); _width = _pixel_width / _cell_width; _height = _pixel_height / _cell_height; int num_cells = _width * _height; - _cells = new TerminalCell[num_cells]; + _cells_front.resize(num_cells); + _cells_back.resize(num_cells); } Terminal::Terminal() - : _screen() + : _screen(), _mousemove_last_x(-1) { if (SDL_Init(SDL_INIT_VIDEO) == -1) { @@ -267,7 +259,7 @@ void Terminal::get_next_event(Event &event) { - SDL_Event sdl_event; + static SDL_Event sdl_event; while (SDL_WaitEvent(&sdl_event)) { @@ -278,11 +270,25 @@ return; case SDL_KEYDOWN: + { //switch(event.key.keysym.sym) event.type = Event::KEYPRESS; - event.key.unicode = sdl_event.key.keysym.unicode; - strncpy(event.key.keyname, _translate_keyname(sdl_event.key.keysym.sym), 10); + const char *keyname = _translate_keyname(sdl_event.key.keysym.sym); + // return only keyname or unicode, never both + if (keyname) + { + strncpy(event.key.keyname, keyname, 10); + event.key.unicode = 0; + } + else + { + event.key.keyname[0] = 0; + event.key.unicode = sdl_event.key.keysym.unicode; + if (!event.key.unicode) + break; // continue loop (unknown key) + } return; + } case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: @@ -290,13 +296,21 @@ event.mouse.x = sdl_event.button.x / _screen.get_cell_width(); event.mouse.y = sdl_event.button.y / _screen.get_cell_height(); event.mouse.button = sdl_event.button.button; + _mousemove_last_x = -1; return; case SDL_MOUSEMOTION: event.type = Event::MOUSEMOVE; event.mouse.x = sdl_event.motion.x / _screen.get_cell_width(); event.mouse.y = sdl_event.motion.y / _screen.get_cell_height(); - return; + if (_mousemove_last_x != event.mouse.x || + _mousemove_last_y != event.mouse.y) + { + _mousemove_last_x = event.mouse.x; + _mousemove_last_y = event.mouse.y; + return; + } + break; // continue loop when mouse position did not change default: break; // continue loop @@ -337,7 +351,7 @@ case SDLK_F10: return "f10"; case SDLK_F11: return "f11"; case SDLK_F12: return "f12"; - default: return ""; + default: return NULL; } } diff -r 1f00e90fd72a -r 1611c462c3e3 sdlterm/src/sdlterm.h --- a/sdlterm/src/sdlterm.h Sat Jan 05 12:40:32 2013 +0100 +++ b/sdlterm/src/sdlterm.h Sat Jan 05 16:47:30 2013 +0100 @@ -45,14 +45,15 @@ { Uint16 ch; Uint16 attr; + bool operator !=(const TerminalCell &rhs) const { return ch != rhs.ch || attr != rhs.attr; }; }; class TerminalScreen { public: - TerminalScreen(): _screen_surface(NULL), _cells(NULL), _render() {}; - ~TerminalScreen(); + TerminalScreen(): _screen_surface(NULL), _render() {}; + ~TerminalScreen() {}; void select_font(const char *fname_regular, const char *fname_bold, int ptsize); void resize(int pxwidth, int pxheight); @@ -68,7 +69,8 @@ private: SDL_Surface *_screen_surface; - TerminalCell *_cells; + std::vector _cells_front; + std::vector _cells_back; GlyphRenderer _render; int _pixel_width; // terminal window width in pixels @@ -135,6 +137,9 @@ int _cursor_y; bool _cursor_visible; + int _mousemove_last_x; + int _mousemove_last_y; + const char *_translate_keyname(SDLKey sym); }; diff -r 1f00e90fd72a -r 1611c462c3e3 tuikit/application.py --- a/tuikit/application.py Sat Jan 05 12:40:32 2013 +0100 +++ b/tuikit/application.py Sat Jan 05 16:47:30 2013 +0100 @@ -67,7 +67,7 @@ '''Application class. Defines main loop.''' - def __init__(self, driver = 'curses'): + def __init__(self, driver = 'sdl'): '''Create application.''' self.top = TopWindow()