DriverSDL: Fix event dispatching. Add SDL events test.
--- a/.hgignore Wed Jan 30 00:38:48 2013 +0100
+++ b/.hgignore Wed Jan 30 19:44:01 2013 +0100
@@ -6,7 +6,7 @@
^sdlterm/build
^sdlterm/font
^sdlterm/cython/sdlterm.cpp$
-^sdlterm/demo$
+^sdlterm/test_
^(.*/)?\.c?project$
^(.*/)?\.pydevproject$
^\.settings
--- a/sdlterm/Makefile Wed Jan 30 00:38:48 2013 +0100
+++ b/sdlterm/Makefile Wed Jan 30 19:44:01 2013 +0100
@@ -1,8 +1,11 @@
CXXFLAGS=`sdl-config --cflags` -g -Wall -std=c++11 -Isrc
LDFLAGS=`sdl-config --libs` -lSDL_ttf
-VPATH=src
+VPATH=src tests
-demo: demo.cc sdlterm.cc sdlterm.h
+all: test_sdlterm test_sdl_events
+
+test_sdlterm: test_sdlterm.cc sdlterm.cc sdlterm.h
+test_sdl_events: test_sdl_events.cc
clean:
- rm -f demo
+ rm -f test_sdlterm test_sdl_events
--- a/sdlterm/demo.cc Wed Jan 30 00:38:48 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-#include "sdlterm.h"
-
-
-class Application
-{
-public:
- Terminal term;
- bool done;
-
- Application() : term(), done(false) {};
-
- void init();
- void wait_and_process_event();
-};
-
-
-void Application::init()
-{
- term.resize(800, 600);
- term.select_font("font/DejaVuSansMono.ttf", "font/DejaVuSansMono-Bold.ttf", 12);
- term.erase();
-
- char hello[] = "Hello World!";
- for (int bg = 0; bg < 16; bg++)
- {
- for (int fg = 0; fg < 16; fg++)
- {
- for (char *c = hello; *c; c++)
- {
- term.set_attr( term.prepare_attr(fg, bg, 1) );
- term.putch(5 + 6 * bg + (c - hello), 5 + fg, *c);
- }
- }
- }
- term.commit();
-}
-
-
-void Application::wait_and_process_event()
-{
- Event event;
- term.wait_event(event, 0);
-
- switch (event.type)
- {
- case Event::QUIT:
- done = true;
- break;
-
- default:
- break;
- }
-}
-
-
-int main(int argc, char *argv[])
-{
- Application app;
- app.init();
-
- while (!app.done)
- {
- app.wait_and_process_event();
- }
-
- return 0;
-}
-
--- a/sdlterm/demo.py Wed Jan 30 00:38:48 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-
-from sdlterm import SDLTerminal
-
-if __name__ == '__main__':
- term = SDLTerminal()
- term.resize(800, 600)
- term.select_font(b"font/DejaVuSansMono.ttf", b"font/DejaVuSansMono-Bold.ttf", 12)
- term.erase()
- term.putch(5, 5, 'W')
- term.commit()
-
- while True:
- event = term.wait_event()
- print(event)
- if event[0] == 'keypress' and event[1] == 'escape':
- break
-
--- a/sdlterm/src/sdlterm.cc Wed Jan 30 00:38:48 2013 +0100
+++ b/sdlterm/src/sdlterm.cc Wed Jan 30 19:44:01 2013 +0100
@@ -371,6 +371,17 @@
bool Terminal::wait_event(Event &event, Uint32 timeout)
{
+ SDL_Event sdl_event;
+ bool translated;
+
+ // any events pending?
+ while (SDL_PollEvent(&sdl_event))
+ {
+ translated = _handle_event(sdl_event, event);
+ if (translated)
+ return true;
+ }
+
// use timer to simulate SDL_WaitEventTimeout, which is not available in SDL 1.2
SDL_TimerID timer_id = NULL;
if (timeout)
@@ -379,104 +390,25 @@
}
// loop until we have something to return
- SDL_Event sdl_event;
bool event_ready = false;
- while (SDL_WaitEvent(&sdl_event) && !event_ready)
+ while (!event_ready && SDL_WaitEvent(&sdl_event))
{
- switch (sdl_event.type)
+ do
{
- case SDL_USEREVENT:
- // timeout
- if (sdl_event.user.code == 1)
- {
- SDL_RemoveTimer(timer_id);
- return false;
- }
- // toggle blink
- if (sdl_event.user.code == 2)
- {
- _screen.toggle_blink();
- }
- break; // continue loop
-
- case SDL_QUIT:
- event.type = Event::QUIT;
- event_ready = true;
- break;
-
- case SDL_VIDEORESIZE:
- event.type = Event::RESIZE;
- _screen.resize(sdl_event.resize.w, sdl_event.resize.h);
- event_ready = true;
- break;
-
- case SDL_VIDEOEXPOSE:
- _screen.redraw();
- break;
-
- case SDL_KEYDOWN:
+ translated = _handle_event(sdl_event, event);
+ if (translated)
{
- //switch(event.key.keysym.sym)
- event.type = Event::KEYPRESS;
- 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)
- }
- event.key.mod = _translate_mod(sdl_event.key.keysym.mod);
event_ready = true;
break;
}
-
- 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;
- if (sdl_event.button.button == SDL_BUTTON_WHEELUP || sdl_event.button.button == SDL_BUTTON_WHEELDOWN)
- {
- if (sdl_event.type == SDL_MOUSEBUTTONUP)
- break; // do not report button-up events for mouse wheel
- event.type = Event::MOUSEWHEEL;
- }
- _mousemove_last_x = -1;
- event_ready = true;
- break;
-
- 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();
- if (_mousemove_last_x != event.mouse.x ||
- _mousemove_last_y != event.mouse.y)
- {
- if (_mousemove_last_x != -1)
- {
- event.mouse.relx = event.mouse.x - _mousemove_last_x;
- event.mouse.rely = event.mouse.y - _mousemove_last_y;
- event_ready = true;
- }
- _mousemove_last_x = event.mouse.x;
- _mousemove_last_y = event.mouse.y;
- break;
- }
- break; // continue loop when mouse position did not change
-
- default:
- break; // continue loop
+ // timeout?
+ if (sdl_event.type == SDL_USEREVENT && sdl_event.user.code == 1)
+ {
+ SDL_RemoveTimer(timer_id);
+ return false;
+ }
}
+ while (!event_ready && SDL_PollEvent(&sdl_event));
}
// remove timer when other event came before timeout
@@ -497,6 +429,104 @@
}
+// return true when SDL_Event was translated to our Event
+bool Terminal::_handle_event(const SDL_Event &sdl_event, Event &event)
+{
+ switch (sdl_event.type)
+ {
+ case SDL_USEREVENT:
+ // toggle blink
+ if (sdl_event.user.code == 2)
+ {
+ _screen.toggle_blink();
+ }
+ return false;
+
+ case SDL_QUIT:
+ event.type = Event::QUIT;
+ return true;
+
+ case SDL_VIDEORESIZE:
+ event.type = Event::RESIZE;
+ _screen.resize(sdl_event.resize.w, sdl_event.resize.h);
+ return true;
+
+ case SDL_VIDEOEXPOSE:
+ _screen.redraw();
+ return false;
+
+ case SDL_KEYDOWN:
+ {
+ //switch(event.key.keysym.sym)
+ event.type = Event::KEYPRESS;
+ 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)
+ {
+ // unknown key
+ return false;
+ }
+ }
+ event.key.mod = _translate_mod(sdl_event.key.keysym.mod);
+ return true;
+ }
+
+ 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;
+ if (sdl_event.button.button == SDL_BUTTON_WHEELUP || sdl_event.button.button == SDL_BUTTON_WHEELDOWN)
+ {
+ if (sdl_event.type == SDL_MOUSEBUTTONUP)
+ {
+ // do not report button-up events for mouse wheel
+ return false;
+ }
+ event.type = Event::MOUSEWHEEL;
+ }
+ _mousemove_last_x = event.mouse.x;
+ _mousemove_last_y = event.mouse.y;
+ return true;
+
+ case SDL_MOUSEMOTION:
+ if (sdl_event.motion.state == 0 || _mousemove_last_x == -1)
+ {
+ // do not report move events when no button is pressed
+ return false;
+ }
+ 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();
+ if (_mousemove_last_x != event.mouse.x ||
+ _mousemove_last_y != event.mouse.y)
+ {
+ event.mouse.relx = event.mouse.x - _mousemove_last_x;
+ event.mouse.rely = event.mouse.y - _mousemove_last_y;
+ _mousemove_last_x = event.mouse.x;
+ _mousemove_last_y = event.mouse.y;
+ return true;
+ }
+ // mouse position did not change
+ return false;
+
+ default:
+ // unknown event
+ return false;
+ }
+}
+
+
const char *Terminal::_translate_keyname(SDLKey sym)
{
switch (sym)
--- a/sdlterm/src/sdlterm.h Wed Jan 30 00:38:48 2013 +0100
+++ b/sdlterm/src/sdlterm.h Wed Jan 30 19:44:01 2013 +0100
@@ -238,6 +238,7 @@
int _mousemove_last_x;
int _mousemove_last_y;
+ bool _handle_event(const SDL_Event &sdl_event, Event &event);
const char *_translate_keyname(SDLKey sym);
int _translate_mod(SDLMod mod);
static Uint32 _wait_event_callback(Uint32 interval, void *param);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sdlterm/test_sdlterm.py Wed Jan 30 19:44:01 2013 +0100
@@ -0,0 +1,19 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+from sdlterm import SDLTerminal
+
+if __name__ == '__main__':
+ term = SDLTerminal()
+ term.resize(800, 600)
+ term.select_font(b"font/DejaVuSansMono.ttf", b"font/DejaVuSansMono-Bold.ttf", 12)
+ term.erase()
+ term.putch(5, 5, 'W')
+ term.commit()
+
+ while True:
+ event = term.wait_event()
+ print(event)
+ if event[0] == 'keypress' and event[1] == 'escape':
+ break
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sdlterm/tests/test_sdl_events.cc Wed Jan 30 19:44:01 2013 +0100
@@ -0,0 +1,97 @@
+#include <SDL/SDL.h>
+
+Uint32 timeout_callback(Uint32 interval, void *param)
+{
+ SDL_Event event;
+ event.type = SDL_USEREVENT;
+ event.user.code = 1;
+ SDL_PushEvent(&event);
+ return 0;
+}
+
+bool handle_events(Uint32 timeout)
+{
+ SDL_Event event;
+ SDL_TimerID timer_id = NULL;
+ bool done = false;
+
+ if (timeout)
+ {
+ timer_id = SDL_AddTimer(timeout, timeout_callback, NULL);
+ }
+
+ // wait for events and handle them
+ if (SDL_WaitEvent(&event))
+ {
+ do
+ {
+ switch (event.type)
+ {
+ case SDL_USEREVENT:
+ // timeout
+ if (event.user.code == 1)
+ {
+ SDL_RemoveTimer(timer_id);
+ printf("timeout\n");
+ }
+ break; // continue loop
+
+ case SDL_QUIT:
+ printf("quit\n");
+ done = true;
+ break;
+
+ case SDL_KEYUP:
+ printf("keyup\n");
+ if (event.key.keysym.sym == SDLK_ESCAPE)
+ {
+ done = true;
+ }
+ break;
+
+ case SDL_MOUSEBUTTONDOWN:
+ printf("mouse button down\n");
+ break;
+
+ case SDL_MOUSEBUTTONUP:
+ printf("mouse button up\n");
+ break;
+ }
+ }
+ while (SDL_PollEvent(&event));
+ }
+ // remove timer when other event came before timeout
+ if (timeout)
+ {
+ SDL_RemoveTimer(timer_id);
+ }
+ return done;
+}
+
+int main(int argc, char **argv)
+{
+ SDL_Surface* screen = NULL;
+
+ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1)
+ {
+ fprintf(stderr, "SDL_Init: %s\n", SDL_GetError());
+ exit(1);
+ }
+
+ atexit(SDL_Quit);
+
+ screen = SDL_SetVideoMode(800, 480, 16, SDL_SWSURFACE);
+ if (screen == NULL)
+ {
+ fprintf(stderr, "SDL_SetVideoMode: %s\n", SDL_GetError());
+ exit(1);
+ }
+
+ bool done = false;
+ while (!done)
+ {
+ done = handle_events(1000);
+ }
+
+ return (0);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sdlterm/tests/test_sdlterm.cc Wed Jan 30 19:44:01 2013 +0100
@@ -0,0 +1,76 @@
+#include "sdlterm.h"
+
+
+class Application
+{
+public:
+ Terminal term;
+ bool done;
+
+ Application() : term(), done(false) {};
+
+ void init();
+ void wait_and_process_event();
+};
+
+
+void Application::init()
+{
+ term.resize(800, 600);
+ term.select_font("font/DejaVuSansMono.ttf", "font/DejaVuSansMono-Bold.ttf", 12);
+ term.erase();
+
+ char hello[] = "Hello World!";
+ for (int bg = 0; bg < 16; bg++)
+ {
+ for (int fg = 0; fg < 16; fg++)
+ {
+ for (char *c = hello; *c; c++)
+ {
+ term.set_attr( term.prepare_attr(fg, bg, 1) );
+ term.putch(5 + 6 * bg + (c - hello), 5 + fg, *c);
+ }
+ }
+ }
+ term.commit();
+}
+
+
+void Application::wait_and_process_event()
+{
+ Event event;
+ term.wait_event(event, 0);
+
+ switch (event.type)
+ {
+ case Event::QUIT:
+ done = true;
+ break;
+
+ case Event::MOUSEDOWN:
+ printf("mouse button down\n");
+ break;
+
+ case Event::MOUSEUP:
+ printf("mouse button up\n");
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+int main(int argc, char *argv[])
+{
+ Application app;
+ app.init();
+
+ while (!app.done)
+ {
+ app.wait_and_process_event();
+ }
+
+ return 0;
+}
+