summaryrefslogtreecommitdiff
path: root/firmware/target/hosted/sdl/system-sdl.c
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2010-05-17 17:19:31 +0000
committerThomas Martitz <kugel@rockbox.org>2010-05-17 17:19:31 +0000
commitc4c7069a8a0b4ffc5de8758c2aa154118449aa62 (patch)
tree9a330d88b3e3d40dbdcfbdddd0f85aa409a77cbf /firmware/target/hosted/sdl/system-sdl.c
parentf4d6ef2292c6a2b482af106e7d73588f65845e94 (diff)
downloadrockbox-c4c7069a8a0b4ffc5de8758c2aa154118449aa62.tar.gz
rockbox-c4c7069a8a0b4ffc5de8758c2aa154118449aa62.zip
Fix FS#11280
SDL docs say SDL_PumpEvent (implicitely called by SDL_Poll/WaitEvent) may only be called from the thread that initializes the video subsystem, apparently because Windows requires that. So create an (or bring it back) SDL thread (with preemtive behavior) to read the event queue for buttons and initialize the video subsystem. I'd probably would have done that anyway because it enables an interrupt-like method to read them (no polling). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26113 a1c6a512-1295-4272-9138-f99709370657
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)