summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/debug_menu.c390
-rw-r--r--apps/gui/list.c103
-rw-r--r--apps/gui/list.h42
3 files changed, 309 insertions, 226 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index 0dec961f3f..397a853857 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -87,95 +87,6 @@
87#endif 87#endif
88#include "hwcompat.h" 88#include "hwcompat.h"
89 89
90#if defined(HAVE_DIRCACHE) || defined(HAVE_TAGCACHE) || CONFIG_TUNER
91#define MAX_DEBUG_MESSAGES 16
92#define DEBUG_MSG_LEN 32
93int debug_listmessage_lines;
94char debug_list_messages[MAX_DEBUG_MESSAGES][DEBUG_MSG_LEN];
95static void dbg_listmessage_setlines(int lines)
96{
97 if (lines < 0)
98 lines = 0;
99 else if (lines > MAX_DEBUG_MESSAGES)
100 lines = MAX_DEBUG_MESSAGES;
101 debug_listmessage_lines = lines;
102}
103#ifndef SIMULATOR
104static int dbg_listmessage_getlines(void)
105{
106 return debug_listmessage_lines;
107}
108#endif
109static void dbg_listmessage_addline(const char *fmt, ...)
110{
111 va_list ap;
112
113 if (debug_listmessage_lines >= MAX_DEBUG_MESSAGES)
114 return;
115
116 va_start(ap, fmt);
117 vsnprintf(debug_list_messages[debug_listmessage_lines++], DEBUG_MSG_LEN, fmt, ap);
118 va_end(ap);
119}
120static char* dbg_listmessage_getname(int item, void * data, char *buffer)
121{
122 (void)buffer; (void)data;
123 return debug_list_messages[item];
124}
125#endif
126
127struct action_callback_info;
128#define DBGLIST_SHOW_SELECTION 0x1
129
130struct action_callback_info
131{
132 char *title;
133 int count;
134 int selection_size;
135 int (*action_callback)(int btn, struct action_callback_info *info);
136 char* (*dbg_getname)(int item, void * data, char *buffer);
137 intptr_t cbdata; /* extra callback data (pointer, int, whatever) */
138 struct gui_synclist *lists; /* passed back to the callback */
139};
140
141static char* dbg_menu_getname(int item, void * data, char *buffer);
142static char* threads_getname(int selected_item, void * data, char *buffer);
143static bool dbg_list(struct action_callback_info *info)
144{
145 struct gui_synclist lists;
146 int action;
147
148 info->lists = &lists;
149
150 gui_synclist_init(&lists, info->dbg_getname, NULL, false,
151 info->selection_size);
152 gui_synclist_set_title(&lists, info->title, NOICON);
153 gui_synclist_set_icon_callback(&lists, NULL);
154 gui_synclist_set_nb_items(&lists, info->count*info->selection_size);
155 gui_synclist_hide_selection_marker(&lists, true);
156
157 if (info->action_callback)
158 info->action_callback(ACTION_REDRAW, info);
159
160 gui_synclist_draw(&lists);
161
162 while(1)
163 {
164 gui_syncstatusbar_draw(&statusbars, true);
165 action = get_action(CONTEXT_STD, HZ/5);
166 if (gui_synclist_do_button(&lists, &action, LIST_WRAP_UNLESS_HELD))
167 continue;
168 if (info->action_callback)
169 action = info->action_callback(action, info);
170 if (action == ACTION_STD_CANCEL)
171 break;
172 else if (action == ACTION_REDRAW)
173 gui_synclist_draw(&lists);
174 else if(default_event_handler(action) == SYS_USB_CONNECTED)
175 return true;
176 }
177 return false;
178}
179/*---------------------------------------------------*/ 90/*---------------------------------------------------*/
180/* SPECIAL DEBUG STUFF */ 91/* SPECIAL DEBUG STUFF */
181/*---------------------------------------------------*/ 92/*---------------------------------------------------*/
@@ -247,28 +158,28 @@ static char* threads_getname(int selected_item, void * data, char *buffer)
247 158
248 return buffer; 159 return buffer;
249} 160}
250static int dbg_threads_action_callback(int action, struct action_callback_info *info) 161static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
251{ 162{
163 (void)lists;
252#ifdef ROCKBOX_HAS_LOGF 164#ifdef ROCKBOX_HAS_LOGF
253 if (action == ACTION_STD_OK) 165 if (action == ACTION_STD_OK)
254 { 166 {
255 int selpos = gui_synclist_get_sel_pos(info->lists); 167 int selpos = gui_synclist_get_sel_pos(lists);
256#if NUM_CORES > 1 168#if NUM_CORES > 1
257 if (selpos >= NUM_CORES) 169 if (selpos >= NUM_CORES)
258 remove_thread(&threads[selpos - NUM_CORES]); 170 remove_thread(&threads[selpos - NUM_CORES]);
259#else 171#else
260 remove_thread(&threads[selpos]); 172 remove_thread(&threads[selpos]);
261#endif 173#endif
174 return ACTION_REDRAW;
262 } 175 }
263 gui_synclist_hide_selection_marker(info->lists, false);
264#endif /* ROCKBOX_HAS_LOGF */ 176#endif /* ROCKBOX_HAS_LOGF */
265 gui_synclist_draw(info->lists);
266 return action; 177 return action;
267} 178}
268/* Test code!!! */ 179/* Test code!!! */
269static bool dbg_os(void) 180static bool dbg_os(void)
270{ 181{
271 struct action_callback_info info; 182 struct simplelist_info info;
272 info.title = IF_COP("Core and ") "Stack usage:"; 183 info.title = IF_COP("Core and ") "Stack usage:";
273#if NUM_CORES == 1 184#if NUM_CORES == 1
274 info.count = MAXTHREADS; 185 info.count = MAXTHREADS;
@@ -276,9 +187,17 @@ static bool dbg_os(void)
276 info.count = MAXTHREADS+NUM_CORES; 187 info.count = MAXTHREADS+NUM_CORES;
277#endif 188#endif
278 info.selection_size = 1; 189 info.selection_size = 1;
190#ifdef ROCKBOX_HAS_LOGF
191 info.hide_selection = false;
192#else
193 info.hide_selection = true;
194#endif
195 info.scroll_all = false;
279 info.action_callback = dbg_threads_action_callback; 196 info.action_callback = dbg_threads_action_callback;
280 info.dbg_getname = threads_getname; 197 info.get_icon = NULL;
281 return dbg_list(&info); 198 info.get_name = threads_getname;
199 info.callback_data = NULL;
200 return simplelist_show_list(&info);
282} 201}
283 202
284#ifdef HAVE_LCD_BITMAP 203#ifdef HAVE_LCD_BITMAP
@@ -816,14 +735,17 @@ static char* dbg_partitions_getname(int selected_item, void * data, char *buffer
816 735
817bool dbg_partitions(void) 736bool dbg_partitions(void)
818{ 737{
819 struct action_callback_info info; 738 struct simplelist_info info;
820 info.title = "Partition Info"; 739 info.title = "Partition Info";
821 info.count = 4; 740 info.count = 4;
822 info.selection_size = 2; 741 info.selection_size = 2;
742 info.hide_selection = true;
743 info.scroll_all = false;
823 info.action_callback = NULL; 744 info.action_callback = NULL;
824 info.dbg_getname = dbg_partitions_getname; 745 info.get_icon = NULL;
825 dbg_list(&info); 746 info.get_name = dbg_partitions_getname;
826 return false; 747 info.callback_data = NULL;
748 return simplelist_show_list(&info);
827} 749}
828#endif 750#endif
829 751
@@ -1693,116 +1615,109 @@ static bool view_battery(void)
1693#else 1615#else
1694#define CARDTYPE "microSD" 1616#define CARDTYPE "microSD"
1695#endif 1617#endif
1696static int cardinfo_callback(int btn, struct action_callback_info *info) 1618static int disk_callback(int btn, struct gui_synclist *lists)
1697{ 1619{
1698 tCardInfo *card; 1620 tCardInfo *card;
1621 int *cardnum = (int*)lists->gui_list[SCREEN_MAIN].data;
1699 unsigned char card_name[7]; 1622 unsigned char card_name[7];
1700 unsigned char pbuf[32]; 1623 unsigned char pbuf[32];
1624 char *title = lists->gui_list[SCREEN_MAIN].title;
1701 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 }; 1625 static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
1702 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 }; 1626 static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
1703 static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" }; 1627 static const unsigned char *kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
1704 static const unsigned char *nsec_units[] = { "ns", "µs", "ms" }; 1628 static const unsigned char *nsec_units[] = { "ns", "�s", "ms" };
1705 static const char *spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2", 1629 static const char *spec_vers[] = { "1.0-1.2", "1.4", "2.0-2.2",
1706 "3.1-3.31", "4.0" }; 1630 "3.1-3.31", "4.0" };
1707 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW)) 1631 if ((btn == ACTION_STD_OK) || (btn == SYS_FS_CHANGED) || (btn == ACTION_REDRAW))
1708 { 1632 {
1709 if (btn == ACTION_STD_OK) 1633 if (btn == ACTION_STD_OK)
1710 info->cbdata ^= 0x1; /* change cards */ 1634 {
1635 *cardnum ^= 0x1; /* change cards */
1636 }
1711 1637
1712 dbg_listmessage_setlines(0); 1638 simplelist_set_line_count(0);
1713 1639
1714 card = card_get_info(info->cbdata); 1640 card = card_get_info(*cardnum);
1715 1641
1716 if (card->initialized > 0) 1642 if (card->initialized > 0)
1717 { 1643 {
1718 card_name[6] = '\0'; 1644 card_name[6] = '\0';
1719 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6); 1645 strncpy(card_name, ((unsigned char*)card->cid) + 3, 6);
1720 dbg_listmessage_addline( 1646 simplelist_addline(SIMPLELIST_ADD_LINE,
1721 "%s Rev %d.%d", card_name, 1647 "%s Rev %d.%d", card_name,
1722 (int) card_extract_bits(card->cid, 72, 4), 1648 (int) card_extract_bits(card->cid, 72, 4),
1723 (int) card_extract_bits(card->cid, 76, 4)); 1649 (int) card_extract_bits(card->cid, 76, 4));
1724 dbg_listmessage_addline( 1650 simplelist_addline(SIMPLELIST_ADD_LINE,
1725 "Prod: %d/%d", 1651 "Prod: %d/%d",
1726 (int) card_extract_bits(card->cid, 112, 4), 1652 (int) card_extract_bits(card->cid, 112, 4),
1727 (int) card_extract_bits(card->cid, 116, 4) + 1997); 1653 (int) card_extract_bits(card->cid, 116, 4) + 1997);
1728 dbg_listmessage_addline( 1654 simplelist_addline(SIMPLELIST_ADD_LINE,
1729 "Ser#: 0x%08lx", 1655 "Ser#: 0x%08lx",
1730 card_extract_bits(card->cid, 80, 32)); 1656 card_extract_bits(card->cid, 80, 32));
1731 dbg_listmessage_addline( 1657 simplelist_addline(SIMPLELIST_ADD_LINE,
1732 "M=%02x, O=%04x", 1658 "M=%02x, O=%04x",
1733 (int) card_extract_bits(card->cid, 0, 8), 1659 (int) card_extract_bits(card->cid, 0, 8),
1734 (int) card_extract_bits(card->cid, 8, 16)); 1660 (int) card_extract_bits(card->cid, 8, 16));
1735 int temp = card_extract_bits(card->csd, 2, 4); 1661 int temp = card_extract_bits(card->csd, 2, 4);
1736 dbg_listmessage_addline( 1662 simplelist_addline(SIMPLELIST_ADD_LINE,
1737 CARDTYPE " v%s", temp < 5 ? 1663 CARDTYPE " v%s", temp < 5 ?
1738 spec_vers[temp] : "?.?"); 1664 spec_vers[temp] : "?.?");
1739 dbg_listmessage_addline( 1665 simplelist_addline(SIMPLELIST_ADD_LINE,
1740 "Blocks: 0x%06lx", card->numblocks); 1666 "Blocks: 0x%06lx", card->numblocks);
1741 dbg_listmessage_addline( 1667 simplelist_addline(SIMPLELIST_ADD_LINE,
1742 "Blksz.: %d P:%c%c", card->blocksize, 1668 "Blksz.: %d P:%c%c", card->blocksize,
1743 card_extract_bits(card->csd, 48, 1) ? 'R' : '-', 1669 card_extract_bits(card->csd, 48, 1) ? 'R' : '-',
1744 card_extract_bits(card->csd, 106, 1) ? 'W' : '-'); 1670 card_extract_bits(card->csd, 106, 1) ? 'W' : '-');
1745 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000, 1671 output_dyn_value(pbuf, sizeof pbuf, card->speed / 1000,
1746 kbit_units, false); 1672 kbit_units, false);
1747 dbg_listmessage_addline( 1673 simplelist_addline(SIMPLELIST_ADD_LINE,
1748 "Speed: %s", pbuf); 1674 "Speed: %s", pbuf);
1749 output_dyn_value(pbuf, sizeof pbuf, card->tsac, 1675 output_dyn_value(pbuf, sizeof pbuf, card->tsac,
1750 nsec_units, false); 1676 nsec_units, false);
1751 dbg_listmessage_addline( 1677 simplelist_addline(SIMPLELIST_ADD_LINE,
1752 "Tsac: %s", pbuf); 1678 "Tsac: %s", pbuf);
1753 dbg_listmessage_addline( 1679 simplelist_addline(SIMPLELIST_ADD_LINE,
1754 "Nsac: %d clk", card->nsac); 1680 "Nsac: %d clk", card->nsac);
1755 dbg_listmessage_addline( 1681 simplelist_addline(SIMPLELIST_ADD_LINE,
1756 "R2W: *%d", card->r2w_factor); 1682 "R2W: *%d", card->r2w_factor);
1757 dbg_listmessage_addline( 1683 simplelist_addline(SIMPLELIST_ADD_LINE,
1758 "IRmax: %d..%d mA", 1684 "IRmax: %d..%d mA",
1759 i_vmin[card_extract_bits(card->csd, 66, 3)], 1685 i_vmin[card_extract_bits(card->csd, 66, 3)],
1760 i_vmax[card_extract_bits(card->csd, 69, 3)]); 1686 i_vmax[card_extract_bits(card->csd, 69, 3)]);
1761 dbg_listmessage_addline( 1687 simplelist_addline(SIMPLELIST_ADD_LINE,
1762 "IWmax: %d..%d mA", 1688 "IWmax: %d..%d mA",
1763 i_vmin[card_extract_bits(card->csd, 72, 3)], 1689 i_vmin[card_extract_bits(card->csd, 72, 3)],
1764 i_vmax[card_extract_bits(card->csd, 75, 3)]); 1690 i_vmax[card_extract_bits(card->csd, 75, 3)]);
1765 } 1691 }
1766 else if (card->initialized == 0) 1692 else if (card->initialized == 0)
1767 { 1693 {
1768 dbg_listmessage_addline("Not Found!"); 1694 simplelist_addline(SIMPLELIST_ADD_LINE, "Not Found!");
1769 } 1695 }
1770#ifndef HAVE_MMC 1696#ifndef HAVE_MMC
1771 else /* card->initialized < 0 */ 1697 else /* card->initialized < 0 */
1772 { 1698 {
1773 dbg_listmessage_addline("Init Error! (%d)", card->initialized); 1699 simplelist_addline(SIMPLELIST_ADD_LINE, "Init Error! (%d)", card->initialized);
1774 } 1700 }
1775#endif 1701#endif
1776 snprintf(info->title, 16, "[" CARDTYPE " %d]", (int)info->cbdata); 1702 snprintf(title, 16, "[" CARDTYPE " %d]", *cardnum);
1777 gui_synclist_set_nb_items(info->lists, dbg_listmessage_getlines()); 1703 gui_synclist_set_title(lists, title, Icon_NOICON);
1778 gui_synclist_select_item(info->lists, 0); 1704 gui_synclist_set_nb_items(lists, simplelist_get_line_count());
1705 gui_synclist_select_item(lists, 0);
1779 btn = ACTION_REDRAW; 1706 btn = ACTION_REDRAW;
1780 } 1707 }
1781 return btn; 1708 return btn;
1782} 1709}
1783static bool dbg_disk_info(void)
1784{
1785 char listtitle[16];
1786 struct action_callback_info info;
1787 info.title = listtitle;
1788 info.count = 1;
1789 info.selection_size = 1;
1790 info.action_callback = cardinfo_callback;
1791 info.dbg_getname = dbg_listmessage_getname;
1792 info.cbdata = 0;
1793 dbg_list(&info);
1794 return false;
1795}
1796#else /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */ 1710#else /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1797static int disk_callback(int btn, struct action_callback_info *info) 1711static int disk_callback(int btn, struct gui_synclist *lists)
1798{ 1712{
1713 (void)lists;
1799 int i; 1714 int i;
1800 char buf[128]; 1715 char buf[128];
1801 unsigned short* identify_info = ata_get_identify(); 1716 unsigned short* identify_info = ata_get_identify();
1802 bool timing_info_present = false; 1717 bool timing_info_present = false;
1803 (void)btn; 1718 (void)btn;
1804 1719
1805 dbg_listmessage_setlines(0); 1720 simplelist_set_line_count(0);
1806 1721
1807 for (i=0; i < 20; i++) 1722 for (i=0; i < 20; i++)
1808 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]); 1723 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
@@ -1810,32 +1725,31 @@ static int disk_callback(int btn, struct action_callback_info *info)
1810 /* kill trailing space */ 1725 /* kill trailing space */
1811 for (i=39; i && buf[i]==' '; i--) 1726 for (i=39; i && buf[i]==' '; i--)
1812 buf[i] = 0; 1727 buf[i] = 0;
1813 dbg_listmessage_addline( 1728 simplelist_addline(SIMPLELIST_ADD_LINE, "Model: %s", buf);
1814 "Model: %s", buf);
1815 for (i=0; i < 4; i++) 1729 for (i=0; i < 4; i++)
1816 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]); 1730 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
1817 buf[8]=0; 1731 buf[8]=0;
1818 dbg_listmessage_addline( 1732 simplelist_addline(SIMPLELIST_ADD_LINE,
1819 "Firmware: %s", buf); 1733 "Firmware: %s", buf);
1820 snprintf(buf, sizeof buf, "%ld MB", 1734 snprintf(buf, sizeof buf, "%ld MB",
1821 ((unsigned long)identify_info[61] << 16 | 1735 ((unsigned long)identify_info[61] << 16 |
1822 (unsigned long)identify_info[60]) / 2048 ); 1736 (unsigned long)identify_info[60]) / 2048 );
1823 dbg_listmessage_addline( 1737 simplelist_addline(SIMPLELIST_ADD_LINE,
1824 "Size: %s", buf); 1738 "Size: %s", buf);
1825 unsigned long free; 1739 unsigned long free;
1826 fat_size( IF_MV2(0,) NULL, &free ); 1740 fat_size( IF_MV2(0,) NULL, &free );
1827 dbg_listmessage_addline( 1741 simplelist_addline(SIMPLELIST_ADD_LINE,
1828 "Free: %ld MB", free / 1024); 1742 "Free: %ld MB", free / 1024);
1829 dbg_listmessage_addline( 1743 simplelist_addline(SIMPLELIST_ADD_LINE,
1830 "Spinup time: %d ms", ata_spinup_time * (1000/HZ)); 1744 "Spinup time: %d ms", ata_spinup_time * (1000/HZ));
1831 i = identify_info[83] & (1<<3); 1745 i = identify_info[83] & (1<<3);
1832 dbg_listmessage_addline( 1746 simplelist_addline(SIMPLELIST_ADD_LINE,
1833 "Power mgmt: %s", i ? "enabled" : "unsupported"); 1747 "Power mgmt: %s", i ? "enabled" : "unsupported");
1834 i = identify_info[83] & (1<<9); 1748 i = identify_info[83] & (1<<9);
1835 dbg_listmessage_addline( 1749 simplelist_addline(SIMPLELIST_ADD_LINE,
1836 "Noise mgmt: %s", i ? "enabled" : "unsupported"); 1750 "Noise mgmt: %s", i ? "enabled" : "unsupported");
1837 i = identify_info[82] & (1<<6); 1751 i = identify_info[82] & (1<<6);
1838 dbg_listmessage_addline( 1752 simplelist_addline(SIMPLELIST_ADD_LINE,
1839 "Read-ahead: %s", i ? "enabled" : "unsupported"); 1753 "Read-ahead: %s", i ? "enabled" : "unsupported");
1840 timing_info_present = identify_info[53] & (1<<1); 1754 timing_info_present = identify_info[53] & (1<<1);
1841 if(timing_info_present) { 1755 if(timing_info_present) {
@@ -1843,122 +1757,137 @@ static int disk_callback(int btn, struct action_callback_info *info)
1843 pio4[1] = 0; 1757 pio4[1] = 0;
1844 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0; 1758 pio3[0] = (identify_info[64] & (1<<0)) ? '3' : 0;
1845 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0; 1759 pio4[0] = (identify_info[64] & (1<<1)) ? '4' : 0;
1846 dbg_listmessage_addline( 1760 simplelist_addline(SIMPLELIST_ADD_LINE,
1847 "PIO modes: 0 1 2 %s %s", pio3, pio4); 1761 "PIO modes: 0 1 2 %s %s", pio3, pio4);
1848 } 1762 }
1849 else { 1763 else {
1850 dbg_listmessage_addline( 1764 simplelist_addline(SIMPLELIST_ADD_LINE,
1851 "No PIO mode info"); 1765 "No PIO mode info");
1852 } 1766 }
1853 timing_info_present = identify_info[53] & (1<<1); 1767 timing_info_present = identify_info[53] & (1<<1);
1854 if(timing_info_present) { 1768 if(timing_info_present) {
1855 dbg_listmessage_addline( 1769 simplelist_addline(SIMPLELIST_ADD_LINE,
1856 "Cycle times %dns/%dns", 1770 "Cycle times %dns/%dns",
1857 identify_info[67], 1771 identify_info[67],
1858 identify_info[68] ); 1772 identify_info[68] );
1859 } else { 1773 } else {
1860 dbg_listmessage_addline( 1774 simplelist_addline(SIMPLELIST_ADD_LINE,
1861 "No timing info"); 1775 "No timing info");
1862 } 1776 }
1863 timing_info_present = identify_info[53] & (1<<1); 1777 timing_info_present = identify_info[53] & (1<<1);
1864 if(timing_info_present) { 1778 if(timing_info_present) {
1865 i = identify_info[49] & (1<<11); 1779 i = identify_info[49] & (1<<11);
1866 dbg_listmessage_addline( 1780 simplelist_addline(SIMPLELIST_ADD_LINE,
1867 "IORDY support: %s", i ? "yes" : "no"); 1781 "IORDY support: %s", i ? "yes" : "no");
1868 i = identify_info[49] & (1<<10); 1782 i = identify_info[49] & (1<<10);
1869 dbg_listmessage_addline( 1783 simplelist_addline(SIMPLELIST_ADD_LINE,
1870 "IORDY disable: %s", i ? "yes" : "no"); 1784 "IORDY disable: %s", i ? "yes" : "no");
1871 } else { 1785 } else {
1872 dbg_listmessage_addline( 1786 simplelist_addline(SIMPLELIST_ADD_LINE,
1873 "No timing info"); 1787 "No timing info");
1874 } 1788 }
1875 dbg_listmessage_addline( 1789 simplelist_addline(SIMPLELIST_ADD_LINE,
1876 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0))); 1790 "Cluster size: %d bytes", fat_get_cluster_size(IF_MV(0)));
1877 gui_synclist_set_nb_items(info->lists, dbg_listmessage_getlines());
1878 return btn; 1791 return btn;
1879} 1792}
1793#endif /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1880static bool dbg_disk_info(void) 1794static bool dbg_disk_info(void)
1881{ 1795{
1882 struct action_callback_info info; 1796 struct simplelist_info info;
1797#if defined(HAVE_MMC) || defined(HAVE_HOTSWAP)
1798 char title[16];
1799 int card = 0;
1800 info.callback_data = (void*)&card;
1801 info.title = title;
1802#else
1803 info.callback_data = NULL;
1883 info.title = "Disk Info"; 1804 info.title = "Disk Info";
1805#endif
1884 info.count = 1; 1806 info.count = 1;
1885 info.selection_size = 1; 1807 info.selection_size = 1;
1886 info.action_callback = disk_callback; 1808 info.action_callback = disk_callback;
1887 info.dbg_getname = dbg_listmessage_getname; 1809 info.hide_selection = true;
1888 dbg_list(&info); 1810 info.scroll_all = false;
1889 return false; 1811 info.get_icon = NULL;
1812 info.get_name = NULL;
1813 return simplelist_show_list(&info);
1890} 1814}
1891#endif /* !defined(HAVE_MMC) && !defined(HAVE_HOTSWAP) */
1892#endif /* !SIMULATOR */ 1815#endif /* !SIMULATOR */
1893 1816
1894#ifdef HAVE_DIRCACHE 1817#ifdef HAVE_DIRCACHE
1895static int dircache_callback(int btn, struct action_callback_info *info) 1818static int dircache_callback(int btn, struct gui_synclist *lists)
1896{ 1819{
1897 (void)btn; (void)info; 1820 (void)btn; (void)lists;
1898 dbg_listmessage_setlines(0); 1821 simplelist_set_line_count(0);
1899 dbg_listmessage_addline("Cache initialized: %s", 1822 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache initialized: %s",
1900 dircache_is_enabled() ? "Yes" : "No"); 1823 dircache_is_enabled() ? "Yes" : "No");
1901 dbg_listmessage_addline("Cache size: %d B", 1824 simplelist_addline(SIMPLELIST_ADD_LINE, "Cache size: %d B",
1902 dircache_get_cache_size()); 1825 dircache_get_cache_size());
1903 dbg_listmessage_addline("Last size: %d B", 1826 simplelist_addline(SIMPLELIST_ADD_LINE, "Last size: %d B",
1904 global_status.dircache_size); 1827 global_status.dircache_size);
1905 dbg_listmessage_addline("Limit: %d B", 1828 simplelist_addline(SIMPLELIST_ADD_LINE, "Limit: %d B",
1906 DIRCACHE_LIMIT); 1829 DIRCACHE_LIMIT);
1907 dbg_listmessage_addline("Reserve: %d/%d B", 1830 simplelist_addline(SIMPLELIST_ADD_LINE, "Reserve: %d/%d B",
1908 dircache_get_reserve_used(), DIRCACHE_RESERVE); 1831 dircache_get_reserve_used(), DIRCACHE_RESERVE);
1909 dbg_listmessage_addline("Scanning took: %d s", 1832 simplelist_addline(SIMPLELIST_ADD_LINE, "Scanning took: %d s",
1910 dircache_get_build_ticks() / HZ); 1833 dircache_get_build_ticks() / HZ);
1911 dbg_listmessage_addline("Entry count: %d", 1834 simplelist_addline(SIMPLELIST_ADD_LINE, "Entry count: %d",
1912 dircache_get_entry_count()); 1835 dircache_get_entry_count());
1913 return btn; 1836 return btn;
1914} 1837}
1915 1838
1916static bool dbg_dircache_info(void) 1839static bool dbg_dircache_info(void)
1917{ 1840{
1918 struct action_callback_info info; 1841 struct simplelist_info info;
1919 info.title = "Dircache Info"; 1842 info.title = "Dircache Info";
1920 info.count = 7; 1843 info.count = 7;
1921 info.selection_size = 1; 1844 info.selection_size = 1;
1922 info.action_callback = dircache_callback; 1845 info.action_callback = dircache_callback;
1923 info.dbg_getname = dbg_listmessage_getname; 1846 info.hide_selection = true;
1924 dbg_list(&info); 1847 info.scroll_all = false;
1925 return false; 1848 info.get_icon = NULL;
1849 info.get_name = NULL;
1850 info.callback_data = NULL;
1851 return simplelist_show_list(&info);
1926} 1852}
1927 1853
1928#endif /* HAVE_DIRCACHE */ 1854#endif /* HAVE_DIRCACHE */
1929 1855
1930#ifdef HAVE_TAGCACHE 1856#ifdef HAVE_TAGCACHE
1931static int database_callback(int btn, struct action_callback_info *info) 1857static int database_callback(int btn, struct gui_synclist *lists)
1932{ 1858{
1933 (void)btn; (void)info; 1859 (void)btn; (void)lists;
1934 struct tagcache_stat *stat = tagcache_get_stat(); 1860 struct tagcache_stat *stat = tagcache_get_stat();
1935 dbg_listmessage_setlines(0); 1861 simplelist_set_line_count(0);
1936 dbg_listmessage_addline("Initialized: %s", 1862 simplelist_addline(SIMPLELIST_ADD_LINE, "Initialized: %s",
1937 stat->initialized ? "Yes" : "No"); 1863 stat->initialized ? "Yes" : "No");
1938 dbg_listmessage_addline("DB Ready: %s", 1864 simplelist_addline(SIMPLELIST_ADD_LINE, "DB Ready: %s",
1939 stat->ready ? "Yes" : "No"); 1865 stat->ready ? "Yes" : "No");
1940 dbg_listmessage_addline("RAM Cache: %s", 1866 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM Cache: %s",
1941 stat->ramcache ? "Yes" : "No"); 1867 stat->ramcache ? "Yes" : "No");
1942 dbg_listmessage_addline("RAM: %d/%d B", 1868 simplelist_addline(SIMPLELIST_ADD_LINE, "RAM: %d/%d B",
1943 stat->ramcache_used, stat->ramcache_allocated); 1869 stat->ramcache_used, stat->ramcache_allocated);
1944 dbg_listmessage_addline("Progress: %d%% (%d entries)", 1870 simplelist_addline(SIMPLELIST_ADD_LINE, "Progress: %d%% (%d entries)",
1945 stat->progress, stat->processed_entries); 1871 stat->progress, stat->processed_entries);
1946 dbg_listmessage_addline("Commit step: %d", 1872 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit step: %d",
1947 stat->commit_step); 1873 stat->commit_step);
1948 dbg_listmessage_addline("Commit delayed: %s", 1874 simplelist_addline(SIMPLELIST_ADD_LINE, "Commit delayed: %s",
1949 stat->commit_delayed ? "Yes" : "No"); 1875 stat->commit_delayed ? "Yes" : "No");
1950 return btn; 1876 return btn;
1951} 1877}
1952static bool dbg_tagcache_info(void) 1878static bool dbg_tagcache_info(void)
1953{ 1879{
1954 struct action_callback_info info; 1880 struct simplelist_info info;
1955 info.title = "Database Info"; 1881 info.title = "Database Info";
1956 info.count = 7; 1882 info.count = 7;
1957 info.selection_size = 1; 1883 info.selection_size = 1;
1958 info.action_callback = database_callback; 1884 info.action_callback = database_callback;
1959 info.dbg_getname = dbg_listmessage_getname; 1885 info.hide_selection = true;
1960 dbg_list(&info); 1886 info.scroll_all = false;
1961 return false; 1887 info.get_icon = NULL;
1888 info.get_name = NULL;
1889 info.callback_data = NULL;
1890 return simplelist_show_list(&info);
1962} 1891}
1963#endif 1892#endif
1964 1893
@@ -2049,61 +1978,67 @@ static bool dbg_save_roms(void)
2049 1978
2050#ifndef SIMULATOR 1979#ifndef SIMULATOR
2051#if CONFIG_TUNER 1980#if CONFIG_TUNER
2052static int radio_callback(int btn, struct action_callback_info *info) 1981static int radio_callback(int btn, struct gui_synclist *lists)
2053{ 1982{
2054 dbg_listmessage_setlines(1); 1983 (void)lists;
1984 if (btn == ACTION_STD_CANCEL)
1985 return btn;
1986 simplelist_set_line_count(1);
2055 1987
2056#if (CONFIG_TUNER & LV24020LP) 1988#if (CONFIG_TUNER & LV24020LP)
2057 dbg_listmessage_addline("CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) ); 1989 simplelist_addline(SIMPLELIST_ADD_LINE,
2058 dbg_listmessage_addline("RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) ); 1990 "CTRL_STAT: %02X", lv24020lp_get(LV24020LP_CTRL_STAT) );
2059 dbg_listmessage_addline("MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) ); 1991 simplelist_addline(SIMPLELIST_ADD_LINE,
2060 dbg_listmessage_addline("MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) ); 1992 "RADIO_STAT: %02X", lv24020lp_get(LV24020LP_REG_STAT) );
2061 dbg_listmessage_addline("MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) ); 1993 simplelist_addline(SIMPLELIST_ADD_LINE,
2062 dbg_listmessage_addline("if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) ); 1994 "MSS_FM: %d kHz", lv24020lp_get(LV24020LP_MSS_FM) );
2063 dbg_listmessage_addline("sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) ); 1995 simplelist_addline(SIMPLELIST_ADD_LINE,
1996 "MSS_IF: %d Hz", lv24020lp_get(LV24020LP_MSS_IF) );
1997 simplelist_addline(SIMPLELIST_ADD_LINE,
1998 "MSS_SD: %d Hz", lv24020lp_get(LV24020LP_MSS_SD) );
1999 simplelist_addline(SIMPLELIST_ADD_LINE,
2000 "if_set: %d Hz", lv24020lp_get(LV24020LP_IF_SET) );
2001 simplelist_addline(SIMPLELIST_ADD_LINE,
2002 "sd_set: %d Hz", lv24020lp_get(LV24020LP_SD_SET) );
2064#endif 2003#endif
2065#if (CONFIG_TUNER & S1A0903X01) 2004#if (CONFIG_TUNER & S1A0903X01)
2066 dbg_listmessage_addline("Samsung regs: %08X", s1a0903x01_get(RADIO_ALL)); 2005 simplelist_addline(SIMPLELIST_ADD_LINE,
2006 "Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
2067 /* This one doesn't return dynamic data atm */ 2007 /* This one doesn't return dynamic data atm */
2068#endif 2008#endif
2069#if (CONFIG_TUNER & TEA5767) 2009#if (CONFIG_TUNER & TEA5767)
2070 struct tea5767_dbg_info nfo; 2010 struct tea5767_dbg_info nfo;
2071 tea5767_dbg_info(&nfo); 2011 tea5767_dbg_info(&nfo);
2072 dbg_listmessage_addline("Philips regs:"); 2012 simplelist_addline(SIMPLELIST_ADD_LINE, "Philips regs:");
2073 dbg_listmessage_addline( 2013 simplelist_addline(SIMPLELIST_ADD_LINE,
2074 " Read: %02X %02X %02X %02X %02X", 2014 " Read: %02X %02X %02X %02X %02X",
2075 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1], 2015 (unsigned)nfo.read_regs[0], (unsigned)nfo.read_regs[1],
2076 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3], 2016 (unsigned)nfo.read_regs[2], (unsigned)nfo.read_regs[3],
2077 (unsigned)nfo.read_regs[4]); 2017 (unsigned)nfo.read_regs[4]);
2078 dbg_listmessage_addline( 2018 simplelist_addline(SIMPLELIST_ADD_LINE,
2079 " Write: %02X %02X %02X %02X %02X", 2019 " Write: %02X %02X %02X %02X %02X",
2080 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1], 2020 (unsigned)nfo.write_regs[0], (unsigned)nfo.write_regs[1],
2081 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3], 2021 (unsigned)nfo.write_regs[2], (unsigned)nfo.write_regs[3],
2082 (unsigned)nfo.write_regs[4]); 2022 (unsigned)nfo.write_regs[4]);
2083#endif 2023#endif
2084 2024 return ACTION_REDRAW;
2085 if (btn != ACTION_STD_CANCEL)
2086 btn = ACTION_REDRAW;
2087
2088 gui_synclist_set_nb_items(info->lists, dbg_listmessage_getlines());
2089 return btn;
2090} 2025}
2091static bool dbg_fm_radio(void) 2026static bool dbg_fm_radio(void)
2092{ 2027{
2093 struct action_callback_info info; 2028 struct simplelist_info info;
2029 simplelist_set_line_count(0);
2030 simplelist_addline(SIMPLELIST_ADD_LINE, "HW detected: %s", radio_hardware_present() ? "yes" : "no");
2094 2031
2095 info.title = "FM Radio"; 2032 info.title = "FM Radio";
2096 info.count = 1; 2033 info.count = 1;
2097 info.selection_size = 1; 2034 info.selection_size = 1;
2098 info.cbdata = radio_hardware_present(); 2035 info.action_callback = radio_hardware_present()?radio_callback : NULL;
2099 info.action_callback = info.cbdata ? radio_callback : NULL; 2036 info.hide_selection = true;
2100 info.dbg_getname = dbg_listmessage_getname; 2037 info.scroll_all = false;
2101 2038 info.get_icon = NULL;
2102 dbg_listmessage_setlines(0); 2039 info.get_name = NULL;
2103 dbg_listmessage_addline("HW detected: %s", info.cbdata ? "yes" : "no"); 2040 info.callback_data = NULL;
2104 2041 return simplelist_show_list(&info);
2105 dbg_list(&info);
2106 return false;
2107} 2042}
2108#endif /* CONFIG_TUNER */ 2043#endif /* CONFIG_TUNER */
2109#endif /* !SIMULATOR */ 2044#endif /* !SIMULATOR */
@@ -2339,13 +2274,12 @@ static const struct the_menu_item menuitems[] = {
2339 {"cpu_boost log",cpu_boost_log}, 2274 {"cpu_boost log",cpu_boost_log},
2340#endif 2275#endif
2341 }; 2276 };
2342static int menu_action_callback(int btn, struct action_callback_info *info) 2277static int menu_action_callback(int btn, struct gui_synclist *lists)
2343{ 2278{
2344 gui_synclist_hide_selection_marker(info->lists, false);
2345 if (btn == ACTION_STD_OK) 2279 if (btn == ACTION_STD_OK)
2346 { 2280 {
2347 menuitems[gui_synclist_get_sel_pos(info->lists)].function(); 2281 menuitems[gui_synclist_get_sel_pos(lists)].function();
2348 gui_synclist_draw(info->lists); 2282 btn = ACTION_REDRAW;
2349 } 2283 }
2350 return btn; 2284 return btn;
2351} 2285}
@@ -2356,12 +2290,16 @@ static char* dbg_menu_getname(int item, void * data, char *buffer)
2356} 2290}
2357bool debug_menu(void) 2291bool debug_menu(void)
2358{ 2292{
2359 struct action_callback_info info; 2293 struct simplelist_info info;
2360 info.title = "Debug Menu"; 2294 info.title = "Debug Menu";
2295 info.selection_size = 1;
2361 info.count = ARRAYLEN(menuitems); 2296 info.count = ARRAYLEN(menuitems);
2362 info.selection_size = 1; 2297 info.selection_size = 1;
2363 info.action_callback = menu_action_callback; 2298 info.action_callback = menu_action_callback;
2364 info.dbg_getname = dbg_menu_getname; 2299 info.hide_selection = false;
2365 dbg_list(&info); 2300 info.scroll_all = false;
2366 return false; 2301 info.get_icon = NULL;
2302 info.get_name = dbg_menu_getname;
2303 info.callback_data = NULL;
2304 return simplelist_show_list(&info);
2367} 2305}
diff --git a/apps/gui/list.c b/apps/gui/list.c
index 41bde5802b..52c1e4a3b9 100644
--- a/apps/gui/list.c
+++ b/apps/gui/list.c
@@ -1028,3 +1028,106 @@ bool gui_synclist_do_button(struct gui_synclist * lists,
1028 } 1028 }
1029 return false; 1029 return false;
1030} 1030}
1031
1032/* Simple use list implementation */
1033static int simplelist_line_count = 0;
1034static char simplelist_text[SIMPLELIST_MAX_LINES][SIMPLELIST_MAX_LINELENGTH];
1035/* set the amount of lines shown in the list */
1036void simplelist_set_line_count(int lines)
1037{
1038 if (lines < 0)
1039 lines = 0;
1040 else if (lines > SIMPLELIST_MAX_LINES)
1041 lines = SIMPLELIST_MAX_LINES;
1042 simplelist_line_count = 0;
1043}
1044/* get the current amount of lines shown */
1045int simplelist_get_line_count(void)
1046{
1047 return simplelist_line_count;
1048}
1049/* add/edit a line in the list.
1050 if line_number > number of lines shown it adds the line, else it edits the line */
1051void simplelist_addline(int line_number, const char *fmt, ...)
1052{
1053 va_list ap;
1054
1055 if (line_number > simplelist_line_count)
1056 {
1057 if (simplelist_line_count < SIMPLELIST_MAX_LINES)
1058 line_number = simplelist_line_count++;
1059 else
1060 return;
1061 }
1062 va_start(ap, fmt);
1063 vsnprintf(simplelist_text[line_number], SIMPLELIST_MAX_LINELENGTH, fmt, ap);
1064 va_end(ap);
1065}
1066
1067static char* simplelist_static_getname(int item, void * data, char *buffer)
1068{
1069 (void)data; (void)buffer;
1070 return simplelist_text[item];
1071}
1072bool simplelist_show_list(struct simplelist_info *info)
1073{
1074 struct gui_synclist lists;
1075 int action, old_line_count = simplelist_line_count;
1076 char* (*getname)(int item, void * data, char *buffer);
1077 if (info->get_name)
1078 getname = info->get_name;
1079 else
1080 getname = simplelist_static_getname;
1081 gui_synclist_init(&lists, getname, info->callback_data,
1082 info->scroll_all, info->selection_size);
1083 if (info->title)
1084 gui_synclist_set_title(&lists, info->title, NOICON);
1085 if (info->get_icon)
1086 gui_synclist_set_icon_callback(&lists, info->get_icon);
1087
1088 gui_synclist_hide_selection_marker(&lists, info->hide_selection);
1089
1090 if (info->action_callback)
1091 info->action_callback(ACTION_REDRAW, &lists);
1092
1093 if (info->get_name == NULL)
1094 gui_synclist_set_nb_items(&lists, simplelist_line_count*info->selection_size);
1095 else
1096 gui_synclist_set_nb_items(&lists, info->count*info->selection_size);
1097
1098 gui_synclist_draw(&lists);
1099
1100 while(1)
1101 {
1102 gui_syncstatusbar_draw(&statusbars, true);
1103 action = get_action(CONTEXT_STD, HZ/5);
1104 if (gui_synclist_do_button(&lists, &action, LIST_WRAP_UNLESS_HELD))
1105 continue;
1106 if (info->action_callback)
1107 {
1108 action = info->action_callback(action, &lists);
1109 if (info->get_name == NULL)
1110 gui_synclist_set_nb_items(&lists, simplelist_line_count*info->selection_size);
1111 }
1112 if (action == ACTION_STD_CANCEL)
1113 break;
1114 else if ((action == ACTION_REDRAW) || (old_line_count == simplelist_line_count))
1115 {
1116 if (info->get_name == NULL)
1117 gui_synclist_set_nb_items(&lists, simplelist_line_count*info->selection_size);
1118 gui_synclist_draw(&lists);
1119 }
1120 else if(default_event_handler(action) == SYS_USB_CONNECTED)
1121 return true;
1122 }
1123 return false;
1124}
1125
1126
1127
1128
1129
1130
1131
1132
1133
diff --git a/apps/gui/list.h b/apps/gui/list.h
index 9aaa18ed08..2de67f5219 100644
--- a/apps/gui/list.h
+++ b/apps/gui/list.h
@@ -223,5 +223,47 @@ extern void gui_synclist_hide_selection_marker(struct gui_synclist *lists,
223extern bool gui_synclist_do_button(struct gui_synclist * lists, 223extern bool gui_synclist_do_button(struct gui_synclist * lists,
224 unsigned *action, 224 unsigned *action,
225 enum list_wrap); 225 enum list_wrap);
226
227/** Simplelist implementation.
228 USe this if you dont need to reimplement the list code,
229 and just need to show a list
230 **/
231
232struct simplelist_info {
233 char *title; /* title to show on the list */
234 int count; /* number of items in the list, each item is selection_size high */
235 char selection_size; /* list selection size, usually 1 */
236 bool hide_selection;
237 bool scroll_all;
238 int (*action_callback)(int action, struct gui_synclist *lists); /* can be NULL */
239 /* action_callback notes:
240 action == the action pressed by the user
241 _after_ gui_synclist_do_button returns.
242 lists == the lists sturct so the callack can get selection and count etc. */
243 list_get_icon *get_icon; /* can be NULL */
244 list_get_name *get_name; /* NULL if you're using simplelist_addline() */
245 void *callback_data; /* data for callbacks */
246};
247
248#define SIMPLELIST_MAX_LINES 32
249#define SIMPLELIST_MAX_LINELENGTH 32
250
251/** The next three functions are used if the text is mostly static.
252 These should be called in the action callback for the list.
253 **/
254/* set the amount of lines shown in the list
255 Only needed if simplelist_info.get_name == NULL */
256void simplelist_set_line_count(int lines);
257/* get the current amount of lines shown */
258int simplelist_get_line_count(void);
259/* add/edit a line in the list.
260 if line_number > number of lines shown it adds the line, else it edits the line */
261#define SIMPLELIST_ADD_LINE (SIMPLELIST_MAX_LINES+1)
262void simplelist_addline(int line_number, const char *fmt, ...);
263
264/* show a list.
265 if list->action_callback != NULL it is called with the action ACTION_REDRAW
266 before the list is dislplayed for the first time */
267bool simplelist_show_list(struct simplelist_info *info);
226 268
227#endif /* _GUI_LIST_H_ */ 269#endif /* _GUI_LIST_H_ */