summaryrefslogtreecommitdiff
path: root/firmware/target
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
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')
-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 cfe08de1d2..e9fc03792c 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) {
85static void button_event(int key, bool pressed); 85static void button_event(int key, bool pressed);
86extern bool debug_wps; 86extern bool debug_wps;
87extern bool mapping; 87extern bool mapping;
88static void gui_message_loop(void) 88
89void gui_message_loop(void)
89{ 90{
90 SDL_Event event; 91 SDL_Event event;
91 static int x,y,xybutton = 0; 92 static int x,y,xybutton = 0;
92 93
93 if (SDL_PollEvent(&event)) 94 while (SDL_WaitEvent(&event))
94 { 95 {
96 sim_enter_irq_handler();
95 switch(event.type) 97 switch(event.type)
96 { 98 {
97 case SDL_KEYDOWN: 99 case SDL_KEYDOWN:
98 button_event(event.key.keysym.sym, true);
99 break;
100 case SDL_KEYUP: 100 case SDL_KEYUP:
101 button_event(event.key.keysym.sym, false); 101 button_event(event.key.keysym.sym, event.type == SDL_KEYDOWN);
102 break;
102 case SDL_MOUSEBUTTONDOWN: 103 case SDL_MOUSEBUTTONDOWN:
103 switch ( event.button.button ) { 104 switch ( event.button.button ) {
104#ifdef HAVE_SCROLLWHEEL 105#ifdef HAVE_SCROLLWHEEL
@@ -174,6 +175,7 @@ static void gui_message_loop(void)
174 175
175 case SDL_QUIT: 176 case SDL_QUIT:
176 { 177 {
178 sim_exit_irq_handler();
177 exit(EXIT_SUCCESS); 179 exit(EXIT_SUCCESS);
178 break; 180 break;
179 } 181 }
@@ -181,6 +183,7 @@ static void gui_message_loop(void)
181 /*printf("Unhandled event\n"); */ 183 /*printf("Unhandled event\n"); */
182 break; 184 break;
183 } 185 }
186 sim_exit_irq_handler();
184 } 187 }
185} 188}
186 189
@@ -1502,7 +1505,6 @@ int button_read_device(void)
1502 return BUTTON_NONE; 1505 return BUTTON_NONE;
1503 else 1506 else
1504#endif 1507#endif
1505 gui_message_loop();
1506 1508
1507 return btn; 1509 return btn;
1508} 1510}
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)
diff --git a/firmware/target/hosted/sdl/system-sdl.h b/firmware/target/hosted/sdl/system-sdl.h
index 917e6e89da..ad7aa709ab 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);
44void sim_kernel_shutdown(void); 44void sim_kernel_shutdown(void);
45void sys_poweroff(void); 45void sys_poweroff(void);
46void sys_handle_argv(int argc, char *argv[]); 46void sys_handle_argv(int argc, char *argv[]);
47void gui_message_loop(void);
47 48
48extern bool background; /* True if the background image is enabled */ 49extern bool background; /* True if the background image is enabled */
49extern int display_zoom; 50extern int display_zoom;