4 #include <algorithm> |
4 #include <algorithm> |
5 |
5 |
6 |
6 |
7 void ColorMap::index_to_rgb(int index, SDL_Color &color) |
7 void ColorMap::index_to_rgb(int index, SDL_Color &color) |
8 { |
8 { |
9 color.r = _map[index][0]; |
9 color.r = _map[index][0]; |
10 color.g = _map[index][1]; |
10 color.g = _map[index][1]; |
11 color.b = _map[index][2]; |
11 color.b = _map[index][2]; |
12 } |
12 } |
13 |
13 |
14 |
14 |
15 SDL_Surface *GlyphCache::lookup_glyph(Uint16 ch) |
15 SDL_Surface *GlyphCache::lookup_glyph(Uint16 ch) |
16 { |
16 { |
17 auto iter = _glyph_map.find(ch); |
17 auto iter = _glyph_map.find(ch); |
18 if (iter == _glyph_map.end()) |
18 if (iter == _glyph_map.end()) |
19 { |
19 { |
20 return NULL; |
20 return NULL; |
21 } |
21 } |
22 return iter->second; |
22 return iter->second; |
23 } |
23 } |
24 |
24 |
25 |
25 |
26 void GlyphCache::put_glyph(Uint16 ch, SDL_Surface *srf) |
26 void GlyphCache::put_glyph(Uint16 ch, SDL_Surface *srf) |
27 { |
27 { |
28 _glyph_map[ch] = srf; |
28 _glyph_map[ch] = srf; |
29 } |
29 } |
30 |
30 |
31 |
31 |
32 void GlyphCache::flush() |
32 void GlyphCache::flush() |
33 { |
33 { |
34 for (auto iter = _glyph_map.begin(); iter != _glyph_map.end(); iter++) |
34 for (auto iter = _glyph_map.begin(); iter != _glyph_map.end(); iter++) |
35 { |
35 { |
36 SDL_FreeSurface(iter->second); |
36 SDL_FreeSurface(iter->second); |
37 } |
37 } |
38 _glyph_map.clear(); |
38 _glyph_map.clear(); |
39 } |
39 } |
40 |
40 |
41 |
41 |
42 GlyphRenderer::GlyphRenderer() |
42 GlyphRenderer::GlyphRenderer() |
43 : _font_regular(NULL), _font_bold(NULL), _cell_width(0), _cell_height(0), _cache(), _colormap() |
43 : _font_regular(NULL), _font_bold(NULL), _cell_width(0), _cell_height(0), _cache(), _colormap() |
44 { |
44 { |
45 if (TTF_Init() == -1) |
45 if (TTF_Init() == -1) |
46 { |
46 { |
47 printf("TTF_Init: %s\n", TTF_GetError()); |
47 printf("TTF_Init: %s\n", TTF_GetError()); |
48 throw std::exception(); |
48 throw std::exception(); |
49 } |
49 } |
50 } |
50 } |
51 |
51 |
52 |
52 |
53 GlyphRenderer::~GlyphRenderer() |
53 GlyphRenderer::~GlyphRenderer() |
54 { |
54 { |
55 _cache.flush(); |
55 _cache.flush(); |
56 close_font(); |
56 close_font(); |
57 TTF_Quit(); |
57 TTF_Quit(); |
58 } |
58 } |
59 |
59 |
60 |
60 |
61 void GlyphRenderer::open_font(const char *fname_regular, const char *fname_bold, int ptsize) |
61 void GlyphRenderer::open_font(const char *fname_regular, const char *fname_bold, int ptsize) |
62 { |
62 { |
63 close_font(); |
63 close_font(); |
64 |
64 |
65 // open regular font |
65 // open regular font |
66 _font_regular = TTF_OpenFont(fname_regular, ptsize); |
66 _font_regular = TTF_OpenFont(fname_regular, ptsize); |
67 if (!_font_regular) |
67 if (!_font_regular) |
68 { |
68 { |
69 printf("TTF_OpenFont: %s\n", TTF_GetError()); |
69 printf("TTF_OpenFont: %s\n", TTF_GetError()); |
70 throw std::exception(); |
70 throw std::exception(); |
71 } |
71 } |
72 |
72 |
73 // open bold font |
73 // open bold font |
74 _font_bold = TTF_OpenFont(fname_bold, ptsize); |
74 _font_bold = TTF_OpenFont(fname_bold, ptsize); |
75 if (!_font_bold) |
75 if (!_font_bold) |
76 { |
76 { |
77 printf("TTF_OpenFont: %s\n", TTF_GetError()); |
77 printf("TTF_OpenFont: %s\n", TTF_GetError()); |
78 throw std::exception(); |
78 throw std::exception(); |
79 } |
79 } |
80 |
80 |
81 // update metrics for regular font |
81 // update metrics for regular font |
82 int advance; |
82 int advance; |
83 if (TTF_GlyphMetrics(_font_regular, 'M', NULL, NULL, NULL, NULL, &advance) == -1) |
83 if (TTF_GlyphMetrics(_font_regular, 'M', NULL, NULL, NULL, NULL, &advance) == -1) |
84 { |
84 { |
85 printf("TTF_GlyphMetrics: %s\n", TTF_GetError()); |
85 printf("TTF_GlyphMetrics: %s\n", TTF_GetError()); |
86 } |
86 } |
87 _cell_width = advance; |
87 _cell_width = advance; |
88 _cell_height = TTF_FontHeight(_font_regular); |
88 _cell_height = TTF_FontHeight(_font_regular); |
89 |
89 |
90 // read metrics for bold font |
90 // read metrics for bold font |
91 if (TTF_GlyphMetrics(_font_bold, 'M', NULL, NULL, NULL, NULL, &advance) == -1) |
91 if (TTF_GlyphMetrics(_font_bold, 'M', NULL, NULL, NULL, NULL, &advance) == -1) |
92 { |
92 { |
93 printf("TTF_GlyphMetrics: %s\n", TTF_GetError()); |
93 printf("TTF_GlyphMetrics: %s\n", TTF_GetError()); |
94 } |
94 } |
95 if (advance > _cell_width) |
95 if (advance > _cell_width) |
96 { |
96 { |
97 _cell_width = advance; |
97 _cell_width = advance; |
98 } |
98 } |
99 int height = TTF_FontHeight(_font_bold); |
99 int height = TTF_FontHeight(_font_bold); |
100 if (height > _cell_height) |
100 if (height > _cell_height) |
101 { |
101 { |
102 _cell_height = height; |
102 _cell_height = height; |
103 } |
103 } |
104 } |
104 } |
105 |
105 |
106 |
106 |
107 void GlyphRenderer::close_font() |
107 void GlyphRenderer::close_font() |
108 { |
108 { |
109 if (_font_regular) |
109 if (_font_regular) |
110 { |
110 { |
111 TTF_CloseFont(_font_regular); |
111 TTF_CloseFont(_font_regular); |
112 _font_regular = NULL; |
112 _font_regular = NULL; |
113 } |
113 } |
114 if (_font_bold) |
114 if (_font_bold) |
115 { |
115 { |
116 TTF_CloseFont(_font_bold); |
116 TTF_CloseFont(_font_bold); |
117 _font_bold = NULL; |
117 _font_bold = NULL; |
118 } |
118 } |
119 } |
119 } |
120 |
120 |
121 |
121 |
122 SDL_Surface *GlyphRenderer::render_cell(Uint16 ch, Uint16 attr) |
122 SDL_Surface *GlyphRenderer::render_cell(Uint16 ch, Uint16 attr) |
123 { |
123 { |
124 SDL_Surface *cell_surface; |
124 SDL_Surface *cell_surface; |
125 TTF_Font *font; |
125 TTF_Font *font; |
126 SDL_Color fgcolor, bgcolor; |
126 SDL_Color fgcolor, bgcolor; |
127 |
127 |
128 // try cache |
128 // try cache |
129 cell_surface = _cache.lookup_glyph(ch); |
129 cell_surface = _cache.lookup_glyph(ch); |
130 if (cell_surface) |
130 if (cell_surface) |
131 { |
131 { |
132 return cell_surface; |
132 return cell_surface; |
133 } |
133 } |
134 |
134 |
135 // load attributes |
135 // load attributes |
136 _colormap.index_to_rgb(attr & 0x000F, fgcolor); |
136 _colormap.index_to_rgb(attr & 0x000F, fgcolor); |
137 _colormap.index_to_rgb((attr & 0x00F0) >> 4, bgcolor); |
137 _colormap.index_to_rgb((attr & 0x00F0) >> 4, bgcolor); |
138 Style style = (Style) ((attr & 0xFF00) >> 8); |
138 Style style = (Style) ((attr & 0xFF00) >> 8); |
139 font = (style == Style::BOLD) ? _font_bold : _font_regular; |
139 font = (style == Style::BOLD) ? _font_bold : _font_regular; |
140 |
140 |
141 // create surface for whole cell and fill it with bg color |
141 // create surface for whole cell and fill it with bg color |
142 cell_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, |
142 cell_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, |
143 _cell_width, _cell_height, 32, 0, 0, 0, 0); |
143 _cell_width, _cell_height, 32, 0, 0, 0, 0); |
144 SDL_Rect dst_rect; |
144 SDL_Rect dst_rect; |
145 dst_rect.x = 0; |
145 dst_rect.x = 0; |
146 dst_rect.y = 0; |
146 dst_rect.y = 0; |
147 dst_rect.w = _cell_width; |
147 dst_rect.w = _cell_width; |
148 dst_rect.h = _cell_height; |
148 dst_rect.h = _cell_height; |
149 Uint32 bgcolor_mapped = SDL_MapRGB(cell_surface->format, bgcolor.r, bgcolor.g, bgcolor.b); |
149 Uint32 bgcolor_mapped = SDL_MapRGB(cell_surface->format, bgcolor.r, bgcolor.g, bgcolor.b); |
150 SDL_FillRect(cell_surface, &dst_rect, bgcolor_mapped); |
150 SDL_FillRect(cell_surface, &dst_rect, bgcolor_mapped); |
151 |
151 |
152 // render glyph, blit it onto cell surface |
152 // render glyph, blit it onto cell surface |
153 if (ch) |
153 if (ch) |
154 { |
154 { |
155 SDL_Surface *glyph_surface = TTF_RenderGlyph_Shaded(font, ch, fgcolor, bgcolor); |
155 SDL_Surface *glyph_surface = TTF_RenderGlyph_Shaded(font, ch, fgcolor, bgcolor); |
156 int minx, maxy; |
156 int minx, maxy; |
157 TTF_GlyphMetrics(font, ch, &minx, NULL, NULL, &maxy, NULL); |
157 TTF_GlyphMetrics(font, ch, &minx, NULL, NULL, &maxy, NULL); |
158 dst_rect.x = minx; |
158 dst_rect.x = minx; |
159 dst_rect.y = TTF_FontAscent(font) - maxy; |
159 dst_rect.y = TTF_FontAscent(font) - maxy; |
160 SDL_BlitSurface(glyph_surface, NULL, cell_surface, &dst_rect); |
160 SDL_BlitSurface(glyph_surface, NULL, cell_surface, &dst_rect); |
161 SDL_FreeSurface(glyph_surface); |
161 SDL_FreeSurface(glyph_surface); |
162 } |
162 } |
163 |
163 |
164 // convert to display format |
164 // convert to display format |
165 SDL_Surface *tmp_surface = cell_surface; |
165 SDL_Surface *tmp_surface = cell_surface; |
166 cell_surface = SDL_DisplayFormat(tmp_surface); |
166 cell_surface = SDL_DisplayFormat(tmp_surface); |
167 SDL_FreeSurface(tmp_surface); |
167 SDL_FreeSurface(tmp_surface); |
168 |
168 |
169 // put to cache |
169 // put to cache |
170 _cache.put_glyph(ch, cell_surface); |
170 _cache.put_glyph(ch, cell_surface); |
171 |
171 |
172 return cell_surface; |
172 return cell_surface; |
173 } |
173 } |
174 |
174 |
175 |
175 |
176 void TerminalScreen::select_font(const char *fname_regular, const char *fname_bold, int ptsize) |
176 void TerminalScreen::select_font(const char *fname_regular, const char *fname_bold, int ptsize) |
177 { |
177 { |
178 _render.open_font(fname_regular, fname_bold, ptsize); |
178 _render.open_font(fname_regular, fname_bold, ptsize); |
179 _reset_cells(); |
179 _reset_cells(); |
180 } |
180 } |
181 |
181 |
182 void TerminalScreen::resize(int pxwidth, int pxheight) |
182 void TerminalScreen::resize(int pxwidth, int pxheight) |
183 { |
183 { |
184 _screen_surface = SDL_SetVideoMode(pxwidth, pxheight, 0, SDL_SWSURFACE|SDL_ANYFORMAT|SDL_RESIZABLE); |
184 _screen_surface = SDL_SetVideoMode(pxwidth, pxheight, 0, SDL_SWSURFACE|SDL_ANYFORMAT|SDL_RESIZABLE); |
185 |
185 |
186 if (_screen_surface == NULL) |
186 if (_screen_surface == NULL) |
187 { |
187 { |
188 fprintf(stderr, "Unable to set video: %s\n", SDL_GetError()); |
188 fprintf(stderr, "Unable to set video: %s\n", SDL_GetError()); |
189 throw std::exception(); |
189 throw std::exception(); |
190 } |
190 } |
191 |
191 |
192 SDL_WM_SetCaption("terminal", NULL); |
192 SDL_WM_SetCaption("terminal", NULL); |
193 |
193 |
194 _pixel_width = pxwidth; |
194 _pixel_width = pxwidth; |
198 } |
198 } |
199 |
199 |
200 |
200 |
201 void TerminalScreen::erase() |
201 void TerminalScreen::erase() |
202 { |
202 { |
203 std::fill(_cells_front.begin(), _cells_front.end(), TerminalCell()); |
203 std::fill(_cells_front.begin(), _cells_front.end(), TerminalCell()); |
204 } |
204 } |
205 |
205 |
206 |
206 |
207 void TerminalScreen::putch(int x, int y, Uint16 ch, Uint16 attr) |
207 void TerminalScreen::putch(int x, int y, Uint16 ch, Uint16 attr) |
208 { |
208 { |
209 TerminalCell &cell = _cells_front[y * _width + x]; |
209 TerminalCell &cell = _cells_front[y * _width + x]; |
210 cell.ch = ch; |
210 cell.ch = ch; |
211 cell.attr = attr; |
211 cell.attr = attr; |
212 } |
212 } |
213 |
213 |
214 |
214 |
215 void TerminalScreen::commit() |
215 void TerminalScreen::commit() |
216 { |
216 { |
217 auto front_iter = _cells_front.begin(); |
217 auto front_iter = _cells_front.begin(); |
218 auto back_iter = _cells_back.begin(); |
218 auto back_iter = _cells_back.begin(); |
219 SDL_Surface *cell_surface; |
219 SDL_Surface *cell_surface; |
220 SDL_Rect dst_rect; |
220 SDL_Rect dst_rect; |
221 for (int y = 0; y < _height; y++) |
221 for (int y = 0; y < _height; y++) |
222 { |
222 { |
223 for (int x = 0; x < _width; x++) |
223 for (int x = 0; x < _width; x++) |
224 { |
224 { |
225 if (*front_iter != *back_iter) |
225 if (*front_iter != *back_iter) |
226 { |
226 { |
227 dst_rect.x = x * _cell_width; |
227 dst_rect.x = x * _cell_width; |
228 dst_rect.y = y * _cell_height; |
228 dst_rect.y = y * _cell_height; |
229 cell_surface = _render.render_cell(front_iter->ch, front_iter->attr); |
229 cell_surface = _render.render_cell(front_iter->ch, front_iter->attr); |
230 SDL_BlitSurface(cell_surface, NULL, _screen_surface, &dst_rect); |
230 SDL_BlitSurface(cell_surface, NULL, _screen_surface, &dst_rect); |
231 *back_iter = *front_iter; |
231 *back_iter = *front_iter; |
232 } |
232 } |
233 front_iter++; |
233 front_iter++; |
234 back_iter++; |
234 back_iter++; |
235 } |
235 } |
236 } |
236 } |
237 |
237 |
238 SDL_UpdateRect(_screen_surface, 0, 0, 0, 0); |
238 SDL_UpdateRect(_screen_surface, 0, 0, 0, 0); |
239 } |
239 } |
240 |
240 |
241 |
241 |
242 void TerminalScreen::_reset_cells() |
242 void TerminalScreen::_reset_cells() |
243 { |
243 { |
244 _cell_width = _render.get_cell_width(); |
244 _cell_width = _render.get_cell_width(); |
245 _cell_height = _render.get_cell_height(); |
245 _cell_height = _render.get_cell_height(); |
246 if (!_cell_width || !_cell_height) |
246 if (!_cell_width || !_cell_height) |
247 return; |
247 return; |
248 |
248 |
249 _width = _pixel_width / _cell_width; |
249 _width = _pixel_width / _cell_width; |
250 _height = _pixel_height / _cell_height; |
250 _height = _pixel_height / _cell_height; |
251 if (!_width || !_height) |
251 if (!_width || !_height) |
252 return; |
252 return; |
253 |
253 |
254 int num_cells = _width * _height; |
254 int num_cells = _width * _height; |
255 _cells_front.resize(num_cells, TerminalCell()); |
255 _cells_front.resize(num_cells, TerminalCell()); |
256 _cells_back.resize(num_cells, TerminalCell()); |
256 _cells_back.resize(num_cells, TerminalCell()); |
257 } |
257 } |
258 |
258 |
259 |
259 |
260 Terminal::Terminal() |
260 Terminal::Terminal() |
261 : _screen(), _attr(7), _mousemove_last_x(-1) |
261 : _screen(), _attr(7), _mousemove_last_x(-1) |
262 { |
262 { |
263 if (SDL_Init(SDL_INIT_VIDEO) == -1) |
263 if (SDL_Init(SDL_INIT_VIDEO) == -1) |
264 { |
264 { |
265 fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError()); |
265 fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError()); |
266 throw std::exception(); |
266 throw std::exception(); |
267 } |
267 } |
268 SDL_EnableUNICODE(1); |
268 SDL_EnableUNICODE(1); |
269 } |
269 } |
270 |
270 |
271 |
271 |
272 Terminal::~Terminal() |
272 Terminal::~Terminal() |
273 { |
273 { |
274 SDL_Quit(); |
274 SDL_Quit(); |
275 } |
275 } |
276 |
276 |
277 |
277 |
278 void Terminal::get_next_event(Event &event) |
278 void Terminal::get_next_event(Event &event) |
279 { |
279 { |
280 static SDL_Event sdl_event; |
280 static SDL_Event sdl_event; |
281 |
281 |
282 while (SDL_WaitEvent(&sdl_event)) |
282 while (SDL_WaitEvent(&sdl_event)) |
283 { |
283 { |
284 switch (sdl_event.type) |
284 switch (sdl_event.type) |
285 { |
285 { |
286 case SDL_QUIT: |
286 case SDL_QUIT: |
287 event.type = Event::QUIT; |
287 event.type = Event::QUIT; |
288 return; |
288 return; |
289 |
289 |
290 case SDL_KEYDOWN: |
290 case SDL_KEYDOWN: |
291 { |
291 { |
292 //switch(event.key.keysym.sym) |
292 //switch(event.key.keysym.sym) |
293 event.type = Event::KEYPRESS; |
293 event.type = Event::KEYPRESS; |
294 const char *keyname = _translate_keyname(sdl_event.key.keysym.sym); |
294 const char *keyname = _translate_keyname(sdl_event.key.keysym.sym); |
295 // return only keyname or unicode, never both |
295 // return only keyname or unicode, never both |
296 if (keyname) |
296 if (keyname) |
297 { |
297 { |
298 strncpy(event.key.keyname, keyname, 10); |
298 strncpy(event.key.keyname, keyname, 10); |
299 event.key.unicode = 0; |
299 event.key.unicode = 0; |
300 } |
300 } |
301 else |
301 else |
302 { |
302 { |
303 event.key.keyname[0] = 0; |
303 event.key.keyname[0] = 0; |
304 event.key.unicode = sdl_event.key.keysym.unicode; |
304 event.key.unicode = sdl_event.key.keysym.unicode; |
305 if (!event.key.unicode) |
305 if (!event.key.unicode) |
306 break; // continue loop (unknown key) |
306 break; // continue loop (unknown key) |
307 } |
307 } |
308 return; |
308 return; |
309 } |
309 } |
310 |
310 |
311 case SDL_MOUSEBUTTONDOWN: |
311 case SDL_MOUSEBUTTONDOWN: |
312 case SDL_MOUSEBUTTONUP: |
312 case SDL_MOUSEBUTTONUP: |
313 event.type = (sdl_event.type == SDL_MOUSEBUTTONDOWN) ? Event::MOUSEDOWN : Event::MOUSEUP; |
313 event.type = (sdl_event.type == SDL_MOUSEBUTTONDOWN) ? Event::MOUSEDOWN : Event::MOUSEUP; |
314 event.mouse.x = sdl_event.button.x / _screen.get_cell_width(); |
314 event.mouse.x = sdl_event.button.x / _screen.get_cell_width(); |
315 event.mouse.y = sdl_event.button.y / _screen.get_cell_height(); |
315 event.mouse.y = sdl_event.button.y / _screen.get_cell_height(); |
316 event.mouse.button = sdl_event.button.button; |
316 event.mouse.button = sdl_event.button.button; |
317 _mousemove_last_x = -1; |
317 _mousemove_last_x = -1; |
318 return; |
318 return; |
319 |
319 |
320 case SDL_MOUSEMOTION: |
320 case SDL_MOUSEMOTION: |
321 event.type = Event::MOUSEMOVE; |
321 event.type = Event::MOUSEMOVE; |
322 event.mouse.x = sdl_event.motion.x / _screen.get_cell_width(); |
322 event.mouse.x = sdl_event.motion.x / _screen.get_cell_width(); |
323 event.mouse.y = sdl_event.motion.y / _screen.get_cell_height(); |
323 event.mouse.y = sdl_event.motion.y / _screen.get_cell_height(); |
324 if (_mousemove_last_x != event.mouse.x || |
324 if (_mousemove_last_x != event.mouse.x || |
325 _mousemove_last_y != event.mouse.y) |
325 _mousemove_last_y != event.mouse.y) |
326 { |
326 { |
327 _mousemove_last_x = event.mouse.x; |
327 _mousemove_last_x = event.mouse.x; |
328 _mousemove_last_y = event.mouse.y; |
328 _mousemove_last_y = event.mouse.y; |
329 return; |
329 return; |
330 } |
330 } |
331 break; // continue loop when mouse position did not change |
331 break; // continue loop when mouse position did not change |
332 |
332 |
333 default: |
333 default: |
334 break; // continue loop |
334 break; // continue loop |
335 } |
335 } |
336 } |
336 } |
337 } |
337 } |
338 |
338 |
339 |
339 |
340 const char *Terminal::_translate_keyname(SDLKey sym) |
340 const char *Terminal::_translate_keyname(SDLKey sym) |
341 { |
341 { |
342 switch (sym) |
342 switch (sym) |
343 { |
343 { |
344 case SDLK_BACKSPACE: return "backspace"; |
344 case SDLK_BACKSPACE: return "backspace"; |
345 case SDLK_TAB: return "tab"; |
345 case SDLK_TAB: return "tab"; |
346 case SDLK_RETURN: return "enter"; |
346 case SDLK_RETURN: return "enter"; |
347 case SDLK_KP_ENTER: return "enter"; |
347 case SDLK_KP_ENTER: return "enter"; |
348 case SDLK_ESCAPE: return "escape"; |
348 case SDLK_ESCAPE: return "escape"; |
349 case SDLK_DELETE: return "delete"; |
349 case SDLK_DELETE: return "delete"; |
350 case SDLK_INSERT: return "insert"; |
350 case SDLK_INSERT: return "insert"; |
351 case SDLK_UP: return "up"; |
351 case SDLK_UP: return "up"; |
352 case SDLK_DOWN: return "down"; |
352 case SDLK_DOWN: return "down"; |
353 case SDLK_LEFT: return "left"; |
353 case SDLK_LEFT: return "left"; |
354 case SDLK_RIGHT: return "right"; |
354 case SDLK_RIGHT: return "right"; |
355 case SDLK_HOME: return "home"; |
355 case SDLK_HOME: return "home"; |
356 case SDLK_END: return "end"; |
356 case SDLK_END: return "end"; |
357 case SDLK_PAGEUP: return "pageup"; |
357 case SDLK_PAGEUP: return "pageup"; |
358 case SDLK_PAGEDOWN: return "pagedown"; |
358 case SDLK_PAGEDOWN: return "pagedown"; |
359 case SDLK_F1: return "f1"; |
359 case SDLK_F1: return "f1"; |
360 case SDLK_F2: return "f2"; |
360 case SDLK_F2: return "f2"; |
361 case SDLK_F3: return "f3"; |
361 case SDLK_F3: return "f3"; |
362 case SDLK_F4: return "f4"; |
362 case SDLK_F4: return "f4"; |
363 case SDLK_F5: return "f5"; |
363 case SDLK_F5: return "f5"; |
364 case SDLK_F6: return "f6"; |
364 case SDLK_F6: return "f6"; |
365 case SDLK_F7: return "f7"; |
365 case SDLK_F7: return "f7"; |
366 case SDLK_F8: return "f8"; |
366 case SDLK_F8: return "f8"; |
367 case SDLK_F9: return "f9"; |
367 case SDLK_F9: return "f9"; |
368 case SDLK_F10: return "f10"; |
368 case SDLK_F10: return "f10"; |
369 case SDLK_F11: return "f11"; |
369 case SDLK_F11: return "f11"; |
370 case SDLK_F12: return "f12"; |
370 case SDLK_F12: return "f12"; |
371 case SDLK_PRINT: return "print"; |
371 case SDLK_PRINT: return "print"; |
372 case SDLK_SCROLLOCK: return "scrllock"; |
372 case SDLK_SCROLLOCK: return "scrllock"; |
373 case SDLK_PAUSE: return "pause"; |
373 case SDLK_PAUSE: return "pause"; |
374 default: return NULL; |
374 default: return NULL; |
375 } |
375 } |
376 } |
376 } |
377 |
377 |