diff options
Diffstat (limited to 'apps/plugin.c')
| -rw-r--r-- | apps/plugin.c | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/apps/plugin.c b/apps/plugin.c new file mode 100644 index 0000000..6366580 --- /dev/null +++ b/apps/plugin.c @@ -0,0 +1,221 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 Björn Stenberg + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include <stdbool.h> +#include <string.h> +#include <stdio.h> +#include "button.h" +#include "lcd.h" +#include "dir.h" +#include "file.h" +#include "kernel.h" +#include "sprintf.h" +#include "screens.h" +#include "misc.h" +#include "mas.h" +#include "plugin.h" +#include "lang.h" + +#ifdef SIMULATOR +#include <dlfcn.h> +#define PREFIX(_x_) x11_ ## _x_ +#else +#define PREFIX(_x_) _x_ +#endif + +static int plugin_test(int api_version, int model); + +static struct plugin_api rockbox_api = { + PLUGIN_API_VERSION, + + plugin_test, + + /* lcd */ + lcd_clear_display, + lcd_puts, + lcd_puts_scroll, + lcd_stop_scroll, +#ifdef HAVE_LCD_CHARCELLS + lcd_define_pattern, +#else + lcd_putsxy, + lcd_bitmap, + lcd_drawline, + lcd_clearline, + lcd_drawpixel, + lcd_clearpixel, + lcd_setfont, + lcd_clearrect, + lcd_fillrect, + lcd_drawrect, + lcd_invertrect, + lcd_getstringsize, + lcd_update, + lcd_update_rect, +#ifndef SIMULATOR + lcd_roll, +#endif +#endif + + /* button */ + button_get, + button_get_w_tmo, + + /* file */ + PREFIX(open), + PREFIX(close), + read, + lseek, + PREFIX(creat), + write, + remove, + rename, + ftruncate, + PREFIX(filesize), + fprintf, + read_line, + + /* dir */ + PREFIX(opendir), + PREFIX(closedir), + PREFIX(readdir), + + /* kernel */ + PREFIX(sleep), + usb_screen, + ¤t_tick, + + /* strings and memory */ + snprintf, + strcpy, + strlen, + memset, + memcpy, + + /* sound */ +#ifndef SIMULATOR +#ifdef HAVE_MAS3587F + mas_codec_readreg, +#endif +#endif + + /* misc */ + srand, + rand, + splash, +}; + +int plugin_load(char* plugin, void* parameter) +{ + enum plugin_status (*plugin_start)(struct plugin_api* api, void* param); + int rc; + char buf[64]; +#ifdef SIMULATOR + void* pd; + char path[256]; +#else + extern unsigned char pluginbuf[]; + int fd; +#endif + + lcd_clear_display(); +#ifdef HAVE_LCD_BITMAP + lcd_setmargins(0,0); + lcd_update(); +#endif +#ifdef SIMULATOR + snprintf(path, sizeof path, "archos%s", plugin); + pd = dlopen(path, RTLD_NOW); + if (!pd) { + snprintf(buf, sizeof buf, "Can't open %s", plugin); + splash(HZ*2, 0, true, buf); + dlclose(pd); + return -1; + } + + plugin_start = dlsym(pd, "plugin_start"); + if (!plugin_start) { + plugin_start = dlsym(pd, "_plugin_start"); + if (!plugin_start) { + splash(HZ*2, 0, true, "Can't find entry point"); + dlclose(pd); + return -1; + } + } +#else + fd = open(plugin, O_RDONLY); + if (fd < 0) { + snprintf(buf, sizeof buf, str(LANG_PLUGIN_CANT_OPEN), plugin); + splash(HZ*2, 0, true, buf); + return fd; + } + + plugin_start = (void*)&pluginbuf; + rc = read(fd, plugin_start, 0x8000); + close(fd); + if (rc < 0) { + /* read error */ + snprintf(buf, sizeof buf, str(LANG_READ_FAILED), plugin); + splash(HZ*2, 0, true, buf); + return -1; + } + if (rc == 0) { + /* loaded a 0-byte plugin, implying it's not for this model */ + splash(HZ*2, 0, true, str(LANG_PLUGIN_WRONG_MODEL)); + return -1; + } +#endif + + rc = plugin_start(&rockbox_api, parameter); + switch (rc) { + case PLUGIN_OK: + break; + + case PLUGIN_USB_CONNECTED: + return PLUGIN_USB_CONNECTED; + + case PLUGIN_WRONG_API_VERSION: + splash(HZ*2, 0, true, str(LANG_PLUGIN_WRONG_VERSION)); + break; + + case PLUGIN_WRONG_MODEL: + splash(HZ*2, 0, true, str(LANG_PLUGIN_WRONG_MODEL)); + break; + + default: + splash(HZ*2, 0, true, str(LANG_PLUGIN_ERROR)); + break; + } + +#ifdef SIMULATOR + dlclose(pd); +#endif + + return PLUGIN_OK; +} + +int plugin_test(int api_version, int model) +{ + if (api_version != PLUGIN_API_VERSION) + return PLUGIN_WRONG_API_VERSION; + + if (model != MODEL) + return PLUGIN_WRONG_MODEL; + + return PLUGIN_OK; +} |