diff options
-rw-r--r-- | apps/SOURCES | 1 | ||||
-rw-r--r-- | apps/filetree.c | 15 | ||||
-rw-r--r-- | apps/filetypes.c | 1 | ||||
-rw-r--r-- | apps/filetypes.h | 1 | ||||
-rw-r--r-- | apps/gui/option_select.c | 7 | ||||
-rw-r--r-- | apps/gui/wps.c | 6 | ||||
-rw-r--r-- | apps/lang/english.lang | 56 | ||||
-rw-r--r-- | apps/menus/settings_menu.c | 14 | ||||
-rw-r--r-- | apps/onplay.c | 30 | ||||
-rw-r--r-- | apps/onplay.h | 4 | ||||
-rw-r--r-- | apps/open_plugin.c | 204 | ||||
-rw-r--r-- | apps/open_plugin.h | 66 | ||||
-rw-r--r-- | apps/plugin.c | 8 | ||||
-rw-r--r-- | apps/plugin.h | 3 | ||||
-rw-r--r-- | apps/plugins/pictureflow/pictureflow.c | 19 | ||||
-rw-r--r-- | apps/plugins/shortcuts/shortcuts_view.c | 74 | ||||
-rw-r--r-- | apps/root_menu.c | 46 | ||||
-rw-r--r-- | apps/root_menu.h | 2 | ||||
-rw-r--r-- | apps/settings_list.c | 54 | ||||
-rw-r--r-- | apps/settings_list.h | 1 | ||||
-rw-r--r-- | apps/shortcuts.c | 7 | ||||
-rw-r--r-- | apps/tree.c | 2 | ||||
-rwxr-xr-x | manual/advanced_topics/main.tex | 6 | ||||
-rw-r--r-- | manual/configure_rockbox/main.tex | 1 | ||||
-rw-r--r-- | manual/configure_rockbox/wps_context_plugin.tex | 5 |
25 files changed, 540 insertions, 93 deletions
diff --git a/apps/SOURCES b/apps/SOURCES index 5335258f70..ba36bc3ef6 100644 --- a/apps/SOURCES +++ b/apps/SOURCES | |||
@@ -38,6 +38,7 @@ menus/sound_menu.c | |||
38 | menus/time_menu.c | 38 | menus/time_menu.c |
39 | #endif | 39 | #endif |
40 | misc.c | 40 | misc.c |
41 | open_plugin.c | ||
41 | onplay.c | 42 | onplay.c |
42 | playlist.c | 43 | playlist.c |
43 | playlist_catalog.c | 44 | playlist_catalog.c |
diff --git a/apps/filetree.c b/apps/filetree.c index d645b7225c..cfa14f86b5 100644 --- a/apps/filetree.c +++ b/apps/filetree.c | |||
@@ -357,7 +357,8 @@ int ft_load(struct tree_context* c, const char* tempdir) | |||
357 | (*c->dirfilter == SHOW_LNG && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_LNG) || | 357 | (*c->dirfilter == SHOW_LNG && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_LNG) || |
358 | (*c->dirfilter == SHOW_MOD && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_MOD) || | 358 | (*c->dirfilter == SHOW_MOD && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_MOD) || |
359 | (*c->dirfilter == SHOW_PLUGINS && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_ROCK && | 359 | (*c->dirfilter == SHOW_PLUGINS && (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_ROCK && |
360 | (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_LUA) || | 360 | (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_LUA && |
361 | (dptr->attr & FILE_ATTR_MASK) != FILE_ATTR_OPX) || | ||
361 | (callback_show_item && !callback_show_item(entry->d_name, dptr->attr, c))) | 362 | (callback_show_item && !callback_show_item(entry->d_name, dptr->attr, c))) |
362 | { | 363 | { |
363 | continue; | 364 | continue; |
@@ -625,6 +626,7 @@ int ft_enter(struct tree_context* c) | |||
625 | /* plugin file */ | 626 | /* plugin file */ |
626 | case FILE_ATTR_ROCK: | 627 | case FILE_ATTR_ROCK: |
627 | case FILE_ATTR_LUA: | 628 | case FILE_ATTR_LUA: |
629 | case FILE_ATTR_OPX: | ||
628 | { | 630 | { |
629 | char *plugin = buf, *argument = NULL, lua_path[MAX_PATH]; | 631 | char *plugin = buf, *argument = NULL, lua_path[MAX_PATH]; |
630 | int ret; | 632 | int ret; |
@@ -634,6 +636,11 @@ int ft_enter(struct tree_context* c) | |||
634 | plugin = lua_path; | 636 | plugin = lua_path; |
635 | argument = buf; | 637 | argument = buf; |
636 | } | 638 | } |
639 | else if ((file_attr & FILE_ATTR_MASK) == FILE_ATTR_OPX) { | ||
640 | snprintf(lua_path, sizeof(lua_path)-1, "%s/open_plugins.rock", VIEWERS_DIR); /* Use a #define here ? */ | ||
641 | plugin = lua_path; | ||
642 | argument = buf; | ||
643 | } | ||
637 | 644 | ||
638 | if (global_settings.party_mode && audio_status()) { | 645 | if (global_settings.party_mode && audio_status()) { |
639 | splash(HZ, ID2P(LANG_PARTY_MODE)); | 646 | splash(HZ, ID2P(LANG_PARTY_MODE)); |
@@ -645,6 +652,9 @@ int ft_enter(struct tree_context* c) | |||
645 | case PLUGIN_GOTO_WPS: | 652 | case PLUGIN_GOTO_WPS: |
646 | play = true; | 653 | play = true; |
647 | break; | 654 | break; |
655 | case PLUGIN_GOTO_PLUGIN: | ||
656 | rc = GO_TO_PLUGIN; | ||
657 | break; | ||
648 | case PLUGIN_USB_CONNECTED: | 658 | case PLUGIN_USB_CONNECTED: |
649 | if(*c->dirfilter > NUM_FILTER_MODES) | 659 | if(*c->dirfilter > NUM_FILTER_MODES) |
650 | /* leave sub-browsers after usb, doing | 660 | /* leave sub-browsers after usb, doing |
@@ -690,6 +700,9 @@ int ft_enter(struct tree_context* c) | |||
690 | case PLUGIN_USB_CONNECTED: | 700 | case PLUGIN_USB_CONNECTED: |
691 | rc = GO_TO_FILEBROWSER; | 701 | rc = GO_TO_FILEBROWSER; |
692 | break; | 702 | break; |
703 | case PLUGIN_GOTO_PLUGIN: | ||
704 | rc = GO_TO_PLUGIN; | ||
705 | break; | ||
693 | case PLUGIN_GOTO_WPS: | 706 | case PLUGIN_GOTO_WPS: |
694 | rc = GO_TO_WPS; | 707 | rc = GO_TO_WPS; |
695 | break; | 708 | break; |
diff --git a/apps/filetypes.c b/apps/filetypes.c index 39fb2c5b32..391412b172 100644 --- a/apps/filetypes.c +++ b/apps/filetypes.c | |||
@@ -125,6 +125,7 @@ static const struct filetype inbuilt_filetypes[] = { | |||
125 | { "lng", FILE_ATTR_LNG, Icon_Language, LANG_LANGUAGE }, | 125 | { "lng", FILE_ATTR_LNG, Icon_Language, LANG_LANGUAGE }, |
126 | { "rock",FILE_ATTR_ROCK,Icon_Plugin, VOICE_EXT_ROCK }, | 126 | { "rock",FILE_ATTR_ROCK,Icon_Plugin, VOICE_EXT_ROCK }, |
127 | { "lua", FILE_ATTR_LUA, Icon_Plugin, VOICE_EXT_ROCK }, | 127 | { "lua", FILE_ATTR_LUA, Icon_Plugin, VOICE_EXT_ROCK }, |
128 | { "opx", FILE_ATTR_OPX, Icon_Plugin, VOICE_EXT_ROCK }, | ||
128 | { "fnt", FILE_ATTR_FONT,Icon_Font, VOICE_EXT_FONT }, | 129 | { "fnt", FILE_ATTR_FONT,Icon_Font, VOICE_EXT_FONT }, |
129 | { "kbd", FILE_ATTR_KBD, Icon_Keyboard, VOICE_EXT_KBD }, | 130 | { "kbd", FILE_ATTR_KBD, Icon_Keyboard, VOICE_EXT_KBD }, |
130 | { "bmark",FILE_ATTR_BMARK, Icon_Bookmark, VOICE_EXT_BMARK }, | 131 | { "bmark",FILE_ATTR_BMARK, Icon_Bookmark, VOICE_EXT_BMARK }, |
diff --git a/apps/filetypes.h b/apps/filetypes.h index 8c9e9a5d93..23f259b3ca 100644 --- a/apps/filetypes.h +++ b/apps/filetypes.h | |||
@@ -47,6 +47,7 @@ | |||
47 | #define FILE_ATTR_LUA 0x1100 /* Lua rockbox plugin */ | 47 | #define FILE_ATTR_LUA 0x1100 /* Lua rockbox plugin */ |
48 | #define FILE_ATTR_FMS 0x1200 /* FM screen skin file */ | 48 | #define FILE_ATTR_FMS 0x1200 /* FM screen skin file */ |
49 | #define FILE_ATTR_RFMS 0x1300 /* FM screen skin file */ | 49 | #define FILE_ATTR_RFMS 0x1300 /* FM screen skin file */ |
50 | #define FILE_ATTR_OPX 0x1400 /* open plugins shortcut */ | ||
50 | #define FILE_ATTR_MASK 0xFF00 /* which bits tree.c uses for file types */ | 51 | #define FILE_ATTR_MASK 0xFF00 /* which bits tree.c uses for file types */ |
51 | 52 | ||
52 | struct filetype { | 53 | struct filetype { |
diff --git a/apps/gui/option_select.c b/apps/gui/option_select.c index ec8b474191..ff257a4925 100644 --- a/apps/gui/option_select.c +++ b/apps/gui/option_select.c | |||
@@ -467,6 +467,8 @@ bool option_screen(const struct settings_list *setting, | |||
467 | int oldvalue, nb_items = 0, selected = 0, temp_var; | 467 | int oldvalue, nb_items = 0, selected = 0, temp_var; |
468 | int *variable; | 468 | int *variable; |
469 | bool allow_wrap = setting->flags & F_NO_WRAP ? false : true; | 469 | bool allow_wrap = setting->flags & F_NO_WRAP ? false : true; |
470 | bool cb_on_select_only = | ||
471 | ((setting->flags & F_CB_ON_SELECT_ONLY) == F_CB_ON_SELECT_ONLY); | ||
470 | int var_type = setting->flags&F_T_MASK; | 472 | int var_type = setting->flags&F_T_MASK; |
471 | void (*function)(int) = NULL; | 473 | void (*function)(int) = NULL; |
472 | char *title; | 474 | char *title; |
@@ -554,12 +556,15 @@ bool option_screen(const struct settings_list *setting, | |||
554 | } | 556 | } |
555 | settings_save(); | 557 | settings_save(); |
556 | done = true; | 558 | done = true; |
559 | if (cb_on_select_only && function) | ||
560 | function(*variable); | ||
557 | } | 561 | } |
558 | else if(default_event_handler(action) == SYS_USB_CONNECTED) | 562 | else if(default_event_handler(action) == SYS_USB_CONNECTED) |
559 | return true; | 563 | return true; |
560 | /* callback */ | 564 | /* callback */ |
561 | if ( function ) | 565 | if (function && !cb_on_select_only) |
562 | function(*variable); | 566 | function(*variable); |
567 | |||
563 | /* if the volume is changing we need to let the skins know */ | 568 | /* if the volume is changing we need to let the skins know */ |
564 | if (function == sound_get_fn(SOUND_VOLUME)) | 569 | if (function == sound_get_fn(SOUND_VOLUME)) |
565 | global_status.last_volume_change = current_tick; | 570 | global_status.last_volume_change = current_tick; |
diff --git a/apps/gui/wps.c b/apps/gui/wps.c index 8d0453385b..8a51d9b810 100644 --- a/apps/gui/wps.c +++ b/apps/gui/wps.c | |||
@@ -687,10 +687,8 @@ long gui_wps_show(void) | |||
687 | return GO_TO_ROOT; | 687 | return GO_TO_ROOT; |
688 | else if (retval == ONPLAY_PLAYLIST) | 688 | else if (retval == ONPLAY_PLAYLIST) |
689 | return GO_TO_PLAYLIST_VIEWER; | 689 | return GO_TO_PLAYLIST_VIEWER; |
690 | #ifdef HAVE_PICTUREFLOW_INTEGRATION | 690 | else if (retval == ONPLAY_PLUGIN) |
691 | else if (retval == ONPLAY_PICTUREFLOW) | 691 | return GO_TO_PLUGIN; |
692 | return GO_TO_PICTUREFLOW; | ||
693 | #endif | ||
694 | restore = true; | 692 | restore = true; |
695 | } | 693 | } |
696 | break; | 694 | break; |
diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 5937df64c0..8af6e55c5e 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang | |||
@@ -16150,3 +16150,59 @@ | |||
16150 | hotkey: "Hold for settings" | 16150 | hotkey: "Hold for settings" |
16151 | </voice> | 16151 | </voice> |
16152 | </phrase> | 16152 | </phrase> |
16153 | <phrase> | ||
16154 | id: LANG_OPEN_PLUGIN | ||
16155 | desc: onplay open plugin | ||
16156 | user: core | ||
16157 | <source> | ||
16158 | *: "Open Plugin" | ||
16159 | </source> | ||
16160 | <dest> | ||
16161 | *: "Open Plugin" | ||
16162 | </dest> | ||
16163 | <voice> | ||
16164 | *: "Open Plugin" | ||
16165 | </voice> | ||
16166 | </phrase> | ||
16167 | <phrase> | ||
16168 | id: LANG_OPEN_PLUGIN_NOT_A_PLUGIN | ||
16169 | desc: open plugin module | ||
16170 | user: core | ||
16171 | <source> | ||
16172 | *: "Not a plugin: %s" | ||
16173 | </source> | ||
16174 | <dest> | ||
16175 | *: "Not a plugin: %s" | ||
16176 | </dest> | ||
16177 | <voice> | ||
16178 | *: "Not a plugin" | ||
16179 | </voice> | ||
16180 | </phrase> | ||
16181 | <phrase> | ||
16182 | id: LANG_OPEN_PLUGIN_SET_WPS_CONTEXT_PLUGIN | ||
16183 | desc: open plugin module | ||
16184 | user: core | ||
16185 | <source> | ||
16186 | *: "Set Wps Context Plugin" | ||
16187 | </source> | ||
16188 | <dest> | ||
16189 | *: "Set Wps Context Plugin" | ||
16190 | </dest> | ||
16191 | <voice> | ||
16192 | *: "Set Wps Context Plugin" | ||
16193 | </voice> | ||
16194 | </phrase> | ||
16195 | <phrase> | ||
16196 | id: LANG_PARAMETER | ||
16197 | desc: | ||
16198 | user: core | ||
16199 | <source> | ||
16200 | *: "Parameter" | ||
16201 | </source> | ||
16202 | <dest> | ||
16203 | *: "Parameter" | ||
16204 | </dest> | ||
16205 | <voice> | ||
16206 | *: "Parameter" | ||
16207 | </voice> | ||
16208 | </phrase> | ||
diff --git a/apps/menus/settings_menu.c b/apps/menus/settings_menu.c index 431600bbe1..9275ff10d6 100644 --- a/apps/menus/settings_menu.c +++ b/apps/menus/settings_menu.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "action.h" | 28 | #include "action.h" |
29 | #include "settings.h" | 29 | #include "settings.h" |
30 | #include "menu.h" | 30 | #include "menu.h" |
31 | #include "open_plugin.h" | ||
31 | #include "keyboard.h" | 32 | #include "keyboard.h" |
32 | #include "sound_menu.h" | 33 | #include "sound_menu.h" |
33 | #include "exported_menus.h" | 34 | #include "exported_menus.h" |
@@ -711,6 +712,18 @@ MAKE_MENU(voice_settings_menu, ID2P(LANG_VOICE), 0, Icon_Voice, | |||
711 | /* VOICE MENU */ | 712 | /* VOICE MENU */ |
712 | /***********************************/ | 713 | /***********************************/ |
713 | 714 | ||
715 | /* WPS_CONTEXT_PLUGIN */ | ||
716 | /***********************************/ | ||
717 | static void wps_plugin_cb(void) | ||
718 | { | ||
719 | open_plugin_browse(ID2P(LANG_OPEN_PLUGIN_SET_WPS_CONTEXT_PLUGIN)); | ||
720 | } | ||
721 | MENUITEM_FUNCTION(wps_set_context_plugin, 0, | ||
722 | ID2P(LANG_OPEN_PLUGIN_SET_WPS_CONTEXT_PLUGIN), | ||
723 | wps_plugin_cb, NULL, NULL, Icon_Plugin); | ||
724 | |||
725 | /* WPS_CONTEXT_PLUGIN */ | ||
726 | /***********************************/ | ||
714 | 727 | ||
715 | /***********************************/ | 728 | /***********************************/ |
716 | /* HOTKEY MENU */ | 729 | /* HOTKEY MENU */ |
@@ -745,6 +758,7 @@ MAKE_MENU(settings_menu_item, ID2P(LANG_GENERAL_SETTINGS), 0, | |||
745 | &autoresume_menu, | 758 | &autoresume_menu, |
746 | #endif | 759 | #endif |
747 | &browse_langs, &voice_settings_menu, | 760 | &browse_langs, &voice_settings_menu, |
761 | &wps_set_context_plugin, | ||
748 | #ifdef HAVE_HOTKEY | 762 | #ifdef HAVE_HOTKEY |
749 | &hotkey_menu, | 763 | &hotkey_menu, |
750 | #endif | 764 | #endif |
diff --git a/apps/onplay.c b/apps/onplay.c index fd956167d3..f2ebd47630 100644 --- a/apps/onplay.c +++ b/apps/onplay.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include "talk.h" | 43 | #include "talk.h" |
44 | #include "onplay.h" | 44 | #include "onplay.h" |
45 | #include "filetypes.h" | 45 | #include "filetypes.h" |
46 | #include "open_plugin.h" | ||
46 | #include "plugin.h" | 47 | #include "plugin.h" |
47 | #include "bookmark.h" | 48 | #include "bookmark.h" |
48 | #include "action.h" | 49 | #include "action.h" |
@@ -1415,10 +1416,8 @@ MENUITEM_FUNCTION(rating_item, 0, ID2P(LANG_MENU_SET_RATING), | |||
1415 | set_rating_inline, NULL, | 1416 | set_rating_inline, NULL, |
1416 | ratingitem_callback, Icon_Questionmark); | 1417 | ratingitem_callback, Icon_Questionmark); |
1417 | #endif | 1418 | #endif |
1418 | #ifdef HAVE_PICTUREFLOW_INTEGRATION | 1419 | MENUITEM_RETURNVALUE(plugin_item, ID2P(LANG_OPEN_PLUGIN), |
1419 | MENUITEM_RETURNVALUE(pictureflow_item, ID2P(LANG_ONPLAY_PICTUREFLOW), | 1420 | GO_TO_PLUGIN, NULL, Icon_Plugin); |
1420 | GO_TO_PICTUREFLOW, NULL, Icon_NOICON); | ||
1421 | #endif | ||
1422 | 1421 | ||
1423 | static bool view_cue(void) | 1422 | static bool view_cue(void) |
1424 | { | 1423 | { |
@@ -1650,9 +1649,7 @@ MAKE_ONPLAYMENU( wps_onplay_menu, ID2P(LANG_ONPLAY_MENU_TITLE), | |||
1650 | &rating_item, | 1649 | &rating_item, |
1651 | #endif | 1650 | #endif |
1652 | &bookmark_menu, | 1651 | &bookmark_menu, |
1653 | #ifdef HAVE_PICTUREFLOW_INTEGRATION | 1652 | &plugin_item, |
1654 | &pictureflow_item, | ||
1655 | #endif | ||
1656 | &browse_id3_item, &list_viewers_item, | 1653 | &browse_id3_item, &list_viewers_item, |
1657 | &delete_file_item, &view_cue_item, | 1654 | &delete_file_item, &view_cue_item, |
1658 | #ifdef HAVE_PITCHCONTROL | 1655 | #ifdef HAVE_PITCHCONTROL |
@@ -1732,6 +1729,11 @@ static int playlist_insert_shuffled(void) | |||
1732 | return ONPLAY_RELOAD_DIR; | 1729 | return ONPLAY_RELOAD_DIR; |
1733 | } | 1730 | } |
1734 | 1731 | ||
1732 | static void hotkey_run_plugin(void) | ||
1733 | { | ||
1734 | open_plugin_run(ID2P(LANG_HOTKEY_WPS)); | ||
1735 | } | ||
1736 | |||
1735 | struct hotkey_assignment { | 1737 | struct hotkey_assignment { |
1736 | int action; /* hotkey_action */ | 1738 | int action; /* hotkey_action */ |
1737 | int lang_id; /* Language ID */ | 1739 | int lang_id; /* Language ID */ |
@@ -1768,11 +1770,9 @@ static struct hotkey_assignment hotkey_items[] = { | |||
1768 | { HOTKEY_INSERT_SHUFFLED, LANG_INSERT_SHUFFLED, | 1770 | { HOTKEY_INSERT_SHUFFLED, LANG_INSERT_SHUFFLED, |
1769 | HOTKEY_FUNC(playlist_insert_shuffled, NULL), | 1771 | HOTKEY_FUNC(playlist_insert_shuffled, NULL), |
1770 | ONPLAY_RELOAD_DIR }, | 1772 | ONPLAY_RELOAD_DIR }, |
1771 | #ifdef HAVE_PICTUREFLOW_INTEGRATION | 1773 | { HOTKEY_PLUGIN, LANG_OPEN_PLUGIN, |
1772 | { HOTKEY_PICTUREFLOW, LANG_ONPLAY_PICTUREFLOW, | 1774 | HOTKEY_FUNC(hotkey_run_plugin, NULL), |
1773 | HOTKEY_FUNC(NULL, NULL), | 1775 | ONPLAY_OK }, |
1774 | ONPLAY_PICTUREFLOW }, | ||
1775 | #endif | ||
1776 | { HOTKEY_BOOKMARK, LANG_BOOKMARK_MENU_CREATE, | 1776 | { HOTKEY_BOOKMARK, LANG_BOOKMARK_MENU_CREATE, |
1777 | HOTKEY_FUNC(bookmark_create_menu, NULL), | 1777 | HOTKEY_FUNC(bookmark_create_menu, NULL), |
1778 | ONPLAY_OK }, | 1778 | ONPLAY_OK }, |
@@ -1861,10 +1861,8 @@ int onplay(char* file, int attr, int from, bool hotkey) | |||
1861 | return ONPLAY_MAINMENU; | 1861 | return ONPLAY_MAINMENU; |
1862 | case GO_TO_PLAYLIST_VIEWER: | 1862 | case GO_TO_PLAYLIST_VIEWER: |
1863 | return ONPLAY_PLAYLIST; | 1863 | return ONPLAY_PLAYLIST; |
1864 | #ifdef HAVE_PICTUREFLOW_INTEGRATION | 1864 | case GO_TO_PLUGIN: |
1865 | case GO_TO_PICTUREFLOW: | 1865 | return ONPLAY_PLUGIN; |
1866 | return ONPLAY_PICTUREFLOW; | ||
1867 | #endif | ||
1868 | default: | 1866 | default: |
1869 | return onplay_result; | 1867 | return onplay_result; |
1870 | } | 1868 | } |
diff --git a/apps/onplay.h b/apps/onplay.h index 24637ac18c..27f0436403 100644 --- a/apps/onplay.h +++ b/apps/onplay.h | |||
@@ -29,7 +29,7 @@ enum { | |||
29 | ONPLAY_RELOAD_DIR, | 29 | ONPLAY_RELOAD_DIR, |
30 | ONPLAY_START_PLAY, | 30 | ONPLAY_START_PLAY, |
31 | ONPLAY_PLAYLIST, | 31 | ONPLAY_PLAYLIST, |
32 | ONPLAY_PICTUREFLOW, | 32 | ONPLAY_PLUGIN, |
33 | }; | 33 | }; |
34 | 34 | ||
35 | #ifdef HAVE_HOTKEY | 35 | #ifdef HAVE_HOTKEY |
@@ -44,7 +44,7 @@ enum hotkey_action { | |||
44 | HOTKEY_DELETE, | 44 | HOTKEY_DELETE, |
45 | HOTKEY_INSERT, | 45 | HOTKEY_INSERT, |
46 | HOTKEY_INSERT_SHUFFLED, | 46 | HOTKEY_INSERT_SHUFFLED, |
47 | HOTKEY_PICTUREFLOW, | 47 | HOTKEY_PLUGIN, |
48 | HOTKEY_BOOKMARK, | 48 | HOTKEY_BOOKMARK, |
49 | }; | 49 | }; |
50 | #endif | 50 | #endif |
diff --git a/apps/open_plugin.c b/apps/open_plugin.c new file mode 100644 index 0000000000..0fb20403bc --- /dev/null +++ b/apps/open_plugin.c | |||
@@ -0,0 +1,204 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2020 by William Wilgus | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #ifndef __PCTOOL__ | ||
23 | |||
24 | #include "plugin.h" | ||
25 | #include "open_plugin.h" | ||
26 | #include "pathfuncs.h" | ||
27 | #include "keyboard.h" | ||
28 | #include "splash.h" | ||
29 | #include "lang.h" | ||
30 | |||
31 | struct open_plugin_entry_t open_plugin_entry; | ||
32 | |||
33 | static const int op_entry_sz = sizeof(struct open_plugin_entry_t); | ||
34 | |||
35 | static void get_param(void) | ||
36 | { | ||
37 | char tmp_buf[OPEN_PLUGIN_BUFSZ+1]; | ||
38 | strlcpy(tmp_buf, open_plugin_entry.param, OPEN_PLUGIN_BUFSZ); | ||
39 | if (kbd_input(tmp_buf, OPEN_PLUGIN_BUFSZ, NULL)) | ||
40 | strlcpy(open_plugin_entry.param, tmp_buf, OPEN_PLUGIN_BUFSZ); | ||
41 | } | ||
42 | |||
43 | uint32_t open_plugin_add_path(const char *key, const char *plugin, const char *parameter) | ||
44 | { | ||
45 | int len; | ||
46 | uint32_t hash; | ||
47 | char *pos; | ||
48 | int fd = 0; | ||
49 | |||
50 | /*strlcpy(plug_entry.key, key, sizeof(plug_entry.key));*/ | ||
51 | open_plugin_entry.lang_id = P2ID((unsigned char*)key); | ||
52 | key = P2STR((unsigned char *)key); | ||
53 | |||
54 | open_plugin_get_hash(key, &hash); | ||
55 | open_plugin_entry.hash = hash; | ||
56 | |||
57 | if (plugin) | ||
58 | { | ||
59 | /* name */ | ||
60 | if (path_basename(plugin, (const char **)&pos) == 0) | ||
61 | pos = "\0"; | ||
62 | |||
63 | len = strlcpy(open_plugin_entry.name, pos, OPEN_PLUGIN_NAMESZ); | ||
64 | |||
65 | if(len > 5 && strcasecmp(&(pos[len-5]), ".rock") == 0) | ||
66 | { | ||
67 | fd = open(OPEN_PLUGIN_DAT ".tmp", O_WRONLY | O_CREAT | O_TRUNC, 0666); | ||
68 | if (!fd) | ||
69 | return 0; | ||
70 | |||
71 | /* path */ | ||
72 | strlcpy(open_plugin_entry.path, plugin, OPEN_PLUGIN_BUFSZ); | ||
73 | |||
74 | if(parameter) | ||
75 | { | ||
76 | if (parameter[0] == '\0' && | ||
77 | yesno_pop(ID2P(LANG_PARAMETER))) | ||
78 | { | ||
79 | get_param(); | ||
80 | } | ||
81 | else | ||
82 | strlcpy(open_plugin_entry.param, parameter, OPEN_PLUGIN_BUFSZ); | ||
83 | } | ||
84 | |||
85 | write(fd, &open_plugin_entry, op_entry_sz); | ||
86 | } | ||
87 | else | ||
88 | { | ||
89 | if (open_plugin_entry.lang_id != LANG_SHORTCUTS) | ||
90 | splashf(HZ / 2, str(LANG_OPEN_PLUGIN_NOT_A_PLUGIN), pos); | ||
91 | return 0; | ||
92 | } | ||
93 | } | ||
94 | |||
95 | int fd1 = open(OPEN_PLUGIN_DAT, O_RDONLY); | ||
96 | if (fd1) | ||
97 | { | ||
98 | while (read(fd1, &open_plugin_entry, op_entry_sz) == op_entry_sz) | ||
99 | { | ||
100 | if (open_plugin_entry.hash != hash) | ||
101 | write(fd, &open_plugin_entry, op_entry_sz); | ||
102 | } | ||
103 | close(fd1); | ||
104 | } | ||
105 | close(fd); | ||
106 | |||
107 | if(fd1) | ||
108 | { | ||
109 | remove(OPEN_PLUGIN_DAT); | ||
110 | rename(OPEN_PLUGIN_DAT ".tmp", OPEN_PLUGIN_DAT); | ||
111 | } | ||
112 | else | ||
113 | hash = 0; | ||
114 | |||
115 | return hash; | ||
116 | } | ||
117 | |||
118 | void open_plugin_browse(const char *key) | ||
119 | { | ||
120 | struct browse_context browse; | ||
121 | char tmp_buf[OPEN_PLUGIN_BUFSZ+1]; | ||
122 | open_plugin_get_entry(key, &open_plugin_entry); | ||
123 | |||
124 | if (open_plugin_entry.path[0] == '\0') | ||
125 | strcpy(open_plugin_entry.path, PLUGIN_DIR"/"); | ||
126 | |||
127 | browse_context_init(&browse, SHOW_ALL, BROWSE_SELECTONLY, "", | ||
128 | Icon_Plugin, open_plugin_entry.path, NULL); | ||
129 | |||
130 | browse.buf = tmp_buf; | ||
131 | browse.bufsize = OPEN_PLUGIN_BUFSZ; | ||
132 | |||
133 | if (rockbox_browse(&browse) == GO_TO_PREVIOUS) | ||
134 | { | ||
135 | open_plugin_add_path(key, tmp_buf, NULL); | ||
136 | } | ||
137 | } | ||
138 | |||
139 | void open_plugin_remove(const char *key) | ||
140 | { | ||
141 | (void)key; | ||
142 | open_plugin_add_path(key, NULL, NULL); | ||
143 | } | ||
144 | |||
145 | static int open_plugin_hash_get_entry(uint32_t hash, struct open_plugin_entry_t *entry) | ||
146 | { | ||
147 | int ret = -1, record = -1; | ||
148 | |||
149 | if (entry) | ||
150 | { | ||
151 | int fd = open(OPEN_PLUGIN_DAT, O_RDONLY); | ||
152 | |||
153 | if (fd) | ||
154 | { | ||
155 | while (read(fd, entry, op_entry_sz) == op_entry_sz) | ||
156 | { | ||
157 | record++; | ||
158 | if (entry->hash == hash) | ||
159 | { | ||
160 | ret = record; | ||
161 | break; | ||
162 | } | ||
163 | } | ||
164 | close(fd); | ||
165 | } | ||
166 | if (ret < 0) | ||
167 | { | ||
168 | memset(entry, 0, op_entry_sz); | ||
169 | entry->lang_id = -1; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | return ret; | ||
174 | } | ||
175 | |||
176 | int open_plugin_get_entry(const char *key, struct open_plugin_entry_t *entry) | ||
177 | { | ||
178 | uint32_t hash; | ||
179 | key = P2STR((unsigned char *)key); | ||
180 | |||
181 | open_plugin_get_hash(key, &hash); | ||
182 | return open_plugin_hash_get_entry(hash, entry); | ||
183 | } | ||
184 | |||
185 | int open_plugin_run(const char *key) | ||
186 | { | ||
187 | int ret = 0; | ||
188 | const char *path; | ||
189 | const char *param; | ||
190 | |||
191 | open_plugin_get_entry(key, &open_plugin_entry); | ||
192 | |||
193 | path = open_plugin_entry.path; | ||
194 | param = open_plugin_entry.param; | ||
195 | if (param[0] == '\0') | ||
196 | param = NULL; | ||
197 | |||
198 | if (path) | ||
199 | ret = plugin_load(path, param); | ||
200 | |||
201 | return ret; | ||
202 | } | ||
203 | |||
204 | #endif /* ndef __PCTOOL__ */ | ||
diff --git a/apps/open_plugin.h b/apps/open_plugin.h new file mode 100644 index 0000000000..2d8a527073 --- /dev/null +++ b/apps/open_plugin.h | |||
@@ -0,0 +1,66 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2020 by William Wilgus | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef OPEN_PLUGIN_H | ||
22 | #define OPEN_PLUGIN_H | ||
23 | |||
24 | /* Open_plugin module | ||
25 | * OP stores and retrieves plugin path and parameters by key | ||
26 | * from a dictionary file | ||
27 | * | ||
28 | * plugins can load other plugins | ||
29 | * return rb->plugin_open(path, parameter); | ||
30 | */ | ||
31 | |||
32 | #ifndef __PCTOOL__ | ||
33 | /* open_plugin path lookup */ | ||
34 | #define OPEN_PLUGIN_DAT PLUGIN_DIR "/plugin.dat" | ||
35 | #define OPEN_PLUGIN_BUFSZ MAX_PATH | ||
36 | #define OPEN_PLUGIN_NAMESZ 32 | ||
37 | struct open_plugin_entry_t | ||
38 | { | ||
39 | uint32_t hash; | ||
40 | int32_t lang_id; | ||
41 | char name[OPEN_PLUGIN_NAMESZ+1]; | ||
42 | /*char key[OPEN_PLUGIN_BUFSZ+1];*/ | ||
43 | char path[OPEN_PLUGIN_BUFSZ+1]; | ||
44 | char param[OPEN_PLUGIN_BUFSZ+1]; | ||
45 | }; | ||
46 | |||
47 | inline static void open_plugin_get_hash(const char *key, uint32_t *hash) | ||
48 | { | ||
49 | /* Calculate modified FNV1a hash of string */ | ||
50 | const uint32_t p = 16777619; | ||
51 | *hash = 0x811C9DC5; //seed, 2166136261; | ||
52 | while(*key) | ||
53 | *hash = (*key++ ^ *hash) * p; | ||
54 | } | ||
55 | |||
56 | #ifndef PLUGIN | ||
57 | extern struct open_plugin_entry_t open_plugin_entry; | ||
58 | uint32_t open_plugin_add_path(const char *key, const char *plugin, const char *parameter); | ||
59 | int open_plugin_get_entry(const char *key, struct open_plugin_entry_t *entry); | ||
60 | void open_plugin_browse(const char *key); | ||
61 | void open_plugin_remove(const char *key); | ||
62 | int open_plugin_run(const char *key); | ||
63 | #endif | ||
64 | |||
65 | #endif /*ndef __PCTOOL__ */ | ||
66 | #endif /* OPEN_PLUGIN_H */ | ||
diff --git a/apps/plugin.c b/apps/plugin.c index 2066d3a108..749132cde8 100644 --- a/apps/plugin.c +++ b/apps/plugin.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #define DIRFUNCTIONS_DEFINED | 21 | #define DIRFUNCTIONS_DEFINED |
22 | #define FILEFUNCTIONS_DEFINED | 22 | #define FILEFUNCTIONS_DEFINED |
23 | #include "plugin.h" | 23 | #include "plugin.h" |
24 | #include "open_plugin.h" | ||
24 | #include <ctype.h> | 25 | #include <ctype.h> |
25 | #include <string.h> | 26 | #include <string.h> |
26 | #include <stdlib.h> | 27 | #include <stdlib.h> |
@@ -807,6 +808,7 @@ static const struct plugin_api rockbox_api = { | |||
807 | #ifdef HAVE_TAGCACHE | 808 | #ifdef HAVE_TAGCACHE |
808 | tagcache_get_stat, | 809 | tagcache_get_stat, |
809 | #endif | 810 | #endif |
811 | plugin_open, | ||
810 | }; | 812 | }; |
811 | 813 | ||
812 | static int plugin_buffer_handle; | 814 | static int plugin_buffer_handle; |
@@ -1019,6 +1021,12 @@ static void plugin_tsr(bool (*exit_callback)(bool)) | |||
1019 | pfn_tsr_exit = exit_callback; /* remember the callback for later */ | 1021 | pfn_tsr_exit = exit_callback; /* remember the callback for later */ |
1020 | } | 1022 | } |
1021 | 1023 | ||
1024 | int plugin_open(char *plugin, char *parameter) | ||
1025 | { | ||
1026 | open_plugin_add_path(ID2P(LANG_OPEN_PLUGIN), plugin, parameter); | ||
1027 | return PLUGIN_GOTO_PLUGIN; | ||
1028 | } | ||
1029 | |||
1022 | char *plugin_get_current_filename(void) | 1030 | char *plugin_get_current_filename(void) |
1023 | { | 1031 | { |
1024 | return current_plugin; | 1032 | return current_plugin; |
diff --git a/apps/plugin.h b/apps/plugin.h index 2585d17205..fc3da61c57 100644 --- a/apps/plugin.h +++ b/apps/plugin.h | |||
@@ -49,6 +49,7 @@ | |||
49 | 49 | ||
50 | char* strncpy(char *, const char *, size_t); | 50 | char* strncpy(char *, const char *, size_t); |
51 | void* plugin_get_buffer(size_t *buffer_size); | 51 | void* plugin_get_buffer(size_t *buffer_size); |
52 | int plugin_open(char *plugin, char *parameter); | ||
52 | 53 | ||
53 | #ifndef __PCTOOL__ | 54 | #ifndef __PCTOOL__ |
54 | #include "config.h" | 55 | #include "config.h" |
@@ -172,6 +173,7 @@ enum plugin_status { | |||
172 | PLUGIN_USB_CONNECTED = INTERNAL_PLUGIN_RETVAL_START, | 173 | PLUGIN_USB_CONNECTED = INTERNAL_PLUGIN_RETVAL_START, |
173 | PLUGIN_POWEROFF, | 174 | PLUGIN_POWEROFF, |
174 | PLUGIN_GOTO_WPS, | 175 | PLUGIN_GOTO_WPS, |
176 | PLUGIN_GOTO_PLUGIN, | ||
175 | PLUGIN_ERROR = -1, | 177 | PLUGIN_ERROR = -1, |
176 | }; | 178 | }; |
177 | 179 | ||
@@ -934,6 +936,7 @@ struct plugin_api { | |||
934 | #ifdef HAVE_TAGCACHE | 936 | #ifdef HAVE_TAGCACHE |
935 | struct tagcache_stat* (*tagcache_get_stat)(void); | 937 | struct tagcache_stat* (*tagcache_get_stat)(void); |
936 | #endif | 938 | #endif |
939 | int (*plugin_open)(char *path, char *parameter); | ||
937 | 940 | ||
938 | }; | 941 | }; |
939 | 942 | ||
diff --git a/apps/plugins/pictureflow/pictureflow.c b/apps/plugins/pictureflow/pictureflow.c index d1da10ee09..91062f8f11 100644 --- a/apps/plugins/pictureflow/pictureflow.c +++ b/apps/plugins/pictureflow/pictureflow.c | |||
@@ -533,19 +533,28 @@ static void free_all_slide_prio(int prio); | |||
533 | static bool check_database(bool prompt) | 533 | static bool check_database(bool prompt) |
534 | { | 534 | { |
535 | bool needwarn = true; | 535 | bool needwarn = true; |
536 | int spin = 5; | ||
537 | |||
536 | struct tagcache_stat *stat = rb->tagcache_get_stat(); | 538 | struct tagcache_stat *stat = rb->tagcache_get_stat(); |
539 | |||
537 | while ( !(stat->initialized && stat->ready) ) | 540 | while ( !(stat->initialized && stat->ready) ) |
538 | { | 541 | { |
539 | if (needwarn) | 542 | if (--spin > 0) |
543 | { | ||
544 | rb->sleep(HZ/5); | ||
545 | } | ||
546 | else if (needwarn) | ||
547 | { | ||
548 | needwarn = false; | ||
540 | rb->splash(0, ID2P(LANG_TAGCACHE_BUSY)); | 549 | rb->splash(0, ID2P(LANG_TAGCACHE_BUSY)); |
541 | if (!prompt) | 550 | } |
551 | else if (!prompt) | ||
542 | return false; | 552 | return false; |
543 | else if (rb->action_userabort(HZ/5)) | 553 | else if (rb->action_userabort(HZ/5)) |
544 | return false; | 554 | return false; |
545 | 555 | ||
546 | needwarn = false; | ||
547 | stat = rb->tagcache_get_stat(); | ||
548 | rb->yield(); | 556 | rb->yield(); |
557 | stat = rb->tagcache_get_stat(); | ||
549 | } | 558 | } |
550 | return true; | 559 | return true; |
551 | } | 560 | } |
@@ -3841,7 +3850,7 @@ enum plugin_status plugin_start(const void *parameter) | |||
3841 | 3850 | ||
3842 | void * buf; | 3851 | void * buf; |
3843 | size_t buf_size; | 3852 | size_t buf_size; |
3844 | bool prompt = (parameter && ((char *) parameter)[0] == ACTIVITY_MAINMENU); | 3853 | bool prompt = (parameter && (((char *) parameter)[0] == ACTIVITY_MAINMENU)); |
3845 | 3854 | ||
3846 | if (!check_database(prompt)) | 3855 | if (!check_database(prompt)) |
3847 | { | 3856 | { |
diff --git a/apps/plugins/shortcuts/shortcuts_view.c b/apps/plugins/shortcuts/shortcuts_view.c index cfc9d8d746..f4c4b58bc1 100644 --- a/apps/plugins/shortcuts/shortcuts_view.c +++ b/apps/plugins/shortcuts/shortcuts_view.c | |||
@@ -22,7 +22,7 @@ | |||
22 | 22 | ||
23 | #include "shortcuts.h" | 23 | #include "shortcuts.h" |
24 | 24 | ||
25 | 25 | #define LOOP_EXIT 1 | |
26 | 26 | ||
27 | enum sc_list_action_type | 27 | enum sc_list_action_type |
28 | { | 28 | { |
@@ -35,7 +35,6 @@ enum sc_list_action_type | |||
35 | 35 | ||
36 | static char *link_filename; | 36 | static char *link_filename; |
37 | static bool user_file; | 37 | static bool user_file; |
38 | static bool usb_connected = false; | ||
39 | 38 | ||
40 | enum sc_list_action_type draw_sc_list(struct gui_synclist *gui_sc); | 39 | enum sc_list_action_type draw_sc_list(struct gui_synclist *gui_sc); |
41 | 40 | ||
@@ -43,10 +42,10 @@ enum sc_list_action_type draw_sc_list(struct gui_synclist *gui_sc); | |||
43 | static const char* build_sc_list(int selected_item, void *data, | 42 | static const char* build_sc_list(int selected_item, void *data, |
44 | char *buffer, size_t buffer_len); | 43 | char *buffer, size_t buffer_len); |
45 | 44 | ||
46 | /* Returns true iff we should leave the main loop */ | 45 | /* Returns LOOP_EXIT iff we should leave the main loop */ |
47 | bool list_sc(void); | 46 | int list_sc(void); |
48 | 47 | ||
49 | bool goto_entry(char *file_or_dir); | 48 | int goto_entry(char *file_or_dir); |
50 | bool ends_with(char *str, char *suffix); | 49 | bool ends_with(char *str, char *suffix); |
51 | 50 | ||
52 | 51 | ||
@@ -104,7 +103,7 @@ static const char* build_sc_list(int selected_item, void *data, | |||
104 | } | 103 | } |
105 | 104 | ||
106 | 105 | ||
107 | bool list_sc(void) | 106 | int list_sc(void) |
108 | { | 107 | { |
109 | int selected_item = 0; | 108 | int selected_item = 0; |
110 | enum sc_list_action_type action = SCLA_NONE; | 109 | enum sc_list_action_type action = SCLA_NONE; |
@@ -122,8 +121,7 @@ bool list_sc(void) | |||
122 | /* Draw the prepared widget to the LCD now */ | 121 | /* Draw the prepared widget to the LCD now */ |
123 | action = draw_sc_list(&gui_sc); | 122 | action = draw_sc_list(&gui_sc); |
124 | if (action == SCLA_USB) { | 123 | if (action == SCLA_USB) { |
125 | usb_connected = true; | 124 | return PLUGIN_USB_CONNECTED; |
126 | return true; | ||
127 | } | 125 | } |
128 | 126 | ||
129 | /* which item do we action? */ | 127 | /* which item do we action? */ |
@@ -132,7 +130,7 @@ bool list_sc(void) | |||
132 | if (!is_valid_index(&sc_file, selected_item)) { | 130 | if (!is_valid_index(&sc_file, selected_item)) { |
133 | /* This should never happen */ | 131 | /* This should never happen */ |
134 | rb->splash(HZ*2, "Bad entry selected!"); | 132 | rb->splash(HZ*2, "Bad entry selected!"); |
135 | return true; | 133 | return PLUGIN_ERROR; |
136 | } | 134 | } |
137 | 135 | ||
138 | /* perform the following actions if the user "selected" | 136 | /* perform the following actions if the user "selected" |
@@ -145,13 +143,13 @@ bool list_sc(void) | |||
145 | rb->splashf(HZ, "Deleting %s", sc_file.entries[selected_item].disp); | 143 | rb->splashf(HZ, "Deleting %s", sc_file.entries[selected_item].disp); |
146 | remove_entry(&sc_file, selected_item); | 144 | remove_entry(&sc_file, selected_item); |
147 | dump_sc_file(&sc_file, link_filename); | 145 | dump_sc_file(&sc_file, link_filename); |
148 | return (sc_file.entry_cnt == 0); | 146 | return (sc_file.entry_cnt == 0)? LOOP_EXIT : PLUGIN_OK; |
149 | default: | 147 | default: |
150 | return true; | 148 | return LOOP_EXIT; |
151 | } | 149 | } |
152 | } | 150 | } |
153 | 151 | ||
154 | 152 | #if 0 | |
155 | bool goto_entry(char *file_or_dir) | 153 | bool goto_entry(char *file_or_dir) |
156 | { | 154 | { |
157 | DEBUGF("Trying to go to '%s'...\n", file_or_dir); | 155 | DEBUGF("Trying to go to '%s'...\n", file_or_dir); |
@@ -181,7 +179,46 @@ bool goto_entry(char *file_or_dir) | |||
181 | rb->set_current_file(file_or_dir); | 179 | rb->set_current_file(file_or_dir); |
182 | return true; | 180 | return true; |
183 | } | 181 | } |
182 | #endif | ||
183 | |||
184 | int goto_entry(char *file_or_dir) | ||
185 | { | ||
186 | DEBUGF("Trying to go to '%s'...\n", file_or_dir); | ||
187 | |||
188 | bool is_dir = ends_with(file_or_dir, PATH_SEPARATOR); | ||
189 | bool exists; | ||
190 | char *what; | ||
191 | if (is_dir) { | ||
192 | what = "Directory"; | ||
193 | exists = rb->dir_exists(file_or_dir); | ||
194 | } else { | ||
195 | what = "File"; | ||
196 | exists = rb->file_exists(file_or_dir); | ||
197 | } | ||
184 | 198 | ||
199 | if (!exists) { | ||
200 | rb->splashf(HZ*2, "%s %s no longer exists on disk", what, file_or_dir); | ||
201 | return PLUGIN_ERROR; | ||
202 | } | ||
203 | |||
204 | int len = rb->strlen(file_or_dir); | ||
205 | if(!is_dir && len > 5 && rb->strcasecmp(&(file_or_dir[len-5]), ".rock") == 0) | ||
206 | { | ||
207 | return rb->plugin_open(file_or_dir, NULL); | ||
208 | } | ||
209 | else | ||
210 | { | ||
211 | /* Set the browsers dirfilter to the global setting | ||
212 | * This is required in case the plugin was launched | ||
213 | * from the plugins browser, in which case the | ||
214 | * dirfilter is set to only display .rock files */ | ||
215 | rb->set_dirfilter(rb->global_settings->dirfilter); | ||
216 | |||
217 | /* Change directory to the entry selected by the user */ | ||
218 | rb->set_current_file(file_or_dir); | ||
219 | } | ||
220 | return PLUGIN_OK; | ||
221 | } | ||
185 | 222 | ||
186 | bool ends_with(char *string, char *suffix) | 223 | bool ends_with(char *string, char *suffix) |
187 | { | 224 | { |
@@ -195,7 +232,7 @@ bool ends_with(char *string, char *suffix) | |||
195 | 232 | ||
196 | enum plugin_status plugin_start(const void* void_parameter) | 233 | enum plugin_status plugin_start(const void* void_parameter) |
197 | { | 234 | { |
198 | bool leave_loop; | 235 | int ret; |
199 | 236 | ||
200 | /* This is a viewer, so a parameter must have been specified */ | 237 | /* This is a viewer, so a parameter must have been specified */ |
201 | if (void_parameter == NULL) { | 238 | if (void_parameter == NULL) { |
@@ -219,8 +256,7 @@ enum plugin_status plugin_start(const void* void_parameter) | |||
219 | /* if there's only one entry in the user .link file, | 256 | /* if there's only one entry in the user .link file, |
220 | * go straight to it without displaying the menu | 257 | * go straight to it without displaying the menu |
221 | * thus allowing 'quick links' */ | 258 | * thus allowing 'quick links' */ |
222 | goto_entry(sc_file.entries[0].path); | 259 | return goto_entry(sc_file.entries[0].path); |
223 | return PLUGIN_OK; | ||
224 | } | 260 | } |
225 | 261 | ||
226 | FOR_NB_SCREENS(i) | 262 | FOR_NB_SCREENS(i) |
@@ -228,11 +264,13 @@ enum plugin_status plugin_start(const void* void_parameter) | |||
228 | 264 | ||
229 | do { | 265 | do { |
230 | /* Display a menu to choose between the entries */ | 266 | /* Display a menu to choose between the entries */ |
231 | leave_loop = list_sc(); | 267 | ret = list_sc(); |
232 | } while (!leave_loop); | 268 | } while (ret == PLUGIN_OK); |
269 | if (ret == LOOP_EXIT) | ||
270 | ret = PLUGIN_OK; | ||
233 | 271 | ||
234 | FOR_NB_SCREENS(i) | 272 | FOR_NB_SCREENS(i) |
235 | rb->viewportmanager_theme_undo(i, false); | 273 | rb->viewportmanager_theme_undo(i, false); |
236 | 274 | ||
237 | return usb_connected ? PLUGIN_USB_CONNECTED : PLUGIN_OK; | 275 | return ret; |
238 | } | 276 | } |
diff --git a/apps/root_menu.c b/apps/root_menu.c index c59c39fe88..2a8662a170 100644 --- a/apps/root_menu.c +++ b/apps/root_menu.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "kernel.h" | 32 | #include "kernel.h" |
33 | #include "debug.h" | 33 | #include "debug.h" |
34 | #include "misc.h" | 34 | #include "misc.h" |
35 | #include "open_plugin.h" | ||
35 | #include "rolo.h" | 36 | #include "rolo.h" |
36 | #include "powermgmt.h" | 37 | #include "powermgmt.h" |
37 | #include "power.h" | 38 | #include "power.h" |
@@ -347,6 +348,7 @@ static int miscscrn(void * param) | |||
347 | int result = do_menu(menu, NULL, NULL, false); | 348 | int result = do_menu(menu, NULL, NULL, false); |
348 | switch (result) | 349 | switch (result) |
349 | { | 350 | { |
351 | case GO_TO_PLUGIN: | ||
350 | case GO_TO_PLAYLIST_VIEWER: | 352 | case GO_TO_PLAYLIST_VIEWER: |
351 | case GO_TO_WPS: | 353 | case GO_TO_WPS: |
352 | return result; | 354 | return result; |
@@ -703,7 +705,6 @@ static int load_context_screen(int selection) | |||
703 | return retval; | 705 | return retval; |
704 | } | 706 | } |
705 | 707 | ||
706 | #ifdef HAVE_PICTUREFLOW_INTEGRATION | ||
707 | static int load_plugin_screen(char *plug_path, void* plug_param) | 708 | static int load_plugin_screen(char *plug_path, void* plug_param) |
708 | { | 709 | { |
709 | int ret_val; | 710 | int ret_val; |
@@ -717,6 +718,9 @@ static int load_plugin_screen(char *plug_path, void* plug_param) | |||
717 | case PLUGIN_GOTO_WPS: | 718 | case PLUGIN_GOTO_WPS: |
718 | ret_val = GO_TO_WPS; | 719 | ret_val = GO_TO_WPS; |
719 | break; | 720 | break; |
721 | case PLUGIN_GOTO_PLUGIN: | ||
722 | ret_val = GO_TO_PLUGIN; | ||
723 | break; | ||
720 | case PLUGIN_OK: | 724 | case PLUGIN_OK: |
721 | ret_val = audio_status() ? GO_TO_PREVIOUS : GO_TO_ROOT; | 725 | ret_val = audio_status() ? GO_TO_PREVIOUS : GO_TO_ROOT; |
722 | break; | 726 | break; |
@@ -729,7 +733,6 @@ static int load_plugin_screen(char *plug_path, void* plug_param) | |||
729 | last_screen = (old_previous == next_screen) ? GO_TO_ROOT : old_previous; | 733 | last_screen = (old_previous == next_screen) ? GO_TO_ROOT : old_previous; |
730 | return ret_val; | 734 | return ret_val; |
731 | } | 735 | } |
732 | #endif | ||
733 | 736 | ||
734 | void root_menu(void) | 737 | void root_menu(void) |
735 | { | 738 | { |
@@ -807,21 +810,36 @@ void root_menu(void) | |||
807 | case GO_TO_ROOTITEM_CONTEXT: | 810 | case GO_TO_ROOTITEM_CONTEXT: |
808 | next_screen = load_context_screen(selected); | 811 | next_screen = load_context_screen(selected); |
809 | break; | 812 | break; |
810 | #ifdef HAVE_PICTUREFLOW_INTEGRATION | 813 | case GO_TO_PLUGIN: |
811 | case GO_TO_PICTUREFLOW: | ||
812 | { | 814 | { |
813 | char pf_path[MAX_PATH]; | 815 | char *key; |
814 | char activity[6];/* big enough to display int */ | 816 | switch (last_screen) |
815 | snprintf(activity, sizeof(activity), "%d", get_current_activity()); | 817 | { |
816 | snprintf(pf_path, sizeof(pf_path), | 818 | case GO_TO_ROOT: |
817 | "%s/pictureflow.rock", | 819 | key = ID2P(LANG_START_SCREEN); |
818 | PLUGIN_DEMOS_DIR); | 820 | break; |
819 | 821 | case GO_TO_WPS: | |
820 | next_screen = load_plugin_screen(pf_path, &activity); | 822 | key = ID2P(LANG_OPEN_PLUGIN_SET_WPS_CONTEXT_PLUGIN); |
821 | previous_browser = (next_screen != GO_TO_WPS) ? GO_TO_FILEBROWSER : GO_TO_PICTUREFLOW; | 823 | break; |
824 | case GO_TO_SHORTCUTMENU: | ||
825 | key = ID2P(LANG_SHORTCUTS); | ||
826 | break; | ||
827 | default: | ||
828 | key = ID2P(LANG_OPEN_PLUGIN); | ||
829 | break; | ||
830 | } | ||
831 | |||
832 | open_plugin_get_entry(key, &open_plugin_entry); | ||
833 | char *path = open_plugin_entry.path; | ||
834 | char *param = open_plugin_entry.param; | ||
835 | if (param[0] == '\0') | ||
836 | param = NULL; | ||
837 | |||
838 | next_screen = load_plugin_screen(path, param); | ||
839 | |||
840 | previous_browser = (next_screen != GO_TO_WPS) ? GO_TO_FILEBROWSER : GO_TO_PLUGIN; | ||
822 | break; | 841 | break; |
823 | } | 842 | } |
824 | #endif | ||
825 | default: | 843 | default: |
826 | #ifdef HAVE_TAGCACHE | 844 | #ifdef HAVE_TAGCACHE |
827 | /* With !HAVE_TAGCACHE previous_browser is always GO_TO_FILEBROWSER */ | 845 | /* With !HAVE_TAGCACHE previous_browser is always GO_TO_FILEBROWSER */ |
diff --git a/apps/root_menu.h b/apps/root_menu.h index 262b1d9a0c..55ea6c72d6 100644 --- a/apps/root_menu.h +++ b/apps/root_menu.h | |||
@@ -55,7 +55,7 @@ enum { | |||
55 | GO_TO_FM, | 55 | GO_TO_FM, |
56 | #endif | 56 | #endif |
57 | GO_TO_RECENTBMARKS, | 57 | GO_TO_RECENTBMARKS, |
58 | GO_TO_PICTUREFLOW, | 58 | GO_TO_PLUGIN, |
59 | /* Do Not add any items above here unless you want it to be able to | 59 | /* Do Not add any items above here unless you want it to be able to |
60 | be the "start screen" after a boot up. The setting in settings_list.c | 60 | be the "start screen" after a boot up. The setting in settings_list.c |
61 | will need editing if this is the case. */ | 61 | will need editing if this is the case. */ |
diff --git a/apps/settings_list.c b/apps/settings_list.c index 1c33f3dc86..a38ebc639c 100644 --- a/apps/settings_list.c +++ b/apps/settings_list.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include "power.h" | 38 | #include "power.h" |
39 | #include "powermgmt.h" | 39 | #include "powermgmt.h" |
40 | #include "kernel.h" | 40 | #include "kernel.h" |
41 | #include "open_plugin.h" | ||
41 | #ifdef HAVE_REMOTE_LCD | 42 | #ifdef HAVE_REMOTE_LCD |
42 | #include "lcd-remote.h" | 43 | #include "lcd-remote.h" |
43 | #endif | 44 | #endif |
@@ -680,6 +681,11 @@ static void tsc_set_default(void* setting, void* defaultval) | |||
680 | } | 681 | } |
681 | #endif | 682 | #endif |
682 | #ifdef HAVE_HOTKEY | 683 | #ifdef HAVE_HOTKEY |
684 | static void hotkey_callback(int var) | ||
685 | { | ||
686 | if (get_hotkey_lang_id(var) == LANG_OPEN_PLUGIN) | ||
687 | open_plugin_browse(ID2P(LANG_HOTKEY_WPS)); | ||
688 | } | ||
683 | static const char* hotkey_formatter(char* buffer, size_t buffer_size, int value, | 689 | static const char* hotkey_formatter(char* buffer, size_t buffer_size, int value, |
684 | const char* unit) | 690 | const char* unit) |
685 | { | 691 | { |
@@ -695,6 +701,12 @@ static int32_t hotkey_getlang(int value, int unit) | |||
695 | } | 701 | } |
696 | #endif /* HAVE_HOTKEY */ | 702 | #endif /* HAVE_HOTKEY */ |
697 | 703 | ||
704 | static void start_in_callback(int var) | ||
705 | { | ||
706 | if (var - 2 == GO_TO_PLUGIN) | ||
707 | open_plugin_browse(ID2P(LANG_START_SCREEN)); | ||
708 | } | ||
709 | |||
698 | /* volume limiter */ | 710 | /* volume limiter */ |
699 | static void volume_limit_load_from_cfg(void* var, char*value) | 711 | static void volume_limit_load_from_cfg(void* var, char*value) |
700 | { | 712 | { |
@@ -1872,7 +1884,7 @@ const struct settings_list settings[] = { | |||
1872 | UNIT_SEC, formatter_time_unit_0_is_skip_track, | 1884 | UNIT_SEC, formatter_time_unit_0_is_skip_track, |
1873 | getlang_time_unit_0_is_skip_track, NULL, | 1885 | getlang_time_unit_0_is_skip_track, NULL, |
1874 | 25, timeout_sec_common), | 1886 | 25, timeout_sec_common), |
1875 | CHOICE_SETTING(0, start_in_screen, LANG_START_SCREEN, 1, | 1887 | CHOICE_SETTING(F_CB_ON_SELECT_ONLY, start_in_screen, LANG_START_SCREEN, 1, |
1876 | "start in screen", "previous,root,files," | 1888 | "start in screen", "previous,root,files," |
1877 | #ifdef HAVE_TAGCACHE | 1889 | #ifdef HAVE_TAGCACHE |
1878 | #define START_DB_COUNT 1 | 1890 | #define START_DB_COUNT 1 |
@@ -1893,15 +1905,10 @@ const struct settings_list settings[] = { | |||
1893 | #else | 1905 | #else |
1894 | #define START_TUNER_COUNT 0 | 1906 | #define START_TUNER_COUNT 0 |
1895 | #endif | 1907 | #endif |
1896 | "bookmarks" | 1908 | "bookmarks," |
1897 | #ifdef HAVE_PICTUREFLOW_INTEGRATION | 1909 | "plugin" |
1898 | #define START_PF_COUNT 1 | 1910 | , start_in_callback, |
1899 | ",pictureflow" | 1911 | (7 + START_DB_COUNT + START_REC_COUNT + START_TUNER_COUNT), |
1900 | #else | ||
1901 | #define START_PF_COUNT 0 | ||
1902 | #endif | ||
1903 | , NULL, | ||
1904 | (6 + START_DB_COUNT + START_REC_COUNT + START_TUNER_COUNT + START_PF_COUNT), | ||
1905 | ID2P(LANG_PREVIOUS_SCREEN), ID2P(LANG_MAIN_MENU), | 1912 | ID2P(LANG_PREVIOUS_SCREEN), ID2P(LANG_MAIN_MENU), |
1906 | ID2P(LANG_DIR_BROWSER), | 1913 | ID2P(LANG_DIR_BROWSER), |
1907 | #ifdef HAVE_TAGCACHE | 1914 | #ifdef HAVE_TAGCACHE |
@@ -1914,10 +1921,8 @@ const struct settings_list settings[] = { | |||
1914 | #if CONFIG_TUNER | 1921 | #if CONFIG_TUNER |
1915 | ID2P(LANG_FM_RADIO), | 1922 | ID2P(LANG_FM_RADIO), |
1916 | #endif | 1923 | #endif |
1917 | ID2P(LANG_BOOKMARK_MENU_RECENT_BOOKMARKS) | 1924 | ID2P(LANG_BOOKMARK_MENU_RECENT_BOOKMARKS), |
1918 | #ifdef HAVE_PICTUREFLOW_INTEGRATION | 1925 | ID2P(LANG_OPEN_PLUGIN) |
1919 | ,ID2P(LANG_ONPLAY_PICTUREFLOW) | ||
1920 | #endif | ||
1921 | ), | 1926 | ), |
1922 | SYSTEM_SETTING(NVRAM(1),last_screen,-1), | 1927 | SYSTEM_SETTING(NVRAM(1),last_screen,-1), |
1923 | #if defined(HAVE_RTC_ALARM) && \ | 1928 | #if defined(HAVE_RTC_ALARM) && \ |
@@ -2098,25 +2103,12 @@ const struct settings_list settings[] = { | |||
2098 | #endif | 2103 | #endif |
2099 | 2104 | ||
2100 | #ifdef HAVE_HOTKEY | 2105 | #ifdef HAVE_HOTKEY |
2101 | TABLE_SETTING(F_ALLOW_ARBITRARY_VALS, hotkey_wps, | 2106 | TABLE_SETTING(F_ALLOW_ARBITRARY_VALS | F_CB_ON_SELECT_ONLY, hotkey_wps, |
2102 | LANG_HOTKEY_WPS, HOTKEY_VIEW_PLAYLIST, "hotkey wps", | 2107 | LANG_HOTKEY_WPS, HOTKEY_VIEW_PLAYLIST, "hotkey wps", |
2103 | "off,view playlist,show track info,pitchscreen,open with,delete,bookmark" | 2108 | "off,view playlist,show track info,pitchscreen,open with,delete,bookmark,plugin" |
2104 | #ifdef HAVE_PICTUREFLOW_INTEGRATION | 2109 | ,UNIT_INT, hotkey_formatter, hotkey_getlang, hotkey_callback,8, HOTKEY_OFF, |
2105 | ",pictureflow" | ||
2106 | #endif | ||
2107 | ,UNIT_INT, hotkey_formatter, hotkey_getlang, NULL, | ||
2108 | #ifdef HAVE_PICTUREFLOW_INTEGRATION | ||
2109 | 8, | ||
2110 | #else | ||
2111 | 7, | ||
2112 | #endif | ||
2113 | HOTKEY_OFF, | ||
2114 | HOTKEY_VIEW_PLAYLIST, HOTKEY_SHOW_TRACK_INFO, HOTKEY_PITCHSCREEN, | 2110 | HOTKEY_VIEW_PLAYLIST, HOTKEY_SHOW_TRACK_INFO, HOTKEY_PITCHSCREEN, |
2115 | HOTKEY_OPEN_WITH, HOTKEY_DELETE, HOTKEY_BOOKMARK | 2111 | HOTKEY_OPEN_WITH, HOTKEY_DELETE, HOTKEY_BOOKMARK, HOTKEY_PLUGIN), |
2116 | #ifdef HAVE_PICTUREFLOW_INTEGRATION | ||
2117 | , HOTKEY_PICTUREFLOW | ||
2118 | #endif | ||
2119 | ), | ||
2120 | TABLE_SETTING(F_ALLOW_ARBITRARY_VALS, hotkey_tree, | 2112 | TABLE_SETTING(F_ALLOW_ARBITRARY_VALS, hotkey_tree, |
2121 | LANG_HOTKEY_FILE_BROWSER, HOTKEY_OFF, "hotkey tree", | 2113 | LANG_HOTKEY_FILE_BROWSER, HOTKEY_OFF, "hotkey tree", |
2122 | "off,open with,delete,insert,insert shuffled", | 2114 | "off,open with,delete,insert,insert shuffled", |
diff --git a/apps/settings_list.h b/apps/settings_list.h index 7f0ae6484f..36c4d8062f 100644 --- a/apps/settings_list.h +++ b/apps/settings_list.h | |||
@@ -100,6 +100,7 @@ struct table_setting { | |||
100 | }; | 100 | }; |
101 | #define F_TABLE_SETTING 0x2000 | 101 | #define F_TABLE_SETTING 0x2000 |
102 | #define F_ALLOW_ARBITRARY_VALS 0x4000 | 102 | #define F_ALLOW_ARBITRARY_VALS 0x4000 |
103 | #define F_CB_ON_SELECT_ONLY 0x20000 | ||
103 | /* these use the _isfunc_type type for the function */ | 104 | /* these use the _isfunc_type type for the function */ |
104 | /* typedef int (*_isfunc_type)(void); */ | 105 | /* typedef int (*_isfunc_type)(void); */ |
105 | #define F_MIN_ISFUNC 0x100000 /* min(above) is function pointer to above type */ | 106 | #define F_MIN_ISFUNC 0x100000 /* min(above) is function pointer to above type */ |
diff --git a/apps/shortcuts.c b/apps/shortcuts.c index c7e5755c1a..aa9a32bbb2 100644 --- a/apps/shortcuts.c +++ b/apps/shortcuts.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "lang.h" | 36 | #include "lang.h" |
37 | #include "menu.h" | 37 | #include "menu.h" |
38 | #include "misc.h" | 38 | #include "misc.h" |
39 | #include "open_plugin.h" | ||
39 | #include "tree.h" | 40 | #include "tree.h" |
40 | #include "splash.h" | 41 | #include "splash.h" |
41 | #include "pathfuncs.h" | 42 | #include "pathfuncs.h" |
@@ -608,6 +609,12 @@ int do_shortcut_menu(void *ignored) | |||
608 | /* else fall through */ | 609 | /* else fall through */ |
609 | case SHORTCUT_BROWSER: | 610 | case SHORTCUT_BROWSER: |
610 | { | 611 | { |
612 | |||
613 | if(open_plugin_add_path(ID2P(LANG_SHORTCUTS), sc->u.path, NULL) != 0) | ||
614 | { | ||
615 | done = GO_TO_PLUGIN; | ||
616 | break; | ||
617 | } | ||
611 | struct browse_context browse; | 618 | struct browse_context browse; |
612 | browse_context_init(&browse, global_settings.dirfilter, 0, | 619 | browse_context_init(&browse, global_settings.dirfilter, 0, |
613 | NULL, NOICON, sc->u.path, NULL); | 620 | NULL, NOICON, sc->u.path, NULL); |
diff --git a/apps/tree.c b/apps/tree.c index 316139427d..48723c4f2e 100644 --- a/apps/tree.c +++ b/apps/tree.c | |||
@@ -676,6 +676,8 @@ static int dirbrowse(void) | |||
676 | #endif | 676 | #endif |
677 | { | 677 | { |
678 | case GO_TO_FILEBROWSER: reload_dir = true; break; | 678 | case GO_TO_FILEBROWSER: reload_dir = true; break; |
679 | case GO_TO_PLUGIN: | ||
680 | return GO_TO_PLUGIN; | ||
679 | case GO_TO_WPS: | 681 | case GO_TO_WPS: |
680 | return GO_TO_WPS; | 682 | return GO_TO_WPS; |
681 | #if CONFIG_TUNER | 683 | #if CONFIG_TUNER |
diff --git a/manual/advanced_topics/main.tex b/manual/advanced_topics/main.tex index 00b1688e11..997850a6fd 100755 --- a/manual/advanced_topics/main.tex +++ b/manual/advanced_topics/main.tex | |||
@@ -36,6 +36,12 @@ This configuration entry can only be created and edited with a text editor or | |||
36 | the Main Menu Config Plugin (see \reference{ref:main_menu_config}). | 36 | the Main Menu Config Plugin (see \reference{ref:main_menu_config}). |
37 | It is not possible to change this setting via the settings menu. | 37 | It is not possible to change this setting via the settings menu. |
38 | 38 | ||
39 | \subsection{\label{ref:OpenPlugins}Open Plugin Menu Items} | ||
40 | |||
41 | Rockbox allows you to choose a plugin to run for select menu options. | ||
42 | Simply choose the option in the setting menu and choose the plugin | ||
43 | you would like to run. | ||
44 | |||
39 | \opt{lcd_bitmap}{ | 45 | \opt{lcd_bitmap}{ |
40 | \subsection{\label{ref:GettingExtras}Getting Extras} | 46 | \subsection{\label{ref:GettingExtras}Getting Extras} |
41 | 47 | ||
diff --git a/manual/configure_rockbox/main.tex b/manual/configure_rockbox/main.tex index 0eeea4e256..83089b6d4e 100644 --- a/manual/configure_rockbox/main.tex +++ b/manual/configure_rockbox/main.tex | |||
@@ -21,6 +21,7 @@ | |||
21 | }} | 21 | }} |
22 | \input{configure_rockbox/language.tex} | 22 | \input{configure_rockbox/language.tex} |
23 | \input{configure_rockbox/voice.tex} | 23 | \input{configure_rockbox/voice.tex} |
24 | \input{configure_rockbox/wps_context_plugin.tex} | ||
24 | \input{configure_rockbox/hotkey_settings.tex} | 25 | \input{configure_rockbox/hotkey_settings.tex} |
25 | 26 | ||
26 | \chapter{Theme Settings} | 27 | \chapter{Theme Settings} |
diff --git a/manual/configure_rockbox/wps_context_plugin.tex b/manual/configure_rockbox/wps_context_plugin.tex new file mode 100644 index 0000000000..8d193d47d6 --- /dev/null +++ b/manual/configure_rockbox/wps_context_plugin.tex | |||
@@ -0,0 +1,5 @@ | |||
1 | \section{\label{ref:SetWPSContextPlugin}Set WPS Context Plugin} | ||
2 | |||
3 | \begin{description} | ||
4 | {This option will allow you to run a rockbox plugin from the WPS context menu} | ||
5 | \end{description} | ||