sdlterm/src/sdlterm.cc
changeset 48 1f00e90fd72a
parent 47 537d7c6b48a2
child 49 1611c462c3e3
--- a/sdlterm/src/sdlterm.cc	Sat Jan 05 00:40:27 2013 +0100
+++ b/sdlterm/src/sdlterm.cc	Sat Jan 05 12:40:32 2013 +0100
@@ -3,6 +3,33 @@
 #include <stdexcept>
 
 
+SDL_Surface *GlyphCache::lookup_glyph(Uint16 ch)
+{
+	auto iter = _glyph_map.find(ch);
+	if (iter == _glyph_map.end())
+	{
+		return NULL;
+	}
+	return iter->second;
+}
+
+
+void GlyphCache::put_glyph(Uint16 ch, SDL_Surface *srf)
+{
+	_glyph_map[ch] = srf;
+}
+
+
+void GlyphCache::flush()
+{
+	for (auto iter = _glyph_map.begin(); iter != _glyph_map.end(); iter++)
+	{
+		SDL_FreeSurface(iter->second);
+	}
+	_glyph_map.clear();
+}
+
+
 GlyphRenderer::GlyphRenderer()
  : _font_regular(NULL), _font_bold(NULL)
 {
@@ -16,6 +43,7 @@
 
 GlyphRenderer::~GlyphRenderer()
 {
+	_cache.flush();
 	close_font();
 	TTF_Quit();
 }
@@ -84,6 +112,15 @@
 
 SDL_Surface *GlyphRenderer::render_glyph(Uint16 ch)
 {
+	SDL_Surface *cell_surface;
+
+	// try cache
+	cell_surface = _cache.lookup_glyph(ch);
+	if (cell_surface)
+	{
+		return cell_surface;
+	}
+
 	TTF_Font *font = _font_regular;
 	SDL_Color color={0xff,0xff,0xff}, bgcolor={0,100,100};
 	if (ch != 'W')
@@ -93,7 +130,7 @@
 	}
 
 	// create surface for whole cell and fill it with bg color
-	SDL_Surface *cell_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
+	cell_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
 			_cell_width, _cell_height, 32, 0, 0, 0, 0);
 	SDL_Rect dst_rect;
 	dst_rect.x = 0;
@@ -112,6 +149,7 @@
 	SDL_BlitSurface(glyph_surface, NULL, cell_surface, &dst_rect);
 	SDL_FreeSurface(glyph_surface);
 
+	_cache.put_glyph(ch, cell_surface);
 	return cell_surface;
 }
 
@@ -133,7 +171,7 @@
 
 void TerminalScreen::resize(int pxwidth, int pxheight)
 {
-    _screen_surface = SDL_SetVideoMode(pxwidth, pxheight, 8, SDL_SWSURFACE|SDL_ANYFORMAT|SDL_RESIZABLE);
+    _screen_surface = SDL_SetVideoMode(pxwidth, pxheight, 32, SDL_HWSURFACE|SDL_RESIZABLE);
 
     if (_screen_surface == NULL)
     {
@@ -183,7 +221,6 @@
 			dst_rect.y = y * _cell_height;
 			glyph_surface = _render.render_glyph(cell->ch);
 			SDL_BlitSurface(glyph_surface, NULL, _screen_surface, &dst_rect);
-			SDL_FreeSurface(glyph_surface);
 			cell++;
 		}
 	}
@@ -218,6 +255,7 @@
 		fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
 		throw std::exception();
     }
+    SDL_EnableUNICODE(1);
 }
 
 
@@ -236,12 +274,28 @@
 		switch (sdl_event.type)
 		{
 			case SDL_QUIT:
-				event.type = EventType::quit;
+				event.type = Event::QUIT;
 				return;
 
 			case SDL_KEYDOWN:
 				//switch(event.key.keysym.sym)
-				event.type = EventType::keypress;
+				event.type = Event::KEYPRESS;
+				event.key.unicode = sdl_event.key.keysym.unicode;
+				strncpy(event.key.keyname, _translate_keyname(sdl_event.key.keysym.sym), 10);
+				return;
+
+			case SDL_MOUSEBUTTONDOWN:
+			case SDL_MOUSEBUTTONUP:
+				event.type = (sdl_event.type == SDL_MOUSEBUTTONDOWN) ? Event::MOUSEDOWN : Event::MOUSEUP;
+				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;
+				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;
 
 			default:
@@ -249,3 +303,41 @@
 		}
 	}
 }
+
+
+const char *Terminal::_translate_keyname(SDLKey sym)
+{
+	switch (sym)
+	{
+		case SDLK_BACKSPACE: 	return "backspace";
+		case SDLK_TAB:			return "tab";
+		case SDLK_RETURN:		return "enter";
+		case SDLK_KP_ENTER:		return "enter";
+		case SDLK_PAUSE:	    return "pause";
+		case SDLK_ESCAPE:		return "escape";
+		case SDLK_DELETE:		return "delete";
+		case SDLK_INSERT:		return "insert";
+		case SDLK_UP:			return "up";
+		case SDLK_DOWN:			return "down";
+		case SDLK_LEFT:			return "left";
+		case SDLK_RIGHT:		return "right";
+		case SDLK_HOME:			return "home";
+		case SDLK_END:			return "end";
+		case SDLK_PAGEUP:		return "pageup";
+		case SDLK_PAGEDOWN:		return "pagedown";
+		case SDLK_F1:			return "f1";
+		case SDLK_F2:			return "f2";
+		case SDLK_F3:			return "f3";
+		case SDLK_F4:			return "f4";
+		case SDLK_F5:			return "f5";
+		case SDLK_F6:			return "f6";
+		case SDLK_F7:			return "f7";
+		case SDLK_F8:			return "f8";
+		case SDLK_F9:			return "f9";
+		case SDLK_F10:			return "f10";
+		case SDLK_F11:			return "f11";
+		case SDLK_F12:			return "f12";
+		default: return "";
+	}
+}
+