# HG changeset patch # User Radek Brich # Date 1357476902 -3600 # Node ID c4263588b716b04f043988f319cac6ad80beffe2 # Parent 50a1857557da211581a686b295dfc95c8c09c930 DriverSDL: Implement cursor, handle window resize. diff -r 50a1857557da -r c4263588b716 sdlterm/cython/sdlterm.pyx --- a/sdlterm/cython/sdlterm.pyx Sat Jan 05 23:00:41 2013 +0100 +++ b/sdlterm/cython/sdlterm.pyx Sun Jan 06 13:55:02 2013 +0100 @@ -45,8 +45,8 @@ int prepare_attr(int fg, int bg, int style) void set_attr(int value) - void set_cursor(int x, int y) - void show_cursor(bool visible) + void show_cursor(int x, int y) + void hide_cursor() void get_next_event(Event event) @@ -82,6 +82,11 @@ def set_attr(self, value): self.thisptr.set_attr(value) + def show_cursor(self, x, y): + self.thisptr.show_cursor(x, y) + def hide_cursor(self): + self.thisptr.hide_cursor() + def get_next_event(self): self.thisptr.get_next_event(self.event) event = self.event @@ -101,6 +106,8 @@ if char == '\x00': char = None return ('keypress', keyname, char) + if event.type == event.RESIZE: + return ('resize',) if event.type == event.QUIT: return ('quit',) return ('unknown',) diff -r 50a1857557da -r c4263588b716 sdlterm/src/sdlterm.cc --- a/sdlterm/src/sdlterm.cc Sat Jan 05 23:00:41 2013 +0100 +++ b/sdlterm/src/sdlterm.cc Sun Jan 06 13:55:02 2013 +0100 @@ -176,7 +176,7 @@ SDL_LockSurface(cell_surface); int y = 1 + TTF_FontAscent(font); Uint32 fgcolor_mapped = SDL_MapRGB(cell_surface->format, fgcolor.r, fgcolor.g, fgcolor.b); - Uint32 *p = (Uint32 *)(cell_surface->pixels + y * cell_surface->pitch); + Uint32 *p = (Uint32 *)((Uint8 *)cell_surface->pixels + y * cell_surface->pitch); for (int x = 0; x < _cell_width; x++) *p++ = fgcolor_mapped; SDL_UnlockSurface(cell_surface); @@ -225,8 +225,6 @@ throw std::exception(); } - SDL_WM_SetCaption("terminal", NULL); - _pixel_width = pxwidth; _pixel_height = pxheight; @@ -248,6 +246,13 @@ } +void TerminalScreen::toggle_cursor(int x, int y) +{ + TerminalCell &cell = _cells_front[y * _width + x]; + cell.attr ^= (Style::STANDOUT << 24); +} + + void TerminalScreen::commit() { auto front_iter = _cells_front.begin(); @@ -275,6 +280,13 @@ } +void TerminalScreen::redraw() +{ + // clear back buffer, current screen is considered blank + std::fill(_cells_back.begin(), _cells_back.end(), TerminalCell()); +} + + void TerminalScreen::_reset_cells() { _cell_width = _render.get_cell_width(); @@ -289,12 +301,13 @@ int num_cells = _width * _height; _cells_front.resize(num_cells, TerminalCell()); - _cells_back.resize(num_cells, TerminalCell()); + _cells_back.resize(num_cells); + redraw(); } Terminal::Terminal() - : _screen(), _attr(7), _mousemove_last_x(-1) + : _screen(), _attr(7), _cursor_visible(false), _mousemove_last_x(-1) { if (SDL_Init(SDL_INIT_VIDEO) == -1) { @@ -302,6 +315,7 @@ throw std::exception(); } SDL_EnableUNICODE(1); + SDL_WM_SetCaption("terminal", NULL); } @@ -311,6 +325,20 @@ } +void Terminal::commit() +{ + if (_cursor_visible) + { + _screen.toggle_cursor(_cursor_x, _cursor_y); + _screen.commit(); + _screen.toggle_cursor(_cursor_x, _cursor_y); + } + else + { + _screen.commit(); + } +} + void Terminal::get_next_event(Event &event) { static SDL_Event sdl_event; @@ -323,6 +351,15 @@ event.type = Event::QUIT; return; + case SDL_VIDEORESIZE: + event.type = Event::RESIZE; + _screen.resize(sdl_event.resize.w, sdl_event.resize.h); + return; + + case SDL_VIDEOEXPOSE: + _screen.redraw(); + break; + case SDL_KEYDOWN: { //switch(event.key.keysym.sym) @@ -354,6 +391,8 @@ return; case SDL_MOUSEMOTION: + if (sdl_event.motion.state == 0) + break; // continue loop, do not report move events when no button is pressed 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(); diff -r 50a1857557da -r c4263588b716 sdlterm/src/sdlterm.h --- a/sdlterm/src/sdlterm.h Sat Jan 05 23:00:41 2013 +0100 +++ b/sdlterm/src/sdlterm.h Sun Jan 06 13:55:02 2013 +0100 @@ -37,7 +37,7 @@ }; public: - void index_to_rgb(int index, SDL_Color &color); + void index_to_rgb(int index, SDL_Color &color) const; }; @@ -66,8 +66,8 @@ // do not free surface returned! SDL_Surface *render_cell(Uint32 ch, Uint32 attr); - int get_cell_width() { return _cell_width; }; - int get_cell_height() { return _cell_height; }; + int get_cell_width() const { return _cell_width; }; + int get_cell_height() const { return _cell_height; }; private: TTF_Font *_font_regular; @@ -100,6 +100,8 @@ { Uint32 ch; Uint32 attr; + + TerminalCell() : ch(0), attr(7) {}; bool operator !=(const TerminalCell &rhs) const { return ch != rhs.ch || attr != rhs.attr; }; }; @@ -118,12 +120,16 @@ void erase(); void putch(int x, int y, Uint32 ch, Uint32 attr); + void toggle_cursor(int x, int y); void commit(); - int get_width() { return _width; }; - int get_height() { return _height; }; - int get_cell_width() { return _cell_width; }; - int get_cell_height() { return _cell_height; }; + // force full redraw on next commit() + void redraw(); + + int get_width() const { return _width; }; + int get_height() const { return _height; }; + int get_cell_width() const { return _cell_width; }; + int get_cell_height() const { return _cell_height; }; private: SDL_Surface *_screen_surface; @@ -175,18 +181,18 @@ void erase() { _screen.erase(); }; void putch(int x, int y, Uint32 ch) { _screen.putch(x, y, ch, _attr); }; - void commit() { _screen.commit(); }; + void commit(); Uint32 prepare_attr(Uint8 fg, Uint8 bg, Uint8 style) { return (Uint32)fg | (Uint32)bg << 8 | (Uint32)style << 24; }; void set_attr(Uint32 value) { _attr = value; }; - void set_cursor(int x, int y) { _cursor_x = x; _cursor_y = y; }; - void show_cursor(bool visible) { _cursor_visible = visible; }; + void show_cursor(int x, int y) { _cursor_x = x; _cursor_y = y; _cursor_visible = true; }; + void hide_cursor() { _cursor_visible = false; }; void get_next_event(Event &event); - int get_width() { return _screen.get_width(); }; - int get_height() { return _screen.get_height(); }; + int get_width() const { return _screen.get_width(); }; + int get_height() const { return _screen.get_height(); }; private: TerminalScreen _screen; diff -r 50a1857557da -r c4263588b716 tuikit/driver_sdl.py --- a/tuikit/driver_sdl.py Sat Jan 05 23:00:41 2013 +0100 +++ b/tuikit/driver_sdl.py Sun Jan 06 13:55:02 2013 +0100 @@ -67,6 +67,8 @@ def getevents(self, timeout=None): '''Process input, return list of events.''' event = self.sdlterm.get_next_event() + if event[0] == 'resize': + self.size.w, self.size.h = self.sdlterm.width, self.sdlterm.height return [event] @@ -139,11 +141,13 @@ def showcursor(self, x, y): '''Set cursor to be shown at x, y coordinates.''' - self.log.info('DummyDriver.showcursor(x=%r, y=%r)', x, y) + if not self.clipstack.test(x, y): + return + self.sdlterm.show_cursor(x, y) def hidecursor(self): '''Hide cursor.''' - self.log.info('DummyDriver.hidecursor()') + self.sdlterm.hide_cursor() driverclass = DriverSDL