* 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:
parent
23f127ddd7
commit
29e259a291
4 changed files with 61 additions and 28 deletions
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 ******************/
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue