beginning of the new menu system. This commit shouldnt break anything, 
but comming ones might.. report bugs in 
http://forums.rockbox.org/index.php?topic=8703.0 and more info at 
http://www.rockbox.org/twiki/bin/view/Main/SettingsRecode


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12227 a1c6a512-1295-4272-9138-f99709370657
diff --git a/apps/menu.h b/apps/menu.h
index f9a3d1f..b0a1b4c 100644
--- a/apps/menu.h
+++ b/apps/menu.h
@@ -22,101 +22,14 @@
 
 #include <stdbool.h>
 
-/* button definitions */
-#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
-    (CONFIG_KEYPAD == IRIVER_H300_PAD)
-#define MENU_EXIT       BUTTON_LEFT
-#define MENU_EXIT2      BUTTON_OFF
-#define MENU_EXIT_MENU  BUTTON_MODE
-#define MENU_ENTER      BUTTON_RIGHT
-#define MENU_ENTER2     BUTTON_SELECT
-
-#define MENU_RC_EXIT        BUTTON_RC_STOP
-#define MENU_RC_EXIT_MENU   BUTTON_RC_MODE
-#define MENU_RC_ENTER       BUTTON_RC_ON
-#define MENU_RC_ENTER2      BUTTON_RC_MENU
-
-
-#elif CONFIG_KEYPAD == RECORDER_PAD
-
-#define MENU_EXIT       BUTTON_LEFT
-#define MENU_EXIT2      BUTTON_OFF
-#define MENU_EXIT_MENU  BUTTON_F1
-#define MENU_ENTER      BUTTON_RIGHT
-#define MENU_ENTER2     BUTTON_PLAY
-
-#define MENU_RC_EXIT    BUTTON_RC_STOP
-#define MENU_RC_ENTER   BUTTON_RC_PLAY
-
-#elif CONFIG_KEYPAD == PLAYER_PAD
-#define MENU_EXIT       BUTTON_STOP
-#define MENU_EXIT_MENU  BUTTON_MENU
-#define MENU_ENTER      BUTTON_PLAY
-
-#define MENU_RC_EXIT    BUTTON_RC_STOP
-#define MENU_RC_ENTER   BUTTON_RC_PLAY
-
-#elif CONFIG_KEYPAD == ONDIO_PAD
-#define MENU_EXIT       BUTTON_LEFT
-#define MENU_EXIT_MENU  BUTTON_MENU
-#define MENU_ENTER      BUTTON_RIGHT
-
-#elif (CONFIG_KEYPAD == IPOD_3G_PAD) || (CONFIG_KEYPAD == IPOD_4G_PAD)
-
-/* TODO: Check menu button assignments */
-
-#define MENU_NEXT       BUTTON_DOWN
-#define MENU_PREV       BUTTON_UP
-#define MENU_EXIT       BUTTON_LEFT
-#define MENU_EXIT_MENU  BUTTON_MENU
-#define MENU_ENTER      BUTTON_RIGHT
-#define MENU_ENTER2     BUTTON_SELECT
-
-#elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
-
-#define MENU_NEXT       BUTTON_DOWN
-#define MENU_PREV       BUTTON_UP
-#define MENU_EXIT       BUTTON_LEFT
-#define MENU_EXIT_MENU  BUTTON_PLAY
-#define MENU_ENTER      BUTTON_RIGHT
-
-#elif CONFIG_KEYPAD == IAUDIO_X5_PAD
-
-#define MENU_NEXT       BUTTON_DOWN
-#define MENU_PREV       BUTTON_UP
-#define MENU_EXIT       BUTTON_LEFT
-#define MENU_EXIT_MENU  BUTTON_REC
-#define MENU_ENTER      BUTTON_RIGHT
-#define MENU_ENTER2     BUTTON_SELECT
-
-#elif CONFIG_KEYPAD == GIGABEAT_PAD
-
-#define MENU_EXIT       BUTTON_LEFT
-#define MENU_EXIT2      BUTTON_A
-#define MENU_EXIT_MENU  BUTTON_MENU
-#define MENU_ENTER      BUTTON_RIGHT
-#define MENU_ENTER2     BUTTON_SELECT
-#define MENU_NEXT       BUTTON_DOWN
-#define MENU_PREV       BUTTON_UP
-
-#elif CONFIG_KEYPAD == IRIVER_H10_PAD
-
-#define MENU_NEXT       BUTTON_SCROLL_DOWN
-#define MENU_PREV       BUTTON_SCROLL_UP
-#define MENU_EXIT       BUTTON_LEFT
-#define MENU_EXIT_MENU  BUTTON_REW
-#define MENU_ENTER      BUTTON_RIGHT
-#define MENU_ENTER2     BUTTON_FF
-
-#endif
-
 struct menu_item {
     unsigned char *desc; /* string or ID */
     bool (*function) (void); /* return true if USB was connected */
 };
 
-int menu_init(const struct menu_item* mitems, int count, int (*callback)(int, int),
-              const char *button1, const char *button2, const char *button3);
+int menu_init(const struct menu_item* mitems, int count,
+                int (*callback)(int, int),
+                const char *button1, const char *button2, const char *button3);
 void menu_exit(int menu);
 
 void put_cursorxy(int x, int y, bool on);
@@ -125,6 +38,8 @@
 int menu_show(int m);
 #define MENU_ATTACHED_USB -1
 #define MENU_SELECTED_EXIT -2
+#define MENU_EXIT_ALL -3
+#define MENU_RETURN_TO_WPS -4
 
 bool menu_run(int menu);
 int menu_cursor(int menu);
@@ -138,4 +53,87 @@
 void menu_set_cursor(int menu, int position);
 void menu_talk_selected(int m);
 
+
+enum menu_item_type {
+    MT_MENU = 0,
+    MT_SETTING,
+    MT_FUNCTION_CALL, /* used when the standard code wont work */
+    MT_FUNCTION_WITH_PARAM,
+    MT_RETURN_ID, /* returns the position of the selected item (starting at 0)*/
+};
+
+typedef int (*menu_function)(void);
+struct menu_func_with_param {
+    int (*function)(void* param);
+    void *param;
+};
+
+#define MENU_TYPE_MASK 0xF /* MT_* type */
+#define MENU_HAS_DESC   0x10
+#define MENU_COUNT_MASK (~(MENU_TYPE_MASK|MENU_HAS_DESC)) /* unless we need more flags*/
+#define MENU_COUNT_SHIFT 5
+
+struct menu_item_ex {
+    int flags; /* above defines */
+    union {
+        const struct menu_item_ex **submenus; /* used with MT_MENU */
+        void *variable; /* used with MT_SETTING,
+                           must be in the settings_list.c list */
+        int (*function)(void); /* used with MT_FUNCTION_CALL */
+        const struct menu_func_with_param 
+                                *func_with_param; /* MT_FUNCTION_WITH_PARAM */
+        const char **strings; /* used with MT_RETURN_ID */
+    };
+    union {
+        int (*menu_callback)(int action, const struct menu_item_ex *this_item);
+        const struct menu_callback_with_desc {
+            int (*menu_callback)(int action, 
+                                 const struct menu_item_ex *this_item);
+            unsigned char *desc; /* string or ID */
+        } *callback_and_desc;
+    };
+};
+
+typedef int (*menu_callback_type)(int action,
+                                  const struct menu_item_ex *this_item);
+int do_menu(const struct menu_item_ex *menu);
+
+#define MENU_ITEM_COUNT(c) (c<<MENU_COUNT_SHIFT)
+
+#define MENUITEM_SETTING(name,var,callback)                  \
+    static const struct menu_item_ex name =                  \
+        {MT_SETTING, {.variable = (void*)var},{callback}};
+
+#define MAKE_MENU( name, str, cb, ... )                                 \
+    static const struct menu_item_ex *name##_[]  = {__VA_ARGS__};       \
+    static const struct menu_callback_with_desc name##__ = {cb,str};    \
+    const struct menu_item_ex name =                                    \
+        {MT_MENU|MENU_HAS_DESC|                                         \
+         MENU_ITEM_COUNT(sizeof( name##_)/sizeof(*name##_)),            \
+            { (void*)name##_},{.callback_and_desc = & name##__}};
+
+#define MENUITEM_STRINGLIST(name, str, callback, ... )                  \
+    static const char *name##_[] = {__VA_ARGS__};                       \
+    static const struct menu_callback_with_desc name##__ = {cb,str};    \
+    static const struct menu_item_ex name =                             \
+        {MT_RETURN_ID|MENU_HAS_DESC|                                    \
+         MENU_ITEM_COUNT(sizeof( name##_)/sizeof(*name##_)),            \
+            { .submenus = name##_},{.callback_and_desc = & name##__}};
+/* This one should be static'ed also, 
+   but cannot be done untill sound and playlist menus are done */
+#define MENUITEM_FUNCTION(name, str, func, cb)                          \
+    static const struct menu_callback_with_desc name##_ = {cb,str};     \
+    const struct menu_item_ex name   =                                  \
+        { MT_FUNCTION_CALL|MENU_HAS_DESC, { .function = func},          \
+        {.callback_and_desc = & name##_}};
+
+#define MENUITEM_FUNCTION_WPARAM(name, str, func, param, callback)          \
+    static const struct menu_callback_with_desc name##_ = {callback,str};   \
+    static const struct menu_func_with_param name##__ = {func, param};      \
+    static const struct menu_item_ex name   =                               \
+        { MT_FUNCTION_WITH_PARAM|MENU_HAS_DESC,                             \
+            { .func_with_param = &name##__},                                \
+            {.callback_and_desc = & name##_}};
+
+
 #endif /* End __MENU_H__ */