* give tsr plugins the choice to quit or not

* bumps plugin api version


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11405 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jonathan Gordon 2006-10-31 11:17:00 +00:00
parent 23f127ddd7
commit 29e259a291
4 changed files with 61 additions and 28 deletions

View file

@ -88,7 +88,8 @@ extern unsigned char pluginbuf[];
/* for actual plugins only, not for codecs */
static bool plugin_loaded = false;
static int plugin_size = 0;
static void (*pfn_tsr_exit)(void) = NULL; /* TSR exit callback */
static bool (*pfn_tsr_exit)(bool) = NULL; /* TSR exit callback */
static char current_plugin[MAX_PATH];
static const struct plugin_api rockbox_api = {
@ -248,6 +249,7 @@ static const struct plugin_api rockbox_api = {
ata_sleep,
ata_disk_is_active,
#endif
ata_spindown,
reload_directory,
/* dir */
@ -317,6 +319,7 @@ static const struct plugin_api rockbox_api = {
memchr,
memcmp,
strcasestr,
strtok_r,
/* unicode stuff */
utf8decode,
iso_decode,
@ -464,21 +467,21 @@ static const struct plugin_api rockbox_api = {
show_logo,
tree_get_context,
/* new stuff at the end, sort into place next time
the API gets incompatible */
strtok_r,
#ifdef HAVE_WHEEL_POSITION
wheel_status,
wheel_send_events,
#endif
ata_spindown,
/* new stuff at the end, sort into place next time
the API gets incompatible */
};
int plugin_load(const char* plugin, void* parameter)
{
int rc;
struct plugin_header *hdr;
const char *p = strrchr(plugin,'/');
#ifdef SIMULATOR
void *pd;
#else
@ -495,14 +498,23 @@ int plugin_load(const char* plugin, void* parameter)
fb_data* old_backdrop;
#endif
if (!p)
p = plugin;
action_signalscreenchange();
if (pfn_tsr_exit != NULL) /* if we have a resident old plugin: */
{
pfn_tsr_exit(); /* force it to exit now */
if (pfn_tsr_exit(!strcmp(current_plugin,p)) == false )
{
/* not allowing another plugin to load */
return PLUGIN_OK;
}
pfn_tsr_exit = NULL;
plugin_loaded = false;
}
gui_syncsplash(0, true, str(LANG_WAIT));
strcpy(current_plugin,p);
#ifdef SIMULATOR
hdr = sim_plugin_load((char *)plugin, &pd);
@ -635,7 +647,6 @@ int plugin_load(const char* plugin, void* parameter)
gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_ERROR));
break;
}
action_signalscreenchange();
return PLUGIN_OK;
}
@ -675,7 +686,7 @@ void* plugin_get_audio_buffer(int* buffer_size)
/* The plugin wants to stay resident after leaving its main function, e.g.
runs from timer or own thread. The callback is registered to later
instruct it to free its resources before a new plugin gets loaded. */
void plugin_tsr(void (*exit_callback)(void))
void plugin_tsr(bool (*exit_callback)(bool))
{
pfn_tsr_exit = exit_callback; /* remember the callback for later */
}

View file

@ -105,12 +105,12 @@
#define PLUGIN_MAGIC 0x526F634B /* RocK */
/* increase this every time the api struct changes */
#define PLUGIN_API_VERSION 33
#define PLUGIN_API_VERSION 34
/* update this to latest version if a change to the api struct breaks
backwards compatibility (and please take the opportunity to sort in any
new function which are "waiting" at the end of the function table) */
#define PLUGIN_MIN_API_VERSION 30
#define PLUGIN_MIN_API_VERSION 34
/* plugin return codes */
enum plugin_status {
@ -304,6 +304,7 @@ struct plugin_api {
void (*ata_sleep)(void);
bool (*ata_disk_is_active)(void);
#endif
void (*ata_spindown)(int seconds);
void (*reload_directory)(void);
/* dir */
@ -378,6 +379,7 @@ struct plugin_api {
void *(*memchr)(const void *s1, int c, size_t n);
int (*memcmp)(const void *s1, const void *s2, size_t n);
char *(*strcasestr) (const char* phaystack, const char* pneedle);
char* (*strtok_r)(char *ptr, const char *sep, char **end);
/* unicode stuff */
const unsigned char* (*utf8decode)(const unsigned char *utf8, unsigned short *ucs);
unsigned char* (*iso_decode)(const unsigned char *iso, unsigned char *utf8, int cp, int count);
@ -511,7 +513,7 @@ struct plugin_api {
int (*set_time)(const struct tm *tm);
void* (*plugin_get_buffer)(int* buffer_size);
void* (*plugin_get_audio_buffer)(int* buffer_size);
void (*plugin_tsr)(void (*exit_callback)(void));
void (*plugin_tsr)(bool (*exit_callback)(bool reenter));
#if defined(DEBUG) || defined(SIMULATOR)
void (*debugf)(const char *fmt, ...);
#endif
@ -543,16 +545,15 @@ struct plugin_api {
int (*show_logo)(void);
struct tree_context* (*tree_get_context)(void);
/* new stuff at the end, sort into place next time
the API gets incompatible */
char* (*strtok_r)(char *ptr, const char *sep, char **end);
#ifdef HAVE_WHEEL_POSITION
int (*wheel_status)(void);
void (*wheel_send_events)(bool send);
#endif
void (*ata_spindown)(int seconds);
/* new stuff at the end, sort into place next time
the API gets incompatible */
};
/* plugin header */
@ -584,7 +585,11 @@ extern unsigned char plugin_end_addr[];
int plugin_load(const char* plugin, void* parameter);
void* plugin_get_buffer(int *buffer_size);
void* plugin_get_audio_buffer(int *buffer_size);
void plugin_tsr(void (*exit_callback)(void));
/* plugin_tsr,
callback returns true to allow the new plugin to load,
reenter means the currently running plugin is being reloaded */
void plugin_tsr(bool (*exit_callback)(bool reenter));
/* defined by the plugin */
enum plugin_status plugin_start(struct plugin_api* rockbox, void* parameter)

View file

@ -1122,8 +1122,10 @@ void thread(void)
}
/* callback to end the TSR plugin, called before a new one gets loaded */
void exit_tsr(void)
bool exit_tsr(bool reenter)
{
if (reenter)
return false; /* dont let it start again */
gTread.exiting = true; /* tell the thread to end */
while (!gTread.ended) /* wait until it did */
rb->yield();
@ -1133,6 +1135,7 @@ void exit_tsr(void)
timer_set_mode(TM_OFF); /* timer interrupt off */
sound_normal(); /* restore sound settings */
return true;
}
/****************** main ******************/

View file

@ -92,7 +92,7 @@ PLUGIN_HEADER
/****************************** Plugin Entry Point ****************************/
static struct plugin_api* rb;
int main(void);
void exit_tsr(void);
bool exit_tsr(bool);
void thread(void);
@ -119,13 +119,27 @@ struct batt_info
struct event_queue thread_q;
void exit_tsr(void)
bool exit_tsr(bool reenter)
{
rb->queue_post(&thread_q, EV_EXIT, NULL);
while (!s_thread.ended)
rb->yield();
/* remove the thread's queue from the broadcast list */
rb->queue_delete(&thread_q);
bool exit = true;
(void)reenter;
rb->lcd_clear_display();
rb->lcd_puts_scroll(0, 0, "Batt.Bench is currently running.");
rb->lcd_puts_scroll(0, 1, "Press OFF to cancel the test");
rb->lcd_puts_scroll(0, 2, "Anything else will resume");
rb->lcd_update();
if (rb->button_get(true) != BATTERY_OFF)
exit = false;
if (exit)
{
rb->queue_post(&thread_q, EV_EXIT, NULL);
while (!s_thread.ended)
rb->yield();
/* remove the thread's queue from the broadcast list */
rb->queue_delete(&thread_q);
return true;
}
else return false;
}
#define BIT_CHARGER 0x1000