summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/target/hosted/sdl/button-sdl.c14
-rw-r--r--firmware/target/hosted/sdl/system-sdl.c71
-rw-r--r--firmware/target/hosted/sdl/system-sdl.h1
3 files changed, 73 insertions, 13 deletions
diff --git a/firmware/target/hosted/sdl/button-sdl.c b/firmware/target/hosted/sdl/button-sdl.c
index cfe08de..e9fc037 100644
--- a/firmware/target/hosted/sdl/button-sdl.c
+++ b/firmware/target/hosted/sdl/button-sdl.c
@@ -85,20 +85,21 @@ bool remote_button_hold(void) {
static void button_event(int key, bool pressed);
extern bool debug_wps;
extern bool mapping;
-static void gui_message_loop(void)
+
+void gui_message_loop(void)
{
SDL_Event event;
static int x,y,xybutton = 0;
- if (SDL_PollEvent(&event))
+ while (SDL_WaitEvent(&event))
{
+ sim_enter_irq_handler();
switch(event.type)
{
case SDL_KEYDOWN:
- button_event(event.key.keysym.sym, true);
- break;
case SDL_KEYUP:
- button_event(event.key.keysym.sym, false);
+ button_event(event.key.keysym.sym, event.type == SDL_KEYDOWN);
+ break;
case SDL_MOUSEBUTTONDOWN:
switch ( event.button.button ) {
#ifdef HAVE_SCROLLWHEEL
@@ -174,6 +175,7 @@ static void gui_message_loop(void)
case SDL_QUIT:
{
+ sim_exit_irq_handler();
exit(EXIT_SUCCESS);
break;
}
@@ -181,6 +183,7 @@ static void gui_message_loop(void)
/*printf("Unhandled event\n"); */
break;
}
+ sim_exit_irq_handler();
}
}
@@ -1502,7 +1505,6 @@ int button_read_device(void)
return BUTTON_NONE;
else
#endif
- gui_message_loop();
return btn;
}
diff --git a/firmware/target/hosted/sdl/system-sdl.c b/firmware/target/hosted/sdl/system-sdl.c
index 693e8d1..3d67de4 100644
--- a/firmware/target/hosted/sdl/system-sdl.c
+++ b/firmware/target/hosted/sdl/system-sdl.c
@@ -70,14 +70,37 @@ void sys_poweroff(void)
SDL_Quit();
}
-void system_init(void)
+/*
+ * Button read loop */
+void gui_message_loop(void);
+
+/*
+ * This callback let's the main thread run again after SDL has been initialized
+ **/
+static uint32_t cond_signal(uint32_t interval, void *param)
+{
+ (void)interval;
+ SDL_cond *c = (SDL_cond*)param;
+ /* remove timer, CondSignal returns 0 on success */
+ return SDL_CondSignal(c);
+}
+
+/*
+ * This thread will read the buttons in an interrupt like fashion, and
+ * also initializes SDL_INIT_VIDEO and the surfaces
+ *
+ * it must be done in the same thread (at least on windows) because events only
+ * work in the thread which called SDL_Init(SubSystem) with SDL_INIT_VIDEO
+ *
+ * This is an SDL thread and relies on preemptive behavoir of the host
+ **/
+static int sdl_event_thread(void * param)
{
+ SDL_InitSubSystem(SDL_INIT_VIDEO);
+
SDL_Surface *picture_surface;
int width, height;
- if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER))
- panicf("%s", SDL_GetError());
-
/* Try and load the background image. If it fails go without */
if (background) {
picture_surface = SDL_LoadBMP("UI256.bmp");
@@ -122,10 +145,43 @@ void system_init(void)
sim_lcd_remote_init();
#endif
- if (background && picture_surface != NULL) {
+ if (background && picture_surface != NULL)
SDL_BlitSurface(picture_surface, NULL, gui_surface, NULL);
- SDL_UpdateRect(gui_surface, 0, 0, 0, 0);
- }
+
+ /* calling SDL_CondSignal() right away here doesn't work reliably so
+ * post-pone it a bit */
+ SDL_AddTimer(100, cond_signal, param);
+ /*
+ * finally enter the button loop */
+ while(1)
+ gui_message_loop();
+
+ return 0;
+}
+
+
+void system_init(void)
+{
+ SDL_cond *c;
+ SDL_mutex *m;
+ if (SDL_Init(SDL_INIT_TIMER))
+ panicf("%s", SDL_GetError());
+ atexit(SDL_Quit);
+
+ c = SDL_CreateCond();
+ m = SDL_CreateMutex();
+
+ SDL_CreateThread(sdl_event_thread, c);
+
+ /* Lock mutex and wait for sdl_event_thread to run so that it can
+ * initialize the surfaces and video subsystem needed for SDL events */
+ SDL_LockMutex(m);
+ SDL_CondWait(c, m);
+ SDL_UnlockMutex(m);
+
+ /* cleanup */
+ SDL_DestroyCond(c);
+ SDL_DestroyMutex(m);
}
void system_exception_wait(void)
@@ -138,6 +194,7 @@ void system_reboot(void)
sim_thread_exception_wait();
}
+
void sys_handle_argv(int argc, char *argv[])
{
if (argc >= 1)
diff --git a/firmware/target/hosted/sdl/system-sdl.h b/firmware/target/hosted/sdl/system-sdl.h
index 917e6e8..ad7aa70 100644
--- a/firmware/target/hosted/sdl/system-sdl.h
+++ b/firmware/target/hosted/sdl/system-sdl.h
@@ -44,6 +44,7 @@ void sim_exit_irq_handler(void);
void sim_kernel_shutdown(void);
void sys_poweroff(void);
void sys_handle_argv(int argc, char *argv[]);
+void gui_message_loop(void);
extern bool background; /* True if the background image is enabled */
extern int display_zoom;