summaryrefslogtreecommitdiff
path: root/firmware/target/hosted/sdl/system-sdl.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/hosted/sdl/system-sdl.c')
-rw-r--r--firmware/target/hosted/sdl/system-sdl.c71
1 files changed, 64 insertions, 7 deletions
diff --git a/firmware/target/hosted/sdl/system-sdl.c b/firmware/target/hosted/sdl/system-sdl.c
index 693e8d1b57..3d67de425b 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)
70 SDL_Quit(); 70 SDL_Quit();
71} 71}
72 72
73void system_init(void) 73/*
74 * Button read loop */
75void gui_message_loop(void);
76
77/*
78 * This callback let's the main thread run again after SDL has been initialized
79 **/
80static uint32_t cond_signal(uint32_t interval, void *param)
81{
82 (void)interval;
83 SDL_cond *c = (SDL_cond*)param;
84 /* remove timer, CondSignal returns 0 on success */
85 return SDL_CondSignal(c);
86}
87
88/*
89 * This thread will read the buttons in an interrupt like fashion, and
90 * also initializes SDL_INIT_VIDEO and the surfaces
91 *
92 * it must be done in the same thread (at least on windows) because events only
93 * work in the thread which called SDL_Init(SubSystem) with SDL_INIT_VIDEO
94 *
95 * This is an SDL thread and relies on preemptive behavoir of the host
96 **/
97static int sdl_event_thread(void * param)
74{ 98{
99 SDL_InitSubSystem(SDL_INIT_VIDEO);
100
75 SDL_Surface *picture_surface; 101 SDL_Surface *picture_surface;
76 int width, height; 102 int width, height;
77 103
78 if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER))
79 panicf("%s", SDL_GetError());
80
81 /* Try and load the background image. If it fails go without */ 104 /* Try and load the background image. If it fails go without */
82 if (background) { 105 if (background) {
83 picture_surface = SDL_LoadBMP("UI256.bmp"); 106 picture_surface = SDL_LoadBMP("UI256.bmp");
@@ -122,10 +145,43 @@ void system_init(void)
122 sim_lcd_remote_init(); 145 sim_lcd_remote_init();
123#endif 146#endif
124 147
125 if (background && picture_surface != NULL) { 148 if (background && picture_surface != NULL)
126 SDL_BlitSurface(picture_surface, NULL, gui_surface, NULL); 149 SDL_BlitSurface(picture_surface, NULL, gui_surface, NULL);
127 SDL_UpdateRect(gui_surface, 0, 0, 0, 0); 150
128 } 151 /* calling SDL_CondSignal() right away here doesn't work reliably so
152 * post-pone it a bit */
153 SDL_AddTimer(100, cond_signal, param);
154 /*
155 * finally enter the button loop */
156 while(1)
157 gui_message_loop();
158
159 return 0;
160}
161
162
163void system_init(void)
164{
165 SDL_cond *c;
166 SDL_mutex *m;
167 if (SDL_Init(SDL_INIT_TIMER))
168 panicf("%s", SDL_GetError());
169 atexit(SDL_Quit);
170
171 c = SDL_CreateCond();
172 m = SDL_CreateMutex();
173
174 SDL_CreateThread(sdl_event_thread, c);
175
176 /* Lock mutex and wait for sdl_event_thread to run so that it can
177 * initialize the surfaces and video subsystem needed for SDL events */
178 SDL_LockMutex(m);
179 SDL_CondWait(c, m);
180 SDL_UnlockMutex(m);
181
182 /* cleanup */
183 SDL_DestroyCond(c);
184 SDL_DestroyMutex(m);
129} 185}
130 186
131void system_exception_wait(void) 187void system_exception_wait(void)
@@ -138,6 +194,7 @@ void system_reboot(void)
138 sim_thread_exception_wait(); 194 sim_thread_exception_wait();
139} 195}
140 196
197
141void sys_handle_argv(int argc, char *argv[]) 198void sys_handle_argv(int argc, char *argv[])
142{ 199{
143 if (argc >= 1) 200 if (argc >= 1)