summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--firmware/backlight.c7
-rw-r--r--firmware/export/kernel.h2
-rw-r--r--uisimulator/common/io.c3
-rw-r--r--uisimulator/sdl/button.c25
-rw-r--r--uisimulator/sdl/kernel.c20
-rw-r--r--uisimulator/sdl/thread-sdl.c25
-rw-r--r--uisimulator/sdl/thread-sdl.h2
-rw-r--r--uisimulator/sdl/uisdl.c6
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;