diff options
-rw-r--r-- | firmware/backlight.c | 7 | ||||
-rw-r--r-- | firmware/export/kernel.h | 2 | ||||
-rw-r--r-- | uisimulator/common/io.c | 3 | ||||
-rw-r--r-- | uisimulator/sdl/button.c | 25 | ||||
-rw-r--r-- | uisimulator/sdl/kernel.c | 20 | ||||
-rw-r--r-- | uisimulator/sdl/thread-sdl.c | 25 | ||||
-rw-r--r-- | uisimulator/sdl/thread-sdl.h | 2 | ||||
-rw-r--r-- | uisimulator/sdl/uisdl.c | 6 |
8 files changed, 74 insertions, 16 deletions
diff --git a/firmware/backlight.c b/firmware/backlight.c index 2ba4d6ed1d..41f0f75424 100644 --- a/firmware/backlight.c +++ b/firmware/backlight.c @@ -487,7 +487,12 @@ void backlight_thread(void) lcd_remote_off(); break; #endif /* defined(HAVE_REMOTE_LCD) && !defined(SIMULATOR) */ - +#ifdef SIMULATOR + /* This one here too for lack of a better place */ + case SYS_SCREENDUMP: + screen_dump(); + break; +#endif case SYS_USB_CONNECTED: /* Tell the USB thread that we are safe */ DEBUGF("backlight_thread got SYS_USB_CONNECTED\n"); diff --git a/firmware/export/kernel.h b/firmware/export/kernel.h index bf5a9d10c3..9ada8eb59c 100644 --- a/firmware/export/kernel.h +++ b/firmware/export/kernel.h @@ -41,6 +41,7 @@ #define SYS_EVENT_CLS_POWER 2 #define SYS_EVENT_CLS_FILESYS 3 #define SYS_EVENT_CLS_PLUG 4 +#define SYS_EVENT_CLS_MISC 5 /* make sure SYS_EVENT_CLS_BITS has enough range */ /* Bit 31->|S|c...c|i...i| */ @@ -68,6 +69,7 @@ #define SYS_PHONE_UNPLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 3) #define SYS_REMOTE_PLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 4) #define SYS_REMOTE_UNPLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 5) +#define SYS_SCREENDUMP MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 0) struct event { diff --git a/uisimulator/common/io.c b/uisimulator/common/io.c index 127a1c36f1..463bbc68d9 100644 --- a/uisimulator/common/io.c +++ b/uisimulator/common/io.c @@ -261,7 +261,8 @@ void sim_io_init(void) } /* Wait for IO thread to lock mutex */ - while (!io.ready); + while (!io.ready) + SDL_Delay(0); /* Wait for it to unlock */ SDL_LockMutex(io.m); diff --git a/uisimulator/sdl/button.c b/uisimulator/sdl/button.c index 1bb9311890..4869dd06b1 100644 --- a/uisimulator/sdl/button.c +++ b/uisimulator/sdl/button.c @@ -30,6 +30,11 @@ static intptr_t button_data; /* data value from last message dequeued */ +/* Special thread-synced queue_post for button driver or any other preemptive sim thread */ +extern void queue_syncpost(struct event_queue *q, long id, intptr_t data); +/* Special thread-synced queue_broadcast for button driver or any other preemptive sim thread */ +extern int queue_syncbroadcast(long id, intptr_t data); + /* how long until repeat kicks in */ #define REPEAT_START 6 @@ -110,9 +115,9 @@ void button_event(int key, bool pressed) { usb_connected = !usb_connected; if (usb_connected) - queue_post(&button_queue, SYS_USB_CONNECTED, 0); + queue_syncpost(&button_queue, SYS_USB_CONNECTED, 0); else - queue_post(&button_queue, SYS_USB_DISCONNECTED, 0); + queue_syncpost(&button_queue, SYS_USB_DISCONNECTED, 0); } return; @@ -590,7 +595,7 @@ void button_event(int key, bool pressed) case SDLK_F5: if(pressed) { - screen_dump(); + queue_syncbroadcast(SYS_SCREENDUMP, 0); return; } break; @@ -611,17 +616,17 @@ void button_event(int key, bool pressed) #ifdef HAVE_REMOTE_LCD if(diff & BUTTON_REMOTE) if(!skip_remote_release) - queue_post(&button_queue, BUTTON_REL | diff, 0); + queue_syncpost(&button_queue, BUTTON_REL | diff, 0); else skip_remote_release = false; else #endif if(!skip_release) - queue_post(&button_queue, BUTTON_REL | diff, 0); + queue_syncpost(&button_queue, BUTTON_REL | diff, 0); else skip_release = false; #else - queue_post(&button_queue, BUTTON_REL | diff, 0); + queue_syncpost(&button_queue, BUTTON_REL | diff, 0); #endif } @@ -673,7 +678,7 @@ void button_event(int key, bool pressed) { if (queue_empty(&button_queue)) { - queue_post(&button_queue, BUTTON_REPEAT | btn, 0); + queue_syncpost(&button_queue, BUTTON_REPEAT | btn, 0); #ifdef HAVE_BACKLIGHT #ifdef HAVE_REMOTE_LCD if(btn & BUTTON_REMOTE) @@ -695,18 +700,18 @@ void button_event(int key, bool pressed) #ifdef HAVE_REMOTE_LCD if (btn & BUTTON_REMOTE) { if (!remote_filter_first_keypress || is_remote_backlight_on()) - queue_post(&button_queue, btn, 0); + queue_syncpost(&button_queue, btn, 0); else skip_remote_release = true; } else #endif if (!filter_first_keypress || is_backlight_on()) - queue_post(&button_queue, btn, 0); + queue_syncpost(&button_queue, btn, 0); else skip_release = true; #else /* no backlight, nothing to skip */ - queue_post(&button_queue, btn, 0); + queue_syncpost(&button_queue, btn, 0); #endif post = false; } diff --git a/uisimulator/sdl/kernel.c b/uisimulator/sdl/kernel.c index c82c6632cf..ff6c94933b 100644 --- a/uisimulator/sdl/kernel.c +++ b/uisimulator/sdl/kernel.c @@ -225,6 +225,15 @@ void queue_post(struct event_queue *q, long id, intptr_t data) wakeup_thread(&q->thread); } +/* Special thread-synced queue_post for button driver or any other preemptive sim thread */ +void queue_syncpost(struct event_queue *q, long id, intptr_t data) +{ + thread_sdl_lock(); + /* No rockbox threads can be running here */ + queue_post(q, id, data); + thread_sdl_unlock(); +} + #ifdef HAVE_EXTENDED_MESSAGING_AND_NAME intptr_t queue_send(struct event_queue *q, long id, intptr_t data) { @@ -332,6 +341,17 @@ int queue_broadcast(long id, intptr_t data) return num_queues; } +/* Special thread-synced queue_broadcast for button driver or any other preemptive sim thread */ +int queue_syncbroadcast(long id, intptr_t data) +{ + int i; + thread_sdl_lock(); + /* No rockbox threads can be running here */ + i = queue_broadcast(id, data); + thread_sdl_unlock(); + return i; +} + void yield(void) { switch_thread(true, NULL); diff --git a/uisimulator/sdl/thread-sdl.c b/uisimulator/sdl/thread-sdl.c index aac8e2fbb9..8769b5d84f 100644 --- a/uisimulator/sdl/thread-sdl.c +++ b/uisimulator/sdl/thread-sdl.c @@ -48,6 +48,8 @@ static SDL_mutex *m; static SDL_sem *s; static struct thread_entry *running; +extern long start_tick; + void kill_sim_threads(void) { int i; @@ -62,6 +64,7 @@ void kill_sim_threads(void) SDL_SemPost(s); else SDL_CondSignal(thread->context.c); + SDL_Delay(10); SDL_KillThread(thread->context.t); SDL_DestroyCond(thread->context.c); } @@ -129,6 +132,16 @@ struct thread_entry *thread_get_current(void) return running; } +void thread_sdl_lock(void) +{ + SDL_LockMutex(m); +} + +void thread_sdl_unlock(void) +{ + SDL_UnlockMutex(m); +} + void switch_thread(bool save_context, struct thread_entry **blocked_list) { struct thread_entry *current = running; @@ -137,6 +150,8 @@ void switch_thread(bool save_context, struct thread_entry **blocked_list) SDL_SemWait(s); + SDL_Delay(0); + SDL_LockMutex(m); running = current; @@ -148,11 +163,19 @@ void switch_thread(bool save_context, struct thread_entry **blocked_list) void sleep_thread(int ticks) { struct thread_entry *current; + int rem; current = running; current->statearg = STATE_SLEEPING; - SDL_CondWaitTimeout(current->context.c, m, (1000/HZ) * ticks + (500/HZ)); + rem = (SDL_GetTicks() - start_tick) % (1000/HZ); + if (rem < 0) + rem = 0; + + SDL_UnlockMutex(m); + SDL_Delay((1000/HZ) * ticks + ((1000/HZ)-1) - rem); + SDL_LockMutex(m); + running = current; current->statearg = STATE_RUNNING; diff --git a/uisimulator/sdl/thread-sdl.h b/uisimulator/sdl/thread-sdl.h index 20641fb673..90dffd6806 100644 --- a/uisimulator/sdl/thread-sdl.h +++ b/uisimulator/sdl/thread-sdl.h @@ -24,6 +24,8 @@ extern SDL_Thread *gui_thread; /* The "main" thread */ void kill_sim_threads(); /* Kill all the rockbox sim threads */ +void thread_sdl_lock(void); /* Sync with SDL threads */ +void thread_sdl_unlock(void); /* Sync with SDL threads */ #endif /* #ifndef __THREADSDL_H__ */ diff --git a/uisimulator/sdl/uisdl.c b/uisimulator/sdl/uisdl.c index 37a0e6fe7a..fdd40beb23 100644 --- a/uisimulator/sdl/uisdl.c +++ b/uisimulator/sdl/uisdl.c @@ -41,8 +41,8 @@ extern void app_main (void *); /* mod entry point */ extern void new_key(int key); extern void sim_tick_tasks(void); -extern void sim_io_init(void); -extern void sim_io_shutdown(void); +extern void sim_io_init(void); +extern void sim_io_shutdown(void); void button_event(int key, bool pressed); @@ -69,7 +69,7 @@ Uint32 tick_timer(Uint32 interval, void *param) (void) interval; (void) param; - new_tick = (SDL_GetTicks() - start_tick) * HZ / 1000; + new_tick = (SDL_GetTicks() - start_tick) / (1000/HZ); if (new_tick != current_tick) { long i; |