Index: apps/SOURCES
===================================================================
RCS file: /cvsroot/rockbox/apps/SOURCES,v
retrieving revision 1.44
diff -u -b -r1.44 SOURCES
--- apps/SOURCES 26 Mar 2006 11:33:41 -0000 1.44
+++ apps/SOURCES 24 Jun 2006 15:11:21 -0000
@@ -81,3 +81,6 @@
#endif
metadata.c
tagcache.c
+#if CONFIG_KEYPAD == IPOD_4G_PAD && !defined(IPOD_MINI)
+ipod_scroll_wheel_gui.c
+#endif
Index: apps/ipod_scroll_wheel_gui.c
===================================================================
RCS file: apps/ipod_scroll_wheel_gui.c
diff -N apps/ipod_scroll_wheel_gui.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ apps/ipod_scroll_wheel_gui.c 24 Jun 2006 15:11:21 -0000
@@ -0,0 +1,164 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) TP Diffenbach (2006)
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "config.h"
+
+#if CONFIG_KEYPAD == IPOD_4G_PAD && !defined(IPOD_MINI)
+
+#include "button.h"
+#include "settings.h"
+#include "logf.h"
+#include "list.h"
+#include "screen_access.h"
+#include "statusbar.h"
+#include "ipod_scroll_wheel_gui.h"
+
+ struct scroll_accel_jump {
+ enum { NOACCEL, PAGE, PERCENT } jump_type ;
+ unsigned int amount ;
+ unsigned int lines ;
+} ;
+
+struct scroll_accel_jump scroll_accel_jumps[] = { { NOACCEL, 0, 0 }, { PAGE, 1, 0 }, { PAGE, 8, 0 } , { PERCENT, 10, 0 } } ;
+
+static void calculate_jump_lines( struct scroll_accel_jump* j, unsigned int list_items, unsigned int screen_lines ) {
+ j->lines = j->jump_type == PERCENT
+ ? ( j->amount * list_items ) / 100
+ : j->amount * screen_lines ;
+}
+
+static inline unsigned int list_items( struct gui_list* list ) {
+ return list->nb_items ;
+}
+
+static inline unsigned int screen_lines( struct gui_list* list ) {
+ return list->display->nb_lines ;
+}
+
+static struct scroll_accel_jump* find_accel_for_list(
+ struct gui_list* list, struct scroll_accel_jump* jump, unsigned int raw_accel ) {
+ unsigned int l_items = list_items( list ) ;
+ unsigned int s_lines = screen_lines( list ) ;
+
+ /* never accel in a list <= page long */
+ if( raw_accel == 0 || l_items <= s_lines ) {
+ return jump ;
+ }
+
+ /* otherwise, find the highest possible accel */
+ calculate_jump_lines( jump + raw_accel, l_items, s_lines ) ;
+
+ while( raw_accel > 1 ) {
+ calculate_jump_lines( jump + raw_accel - 1, l_items, s_lines ) ;
+ if( jump[ raw_accel ].lines > jump[ raw_accel - 1 ].lines ) break ;
+ --raw_accel ;
+ }
+ return jump + raw_accel ;
+}
+
+static void display_ipod_scroll_wheel_acceration( int accel, int speed ) {
+ static int previous_accel = -1 ;
+ static int previous_speed = 0 ;
+ if( previous_accel != accel || previous_speed != speed ) {
+ gui_statusbar_draw_scroll_accel( &screens[ SCREEN_MAIN ], accel, speed ) ;
+ previous_accel = accel ;
+ previous_speed = speed ;
+ }
+}
+
+
+/* public functions declared in header */
+/* these next two really belong in list.c */
+void gui_synclist_select_forward_n_lines( struct gui_synclist* lists, unsigned int lines )
+{
+ int i;
+ FOR_NB_SCREENS(i)
+ gui_list_select_next_page(&(lists->gui_list[i]), lines );
+}
+
+void gui_synclist_select_back_n_lines( struct gui_synclist* lists, unsigned int lines )
+{
+ int i;
+ FOR_NB_SCREENS(i)
+ gui_list_select_previous_page(&(lists->gui_list[i]), lines);
+}
+
+
+/* this goes away in production, I think */
+static get_ipod_scroll_wheel_acceration_and_cps( int* speed ) {
+ int cps = get_ipod_scroll_wheel_clicks_per_second() ;
+ *speed = cps ;
+ unsigned int acps = cps < 0 ? -cps : cps ;
+ int a = acps < global_settings.ipod_scroll_wheel_acceleration_fast
+ ? 0
+ : ( acps < global_settings.ipod_scroll_wheel_acceleration_faster
+ ? 1
+ : ( acps < global_settings.ipod_scroll_wheel_acceleration_fastest
+ ? 2
+ : 3 ) ) ;
+#ifdef ROCKBOX_HAS_LOGF
+ logf( "g:%d,%d", cps, a ) ;
+#endif
+ return a ;
+}
+
+
+/* dispatch the correct synclist function depending on scroll acceleration factor */
+void gui_synclist_handle_accel( struct gui_synclist * lists, enum screen_type screen, enum list_dir dir)
+{
+ int cps ;
+ struct scroll_accel_jump* jump = find_accel_for_list(
+ &(lists->gui_list[ screen ] ), scroll_accel_jumps, get_ipod_scroll_wheel_acceration_and_cps( &cps ) ) ;
+
+ if( jump->jump_type == NOACCEL ) {
+ if( dir == FORWARD )
+ gui_synclist_select_next( lists ) ;
+ else
+ gui_synclist_select_previous( lists ) ;
+ } else {
+ if( dir == FORWARD )
+ gui_synclist_select_forward_n_lines( lists, jump->lines ) ;
+ else
+ gui_synclist_select_back_n_lines( lists, jump->lines ) ;
+ }
+
+ display_ipod_scroll_wheel_acceration( jump - scroll_accel_jumps, cps ) ;
+}
+
+ unsigned int get_ipod_scroll_wheel_acceration( void ) {
+ int cps = get_ipod_scroll_wheel_clicks_per_second() ;
+
+ unsigned int acps = cps < 0 ? -cps : cps ;
+ int a = acps < global_settings.ipod_scroll_wheel_acceleration_fast
+ ? 0
+ : ( acps < global_settings.ipod_scroll_wheel_acceleration_faster
+ ? 1
+ : ( acps < global_settings.ipod_scroll_wheel_acceleration_fastest
+ ? 2
+ : 3 ) ) ;
+
+ return a ;
+ }
+
+unsigned int get_and_display_ipod_scroll_wheel_acceration( void ) {
+ int cps ;
+ int a = get_ipod_scroll_wheel_acceration_and_cps( &cps ) ;
+ display_ipod_scroll_wheel_acceration( a, cps ) ;
+ return a ;
+}
+#endif
Index: apps/ipod_scroll_wheel_gui.h
===================================================================
RCS file: apps/ipod_scroll_wheel_gui.h
diff -N apps/ipod_scroll_wheel_gui.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ apps/ipod_scroll_wheel_gui.h 24 Jun 2006 15:11:21 -0000
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) TP Diffenbach (2006)
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef _IPOD_SCROLL_WHEEL_GUI_H_
+#define _IPOD_SCROLL_WHEEL_GUI_H_
+#include "config.h"
+
+#if CONFIG_KEYPAD == IPOD_4G_PAD && !defined(IPOD_MINI)
+#include "list.h"
+#include "screen_access.h"
+
+extern void gui_synclist_select_forward_n_lines(struct gui_synclist* lists, unsigned int lines ) ;
+extern void gui_synclist_select_back_n_lines(struct gui_synclist* lists, unsigned int lines ) ;
+
+enum list_dir { BACKWARD, FORWARD } ;
+/* dispatch the correct synclist function depending on scroll acceleration factor
+ * may adjust the actual accelration depending on list length
+ * displays adjusted acceleration to the statusbar (if the statusbar is on, clients don't need to check)
+*/
+extern void gui_synclist_handle_accel( struct gui_synclist* lists, enum screen_type screen, enum list_dir dir) ;
+
+/* returns the accelreation */
+extern unsigned int get_ipod_scroll_wheel_acceration( void ) ;
+
+/* returns the accelreation and displays it to the statusbar (if the statusbar is on, clients don't need to check) */
+extern unsigned int get_and_display_ipod_scroll_wheel_acceration( void ) ;
+
+#endif
+#endif
Index: apps/settings.c
===================================================================
RCS file: /cvsroot/rockbox/apps/settings.c,v
retrieving revision 1.389
diff -u -b -r1.389 settings.c
--- apps/settings.c 6 Jun 2006 22:23:40 -0000 1.389
+++ apps/settings.c 24 Jun 2006 15:11:22 -0000
@@ -563,6 +563,11 @@
{1, S_O(warnon_erase_dynplaylist), false,
"warn when erasing dynamic playlist", off_on },
+#if (CONFIG_KEYPAD == IPOD_4G_PAD) && !defined(IPOD_MINI)
+ {9, S_O(ipod_scroll_wheel_acceleration_fast), 55, "ipod scroll wheel fast threshold in clicks/sec", NULL }, /* 0...511 */
+ {9, S_O(ipod_scroll_wheel_acceleration_faster), 110, "ipod scroll wheel faster threshold in clicks/sec", NULL }, /* 0...511 */
+ {9, S_O(ipod_scroll_wheel_acceleration_fastest), 165, "ipod scroll wheel fastest threshold in clicks/sec", NULL }, /* 0...511 */
+#endif
/* If values are just added to the end, no need to bump the version. */
/* new stuff to be added at the end */
Index: apps/settings.h
===================================================================
RCS file: /cvsroot/rockbox/apps/settings.h,v
retrieving revision 1.219
diff -u -b -r1.219 settings.h
--- apps/settings.h 25 May 2006 13:34:51 -0000 1.219
+++ apps/settings.h 24 Jun 2006 15:11:23 -0000
@@ -495,6 +495,12 @@
#ifdef HAVE_LCD_BITMAP
unsigned char kbd_file[MAX_FILENAME+1]; /* last keyboard */
#endif
+
+#if (CONFIG_KEYPAD == IPOD_4G_PAD) && !defined(IPOD_MINI)
+ unsigned int ipod_scroll_wheel_acceleration_fast ;
+ unsigned int ipod_scroll_wheel_acceleration_faster ;
+ unsigned int ipod_scroll_wheel_acceleration_fastest ;
+#endif
};
enum optiontype { INT, BOOL };
Index: apps/settings_menu.c
===================================================================
RCS file: /cvsroot/rockbox/apps/settings_menu.c,v
retrieving revision 1.257
diff -u -b -r1.257 settings_menu.c
--- apps/settings_menu.c 6 Jun 2006 22:23:41 -0000 1.257
+++ apps/settings_menu.c 24 Jun 2006 15:11:24 -0000
@@ -1950,6 +1950,7 @@
return result;
}
+static bool ipod_scroll_wheel_acceleration_by_speed_menu( void ) ;
static bool system_settings_menu(void)
{
@@ -1976,6 +1977,7 @@
#ifdef CONFIG_CHARGING
{ ID2P(LANG_CAR_ADAPTER_MODE), car_adapter_mode },
#endif
+ { ID2P(LANG_IPOD_SCROLL_WHEEL_SPEED), ipod_scroll_wheel_acceleration_by_speed_menu },
};
m=menu_init( items, sizeof(items) / sizeof(*items), NULL,
@@ -2006,3 +2008,46 @@
menu_exit(m);
return result;
}
+
+static bool ipod_scroll_wheel_set_acceleration_by_speed( int* var, const unsigned char* desc )
+{
+ return set_int( desc, "s", UNIT_SEC, var,
+ NULL, 5, 1, 500, NULL );
+}
+
+static bool ipod_scroll_wheel_acceleration_by_speed_fast( void )
+{
+ return ipod_scroll_wheel_set_acceleration_by_speed(
+ &global_settings.ipod_scroll_wheel_acceleration_fast,
+ str(LANG_IPOD_SCROLL_WHEEL_FAST) ) ;
+}
+
+static bool ipod_scroll_wheel_acceleration_by_speed_faster( void )
+{
+ return ipod_scroll_wheel_set_acceleration_by_speed(
+ &global_settings.ipod_scroll_wheel_acceleration_faster,
+ str(LANG_IPOD_SCROLL_WHEEL_FASTER) ) ;
+}
+
+static bool ipod_scroll_wheel_acceleration_by_speed_fastest( void )
+{
+ return ipod_scroll_wheel_set_acceleration_by_speed(
+ &global_settings.ipod_scroll_wheel_acceleration_fastest,
+ str(LANG_IPOD_SCROLL_WHEEL_FASTEST) ) ;
+}
+
+static bool ipod_scroll_wheel_acceleration_by_speed_menu( void )
+{
+ struct menu_item items[] = {
+ { ID2P(LANG_IPOD_SCROLL_WHEEL_FAST), ipod_scroll_wheel_acceleration_by_speed_fast },
+ { ID2P(LANG_IPOD_SCROLL_WHEEL_FASTER), ipod_scroll_wheel_acceleration_by_speed_faster },
+ { ID2P(LANG_IPOD_SCROLL_WHEEL_FASTEST), ipod_scroll_wheel_acceleration_by_speed_fastest },
+ };
+
+ int m=menu_init( items, sizeof(items) / sizeof(*items), NULL,
+ NULL, NULL, NULL);
+ bool result = menu_run(m);
+ menu_exit(m);
+ return result;
+}
+
Index: apps/gui/list.c
===================================================================
RCS file: /cvsroot/rockbox/apps/gui/list.c,v
retrieving revision 1.21
diff -u -b -r1.21 list.c
--- apps/gui/list.c 4 Jun 2006 17:14:17 -0000 1.21
+++ apps/gui/list.c 24 Jun 2006 15:11:25 -0000
@@ -30,6 +30,11 @@
#include "scrollbar.h"
#include "statusbar.h"
#include "textarea.h"
+#include "logf.h"
+
+#if CONFIG_KEYPAD == IPOD_4G_PAD && !defined(IPOD_MINI)
+#include "ipod_scroll_wheel_gui.h"
+#endif
#ifdef HAVE_LCD_CHARCELLS
#define SCROLL_LIMIT 1
@@ -43,7 +48,7 @@
static bool offset_out_of_view = false;
#endif
-
+static struct gui_list* last_list_displayed = 0 ;
void gui_list_init(struct gui_list * gui_list,
list_get_name callback_get_item_name,
@@ -62,6 +67,10 @@
#ifdef HAVE_LCD_BITMAP
gui_list->offset_position = 0;
#endif
+ gui_list->last_displayed_selected_item = -1 ;
+ gui_list->last_displayed_start_item = -1 ;
+ gui_list->old_cursor_x = -1 ;
+ gui_list->old_cursor_y = -1 ;
}
void gui_list_set_display(struct gui_list * gui_list, struct screen * display)
@@ -173,12 +182,49 @@
text_pos = 1;
#endif
- gui_textarea_clear(display);
+ //gui_textarea_clear(display);
#ifdef HAVE_LCD_BITMAP
screen_set_xmargin(display, text_pos);
#endif
- for(i = 0;i < display->nb_lines;i++)
+ unsigned long start = USEC_TIMER ; // remove in production code
+ bool optimize = false ; // remove in production code
+ int nsi = gui_list->start_item ;
+ int n ;
+ /* tagcache is sneaky, and reuses the same gui_list for all its lists;
+ * this complicates our pointer check,
+ * and necessitates the default case on the button switch in gui_synclist_do_button
+ */
+ if( gui_list == last_list_displayed && nsi == gui_list->last_displayed_start_item ) {
+ optimize = true ; // remove in production code
+ n = gui_list->last_displayed_selected_item - nsi ;
+ int m = gui_list->selected_item - nsi ;
+ if( m < n ) {
+ i = m ;
+ ++n ;
+ } else { //if( n > m ) {
+ i = n ;
+ n = m + 1 ;
+ }
+ //~ } else {
+ //~ return ;
+ //~ }
+
+ int old_cursor_x = gui_list->old_cursor_x ;
+ if( old_cursor_x != -1 ) {
+ screen_put_cursorxy(display, old_cursor_x, gui_list->old_cursor_y, false);
+ }
+ } else {
+ gui_textarea_clear(display);
+ i = 0 ;
+ n = display->nb_lines ;
+ gui_list->last_displayed_start_item = nsi ;
+ last_list_displayed = gui_list ;
+ }
+
+ gui_list->last_displayed_selected_item = gui_list->selected_item ;
+
+ for( ; i < n ; ++i )
{
char entry_buffer[MAX_PATH];
unsigned char *entry_name;
@@ -191,6 +237,7 @@
entry_name = gui_list->callback_get_item_name(current_item,
gui_list->data,
entry_buffer);
+
#ifdef HAVE_LCD_BITMAP
/* position the string at the correct offset place */
int item_offset;
@@ -232,8 +279,13 @@
display->puts_scroll(text_pos, i, entry_name);
#endif
- if(draw_cursor)
+ if(draw_cursor) {
screen_put_cursorxy(display, cursor_pos, i, true);
+ gui_list->old_cursor_x = cursor_pos ;
+ gui_list->old_cursor_y = i ;
+ } else {
+ gui_list->old_cursor_x = -1 ;
+ }
}
else
{/* normal item */
@@ -254,6 +306,12 @@
screen_put_iconxy(display, icon_pos, i, icon);
}
}
+
+#ifdef ROCKBOX_HAS_LOGF
+ unsigned long end = USEC_TIMER ; // remove in production code
+ logf( "ld %s %d", optimize ? "o" : "n", end - start ) ; // remove in production code
+#endif
+
#ifdef HAVE_LCD_BITMAP
/* Draw the scrollbar if needed*/
if(draw_scrollbar)
@@ -613,7 +671,11 @@
#ifdef LIST_RC_PREV
case LIST_RC_PREV | BUTTON_REPEAT:
#endif
+#if CONFIG_KEYPAD == IPOD_4G_PAD && !defined(IPOD_MINI)
+ gui_synclist_handle_accel( lists, SCREEN_MAIN, BACKWARD ) ;
+#else
gui_synclist_select_previous(lists);
+#endif
gui_synclist_draw(lists);
yield();
return LIST_PREV;
@@ -629,7 +691,11 @@
case LIST_RC_NEXT | BUTTON_REPEAT:
#endif
+#if CONFIG_KEYPAD == IPOD_4G_PAD && !defined(IPOD_MINI)
+ gui_synclist_handle_accel( lists, SCREEN_MAIN, FORWARD ) ;
+#else
gui_synclist_select_next(lists);
+#endif
gui_synclist_draw(lists);
yield();
return LIST_NEXT;
@@ -700,6 +766,14 @@
yield();
return LIST_PREV;
#endif
+
+ case BUTTON_NONE:
+ return 0 ;
+
+ default:
+ last_list_displayed = 0 ;
+ return 0 ;
}
+
return 0;
}
Index: apps/gui/list.h
===================================================================
RCS file: /cvsroot/rockbox/apps/gui/list.h,v
retrieving revision 1.19
diff -u -b -r1.19 list.h
--- apps/gui/list.h 22 Jun 2006 06:38:57 -0000 1.19
+++ apps/gui/list.h 24 Jun 2006 15:11:25 -0000
@@ -5,7 +5,7 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
- * $Id: list.h,v 1.19 2006-06-22 06:38:57 amiconn Exp $
+ * $Id: list.h,v 1.18 2006-04-03 08:51:08 bger Exp $
*
* Copyright (C) 2005 by Kevin Ferrare
*
@@ -53,15 +53,19 @@
#define LIST_PGRIGHT (BUTTON_ON | BUTTON_RIGHT)
#define LIST_PGLEFT (BUTTON_ON | BUTTON_LEFT)
+#ifdef CONFIG_REMOTE_KEYPAD
#define LIST_RC_NEXT BUTTON_RC_RIGHT
#define LIST_RC_PREV BUTTON_RC_LEFT
+#endif /* CONFIG_REMOTE_KEYPAD */
#elif CONFIG_KEYPAD == PLAYER_PAD
#define LIST_NEXT BUTTON_RIGHT
#define LIST_PREV BUTTON_LEFT
+#ifdef CONFIG_REMOTE_KEYPAD
#define LIST_RC_NEXT BUTTON_RC_RIGHT
#define LIST_RC_PREV BUTTON_RC_LEFT
+#endif /* CONFIG_REMOTE_KEYPAD */
#elif CONFIG_KEYPAD == ONDIO_PAD
#define LIST_NEXT BUTTON_DOWN
@@ -149,6 +153,10 @@
bool limit_scroll;
/* The data that will be passed to the callback function YOU implement */
void * data;
+ int last_displayed_selected_item ;
+ int last_displayed_start_item ;
+ int old_cursor_x ;
+ int old_cursor_y ;
};
/*
@@ -282,6 +290,15 @@
int nb_lines);
/*
+ * Advance/retreat in the list by n percent of the total list elements,
+ * by at least one line if percent_lines != 0
+ * - gui_list : the list structure
+ * - percent_lines : the percent of the total number of lines to try to move the cursor
+ * postive adavnces forward, negative retreats back, 0 has no effect
+ */
+extern void gui_list_select_relative_percent( struct gui_list * gui_list,
+ int percent_lines ) ;
+/*
* Adds an item to the list (the callback will be asked for one more item)
* - gui_list : the list structure
*/
Index: apps/gui/statusbar.c
===================================================================
RCS file: /cvsroot/rockbox/apps/gui/statusbar.c,v
retrieving revision 1.26
diff -u -b -r1.26 statusbar.c
--- apps/gui/statusbar.c 21 Jun 2006 18:41:57 -0000 1.26
+++ apps/gui/statusbar.c 24 Jun 2006 15:11:26 -0000
@@ -5,7 +5,7 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
- * $Id: statusbar.c,v 1.26 2006-06-21 18:41:57 amiconn Exp $
+ * $Id: statusbar.c,v 1.25 2006-06-06 22:23:52 amiconn Exp $
*
* Copyright (C) Robert E. Hak (2002), Linus Nielsen Feltzing (2002)
*
@@ -93,6 +93,20 @@
7*ICONS_SPACING
#define STATUSBAR_LOCKR_WIDTH 5
+#if CONFIG_KEYPAD == IPOD_4G_PAD && !defined(IPOD_MINI)
+#define STATUSBAR_SCROLL_ACCEL_X_POS STATUSBAR_X_POS + \
+ STATUSBAR_BATTERY_WIDTH + \
+ STATUSBAR_PLUG_WIDTH + \
+ STATUSBAR_VOLUME_WIDTH + \
+ STATUSBAR_PLAY_STATE_WIDTH + \
+ STATUSBAR_PLAY_MODE_WIDTH + \
+ STATUSBAR_SHUFFLE_WIDTH + \
+ STATUSBAR_LOCKM_WIDTH + \
+ STATUSBAR_LOCKR_WIDTH + \
+ 8*ICONS_SPACING
+#define STATUSBAR_SCROLL_ACCEL_WIDTH 48
+#endif
+
#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
#define STATUSBAR_DISK_WIDTH 12
#define STATUSBAR_DISK_X_POS(statusbar_width) statusbar_width - \
@@ -203,7 +217,14 @@
memcmp(&(bar->info), &(bar->lastinfo), sizeof(struct status_info)))
{
display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+#if CONFIG_KEYPAD == IPOD_4G_PAD && !defined(IPOD_MINI)
+ display->fillrect(0, 0, STATUSBAR_SCROLL_ACCEL_X_POS, STATUSBAR_HEIGHT);
+ display->fillrect(STATUSBAR_SCROLL_ACCEL_X_POS + STATUSBAR_SCROLL_ACCEL_WIDTH, 0,
+ display->width-(STATUSBAR_SCROLL_ACCEL_X_POS + STATUSBAR_SCROLL_ACCEL_WIDTH),
+ STATUSBAR_HEIGHT);
+#else
display->fillrect(0, 0, display->width, STATUSBAR_HEIGHT);
+#endif
display->set_drawmode(DRMODE_SOLID);
#else
@@ -222,12 +243,10 @@
STATUSBAR_PLUG_X_POS,
STATUSBAR_Y_POS, STATUSBAR_PLUG_WIDTH,
STATUSBAR_HEIGHT);
-#endif /* HAVE_USB_POWER */
-#ifdef CONFIG_CHARGING
-#ifdef HAVE_USB_POWER
else
-#endif
+#endif /* HAVE_USB_POWER */
/* draw power plug if charging */
+#ifdef CONFIG_CHARGING
if (bar->info.inserted)
display->mono_bitmap(bitmap_icons_7x8[Icon_Plug],
STATUSBAR_PLUG_X_POS,
@@ -236,7 +255,8 @@
#endif
bar->redraw_volume = gui_statusbar_icon_volume(bar, bar->info.volume);
- gui_statusbar_icon_play_state(display, current_playmode() + Icon_Play);
+ gui_statusbar_icon_play_state(display, current_playmode() +
+ Icon_Play);
switch (bar->info.repeat) {
#if (AB_REPEAT_ENABLE == 1)
@@ -553,6 +573,34 @@
}
#endif
+#if CONFIG_KEYPAD == IPOD_4G_PAD && !defined(IPOD_MINI)
+/*
+ * Print scroll accel to status bar
+ * Note this function is funny; unlike all the others, it's NOT called by gui_statusbar_draw
+ */
+void gui_statusbar_draw_scroll_accel(struct screen* display, int accel, int speed )
+{
+ if(!global_settings.statusbar)
+ return;
+
+ unsigned char buffer[ 10 ];
+ unsigned int width, height;
+ snprintf(buffer, sizeof(buffer), "%d %d", accel, speed );
+ display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+ display->fillrect(STATUSBAR_SCROLL_ACCEL_X_POS, 0,
+ STATUSBAR_SCROLL_ACCEL_WIDTH, STATUSBAR_HEIGHT);
+ display->set_drawmode(DRMODE_SOLID);
+ display->setfont(FONT_SYSFIXED);
+ display->getstringsize(buffer, &width, &height);
+ if (height <= STATUSBAR_HEIGHT) {
+ display->putsxy(STATUSBAR_SCROLL_ACCEL_X_POS, STATUSBAR_Y_POS, buffer);
+ }
+ display->setfont(FONT_UI);
+ display->update_rect( STATUSBAR_SCROLL_ACCEL_X_POS, STATUSBAR_Y_POS,
+ STATUSBAR_SCROLL_ACCEL_WIDTH, STATUSBAR_HEIGHT ) ;
+}
+#endif
+
#endif /* HAVE_LCD_BITMAP */
void gui_syncstatusbar_init(struct gui_syncstatusbar * bars)
Index: apps/gui/statusbar.h
===================================================================
RCS file: /cvsroot/rockbox/apps/gui/statusbar.h,v
retrieving revision 1.16
diff -u -b -r1.16 statusbar.h
--- apps/gui/statusbar.h 6 Jun 2006 22:23:52 -0000 1.16
+++ apps/gui/statusbar.h 24 Jun 2006 15:11:26 -0000
@@ -111,6 +111,16 @@
void gui_statusbar_time(struct screen * display, int hour, int minute);
#endif
+#if CONFIG_KEYPAD == IPOD_4G_PAD && !defined(IPOD_MINI)
+/*
+ * Print scroll accel to status bar
+ * Note this function is funny; unlike all the others, it's NOT called by gui_statusbar_draw
+ * it updtes teh screen on its own,
+ * and it is public so outside clients can call it
+ */
+extern void gui_statusbar_draw_scroll_accel(struct screen* display, int accel, int speed ) ;
+#endif
+
struct gui_syncstatusbar
{
Index: apps/lang/english.lang
===================================================================
RCS file: /cvsroot/rockbox/apps/lang/english.lang,v
retrieving revision 1.252
diff -u -b -r1.252 english.lang
--- apps/lang/english.lang 25 May 2006 13:34:51 -0000 1.252
+++ apps/lang/english.lang 24 Jun 2006 15:11:29 -0000
@@ -8529,3 +8529,59 @@
*: "Remote Scrolling Options"
+
+ id: LANG_IPOD_SCROLL_WHEEL_SPEED
+ desc: "Ipod Scroll Wheel Acceleration By Speed" Submenu in "System" menu
+ user:
+
+ *: "Ipod Scroll Wheel Acceleration"
+
+
+ *: "Ipod Scroll Wheel Acceleration"
+
+
+ *: "Ipod Scroll Wheel Acceleration"
+
+
+
+ id: LANG_IPOD_SCROLL_WHEEL_FAST
+ desc: "Ipod Scroll Wheel By Speed Fast Threshold" Submenu in "Ipod Scroll Wheel Acceleration By Speed" menu
+ user:
+
+ *: "Minimum speed for 'fast' acceleration"
+
+
+ *: "Minimum speed for 'fast' acceleration"
+
+
+ *: "Minimum speed for 'fast' acceleration"
+
+
+
+ id: LANG_IPOD_SCROLL_WHEEL_FASTER
+ desc: "Ipod Scroll Wheel By Speed Faster Threshold" Submenu in "Ipod Scroll Wheel Acceleration By Speed" menu
+ user:
+
+ *: "Minimum speed for 'faster' acceleration"
+
+
+ *: "Minimum speed for 'faster' acceleration"
+
+
+ *: "Minimum speed for 'faster' acceleration"
+
+
+
+ id: LANG_IPOD_SCROLL_WHEEL_FASTEST
+ desc: "Ipod Scroll Wheel By Speed Fastest Threshold" Submenu in "Ipod Scroll Wheel Acceleration By Speed" menu
+ user:
+
+ *: "Minimum speed for 'fastest' acceleration"
+
+
+ *: "Minimum speed for 'fastest' acceleration"
+
+
+ *: "Minimum speed for 'fastest' acceleration"
+
+
Index: firmware/drivers/button.c
===================================================================
RCS file: /cvsroot/rockbox/firmware/drivers/button.c,v
retrieving revision 1.143
diff -u -b -r1.143 button.c
--- firmware/drivers/button.c 6 Jun 2006 22:23:41 -0000 1.143
+++ firmware/drivers/button.c 24 Jun 2006 15:11:31 -0000
@@ -39,6 +39,7 @@
#include "power.h"
#include "system.h"
#include "powermgmt.h"
+#include "logf.h"
#ifdef HAVE_REMOTE_LCD
#include "lcd-remote.h"
@@ -86,12 +87,38 @@
static bool remote_button_hold_only(void);
#endif
-#if CONFIG_KEYPAD == IPOD_4G_PAD
+#if CONFIG_KEYPAD == IPOD_4G_PAD && !defined(IPOD_MINI)
/* Variable to use for setting button status in interrupt handler */
int int_btn = BUTTON_NONE;
+
+void ipod_4g_button_int( void ) ;
+
+static int accumulated_wheel_scroll_delta = 0 ;
+unsigned long wheel_scroll_down_microsecond_tick = 0 ;
+unsigned long wheel_scroll_key_microsecond_tick = 0 ;
+unsigned long wheel_scroll_key_microsecond_tick_elapsed = 0 ;
+const unsigned long ONE_MILLION = 1000000 ;
+
+int get_accumulated_wheel_scroll_delta( void ) {
+ return accumulated_wheel_scroll_delta ;
+}
+
+int get_ipod_scroll_wheel_clicks_per_second( void ) {
+ unsigned long wst = wheel_scroll_key_microsecond_tick ;
+ int accum = accumulated_wheel_scroll_delta ;
+ unsigned int abs_accum = accum < 0 ? -accum : accum ;
+ unsigned long wste = wheel_scroll_key_microsecond_tick_elapsed ;
+ if( wste == wst ) wst = wheel_scroll_down_microsecond_tick ;
+ unsigned long diff = wste - wst ;
+ unsigned int r = diff ? ( ( abs_accum * ONE_MILLION ) / diff ) : 0 ;
+#ifdef ROCKBOX_HAS_LOGF
+ logf( "d1,%d,%d", wst, wste ) ;
+ logf( "d2,%d,%d,%d", diff, accum, r ) ;
#endif
+ return accum < 0 ? -r : r ;
+}
+
-#if (CONFIG_KEYPAD == IPOD_4G_PAD) && !defined(IPOD_MINI)
static void opto_i2c_init(void)
{
int i, curr_value;
@@ -156,37 +183,58 @@
/* NB: highest wheel = 0x5F, clockwise increases */
int new_wheel_value = (status << 9) >> 25;
backlight_on();
+
+ if( old_wheel_value == -1 ) {
+ /* -1 is a sentinal value, meaning there is no old value
+ * because the finger was lifted and thus, no key to emit
+ */
+ old_wheel_value = new_wheel_value ;
+ accumulated_wheel_scroll_delta = 0 ;
+ wheel_scroll_down_microsecond_tick = USEC_TIMER ;
+
+ } else {
+ /* calculate the delta regardless of whether we'll add a key
+ * for the use of the acceleration fucntion
+ */
/* The queue should have no other events when scrolling */
- if (queue_empty(&button_queue) && old_wheel_value >= 0) {
/* This is for later = BUTTON_SCROLL_TOUCH;*/
int wheel_delta = new_wheel_value - old_wheel_value;
- unsigned long data;
- int wheel_keycode;
if (wheel_delta < -48)
wheel_delta += 96; /* Forward wrapping case */
else if (wheel_delta > 48)
wheel_delta -= 96; /* Backward wrapping case */
- if (wheel_delta > 4) {
- wheel_keycode = BUTTON_SCROLL_FWD;
- } else if (wheel_delta < -4) {
- wheel_keycode = BUTTON_SCROLL_BACK;
- } else goto wheel_end;
+ if( wheel_delta > 4 || wheel_delta < -4 ) {
+ /* ignore anything less than a jiggle factor */
- data = (wheel_delta << 16) | new_wheel_value;
- queue_post(&button_queue, wheel_keycode | wheel_repeat,
- (void *)data);
+ if ( queue_empty(&button_queue) ) {
+ /* only post a scroll button if the queue is empty */
+ int wheel_keycode = wheel_delta > 0 ? BUTTON_SCROLL_FWD : BUTTON_SCROLL_BACK ;
+ unsigned long data = (wheel_delta << 16) | new_wheel_value;
+ wheel_scroll_key_microsecond_tick = wheel_scroll_key_microsecond_tick_elapsed ;
+ accumulated_wheel_scroll_delta = 0 ;
+ queue_post(&button_queue, wheel_keycode | wheel_repeat, (void *)data);
if (!wheel_repeat) wheel_repeat = BUTTON_REPEAT;
}
- old_wheel_value = new_wheel_value;
+ accumulated_wheel_scroll_delta += wheel_delta ;
+ old_wheel_value = new_wheel_value ;
+ wheel_scroll_key_microsecond_tick_elapsed = USEC_TIMER ;
+
+ } else goto wheel_end ; /* not clear this is still needed, basically skips call to opto_i2c_init() */
+ }
+
} else if (old_wheel_value >= 0) {
/* scroll wheel up */
old_wheel_value = -1;
wheel_repeat = 0;
+ accumulated_wheel_scroll_delta = 0 ;
+ wheel_scroll_down_microsecond_tick = 0 ;
+ wheel_scroll_key_microsecond_tick = 0 ;
+ wheel_scroll_key_microsecond_tick_elapsed = 0 ;
}
} else if (status == 0xffffffff) {
@@ -211,6 +259,7 @@
udelay(50);
outl(0x0, 0x7000c140);
int_btn = ipod_4g_button_read();
+
outl(inl(0x7000c104) | 0xC000000, 0x7000c104);
outl(0x400a1f00, 0x7000c100);
Index: firmware/export/button.h
===================================================================
RCS file: /cvsroot/rockbox/firmware/export/button.h,v
retrieving revision 1.50
diff -u -b -r1.50 button.h
--- firmware/export/button.h 26 Mar 2006 22:20:27 -0000 1.50
+++ firmware/export/button.h 24 Jun 2006 15:11:31 -0000
@@ -33,7 +33,7 @@
#define HAS_BUTTON_HOLD
#endif
extern struct event_queue button_queue;
-
+extern unsigned long wheel_scroll_tick ;
void button_init (void);
long button_get (bool block);
long button_get_w_tmo(int ticks);
@@ -233,6 +233,21 @@
#define BUTTON_REMOTE 0
+#if (CONFIG_KEYPAD == IPOD_4G_PAD)
+extern int get_accumulated_wheel_scroll_delta( void ) ;
+extern int get_ipod_scroll_wheel_clicks_per_second( void ) ;
+//enum wheel_acceleration { ACCEL_NONE, ACCEL_FAST, ACCEL_FASTER, ACCEL_FASTEST } ;
+//extern enum wheel_acceleration get_ipod_scroll_wheel_acceration( unsigned int* pq1, unsigned int* pq1a ) ;
+/* warning to clients calling get_ipod_scroll_wheel_acceration:
+ * Calling this function may have side-effects;
+ * this function should be called once per call to button_get
+ * or button_get_w_tmo, and results locally cached as needed.
+ * In particular, some acceleration implementations
+ * may need to reset a calculated delta when
+ * get_ipod_scroll_wheel_acceration is called.
+ */
+#endif
+
/* This is for later
#define BUTTON_SCROLL_TOUCH 0x00000200
*/