static int boot_menu(void) { const char* strings[] = {"Boot Rockbox", "Boot OF", "USB mode", "Reset Rockbox configuration"}; int button, touch, poweroff_repeat = 0; unsigned int i; verbose = true; adc_init(); redraw: lcd_clear_display(); for(i=0; i<ARRAYLEN(strings); i++) { lcd_drawrect(RECT_X, RECT_Y(i), RECT_WIDTH, RECT_HEIGHT); lcd_putsxy(TEXT_X(i), TEXT_Y(i), strings[i]); } lcd_update(); while(1) { button = button_get_w_tmo(HZ/4); if(button & BUTTON_TOUCHSCREEN) { touch = button_get_data(); unsigned int x = touch & 0xFFFF, y = touch >> 16; int found = -1; for(i=0; i<ARRAYLEN(strings); i++) { if(x > RECT_X && x < RECT_X+RECT_WIDTH && y > RECT_Y(i) && y < RECT_Y(i)+RECT_HEIGHT) { found = i; break; } } switch(found) { case 0: reset_screen(); boot_rockbox(); break; case 1: reset_screen(); boot_of(); break; case 2: usb_mode(); break; case 3: reset_configuration(); break; } if(found != -1) goto redraw; } else if(button & BUTTON_POWER)
/* return BUTTON_NONE on error * BUTTON_REPEAT if repeated press * BUTTON_REPEAT|BUTTON_REL if release after repeated press * BUTTON_REL if it's a short press = release after press * BUTTON_TOUCHSCREEN if press */ int action_get_touchscreen_press(short *x, short *y) { static int last_data = 0; int data; if ((last_button & BUTTON_TOUCHSCREEN) == 0) return BUTTON_NONE; data = button_get_data(); if (last_button & BUTTON_REL) { *x = (last_data&0xffff0000)>>16; *y = (last_data&0xffff); }
void display_logf(void) /* Doesn't return! */ { int i, index, button, user_index=0; #ifdef HAVE_TOUCHSCREEN int touch, prev_y=0; #endif char buffer[COLUMNS+1]; while(1) { index = logfindex + user_index; lcd_clear_display(); for(i = LINES-1; i>=0; i--) { if(--index < 0) { if(logfwrap) index = MAX_LOGF_LINES-1; else break; /* done */ } memcpy(buffer, logfbuffer[index], COLUMNS); if (logfbuffer[index][MAX_LOGF_ENTRY] == LOGF_TERMINATE_CONTINUE_LINE) buffer[MAX_LOGF_ENTRY-1] = '>'; else if (logfbuffer[index][MAX_LOGF_ENTRY] == LOGF_TERMINATE_MULTI_LINE) buffer[MAX_LOGF_ENTRY-1] = '\0'; buffer[COLUMNS] = '\0'; lcd_puts(0, i, buffer); } button = button_get(false); if(button == SYS_USB_CONNECTED) usb_acknowledge(SYS_USB_CONNECTED_ACK); else if(button == SYS_USB_DISCONNECTED) ; else if(button & LOGF_UP) user_index++; else if(button & LOGF_DOWN) user_index--; else if(button & LOGF_CLEAR) user_index = 0; #ifdef HAVE_TOUCHSCREEN else if(button & BUTTON_TOUCHSCREEN) { touch = button_get_data(); if(button & BUTTON_REL) prev_y = 0; if(prev_y != 0) user_index += (prev_y - (touch & 0xFFFF)) / SYSFONT_HEIGHT; prev_y = touch & 0xFFFF; } #endif lcd_update(); sleep(HZ/16); } }
/* * int get_action_worker(int context, struct button_mapping *user_mappings, int timeout) This function searches the button list for the given context for the just pressed button. If there is a match it returns the value from the list. If there is no match.. the last item in the list "points" to the next context in a chain so the "chain" is followed until the button is found. putting ACTION_NONE will get CONTEXT_STD which is always the last list checked. Timeout can be TIMEOUT_NOBLOCK to return immediatly TIMEOUT_BLOCK to wait for a button press Any number >0 to wait that many ticks for a press */ static int get_action_worker(int context, int timeout, const struct button_mapping* (*get_context_map)(int) ) { const struct button_mapping *items = NULL; int button; int i=0; int ret = ACTION_UNKNOWN; static int last_context = CONTEXT_STD; send_event(GUI_EVENT_ACTIONUPDATE, NULL); if (timeout == TIMEOUT_NOBLOCK) button = button_get(false); else if (timeout == TIMEOUT_BLOCK) button = button_get(true); else button = button_get_w_tmo(timeout); #if defined(HAVE_GUI_BOOST) && defined(HAVE_ADJUSTABLE_CPU_FREQ) static struct timeout gui_unboost; /* Boost the CPU in case of wheel scrolling activity in the defined contexts. * Call unboost with a timeout of GUI_BOOST_TIMEOUT. */ if ((button&(BUTTON_SCROLL_BACK|BUTTON_SCROLL_FWD)) && (context == CONTEXT_STD || context == CONTEXT_LIST || context == CONTEXT_MAINMENU || context == CONTEXT_TREE)) { gui_boost(true); timeout_register(&gui_unboost, gui_unboost_callback, GUI_BOOST_TIMEOUT, 0); } #endif /* Data from sys events can be pulled with button_get_data * multimedia button presses don't go through the action system */ if (button == BUTTON_NONE || button & (SYS_EVENT|BUTTON_MULTIMEDIA)) return button; /* Don't send any buttons through untill we see the release event */ if (wait_for_release) { if (button&BUTTON_REL) { /* remember the button for the below button eating on context * change */ last_button = button; wait_for_release = false; } return ACTION_NONE; } #if CONFIG_CODEC == SWCODEC /* Produce keyclick */ keyclick_click(button); #endif if ((context != last_context) && ((last_button & BUTTON_REL) == 0) #ifdef HAVE_SCROLLWHEEL /* Scrollwheel doesn't generate release events */ && !(last_button & (BUTTON_SCROLL_BACK | BUTTON_SCROLL_FWD)) #endif ) { if (button & BUTTON_REL) { last_button = button; last_action = ACTION_NONE; } /* eat all buttons until the previous button was |BUTTON_REL (also eat the |BUTTON_REL button) */ return ACTION_NONE; /* "safest" return value */ } last_context = context; #ifndef HAS_BUTTON_HOLD screen_has_lock = ((context & ALLOW_SOFTLOCK) == ALLOW_SOFTLOCK); if (screen_has_lock && keys_locked) { if (button == unlock_combo) { last_button = BUTTON_NONE; keys_locked = false; splash(HZ/2, str(LANG_KEYLOCK_OFF)); return ACTION_REDRAW; } else #if (BUTTON_REMOTE != 0) if ((button & BUTTON_REMOTE) == 0) #endif { if ((button & BUTTON_REL)) splash(HZ/2, str(LANG_KEYLOCK_ON)); return ACTION_REDRAW; } } context &= ~ALLOW_SOFTLOCK; #endif /* HAS_BUTTON_HOLD */ #ifdef HAVE_TOUCHSCREEN if (button & BUTTON_TOUCHSCREEN) { repeated = false; short_press = false; if (last_button & BUTTON_TOUCHSCREEN) { if ((button & BUTTON_REL) && ((last_button & BUTTON_REPEAT)==0)) { short_press = true; } else if (button & BUTTON_REPEAT) repeated = true; } last_button = button; return ACTION_TOUCHSCREEN; } #endif #if defined(HAVE_LCD_BITMAP) && !defined(BOOTLOADER) button = button_flip_horizontally(context, button); #endif /* logf("%x,%x",last_button,button); */ while (1) { /* logf("context = %x",context); */ #if (BUTTON_REMOTE != 0) if (button & BUTTON_REMOTE) context |= CONTEXT_REMOTE; #endif if ((context & CONTEXT_PLUGIN) && get_context_map) items = get_context_map(context); else items = get_context_mapping(context); if (items == NULL) break; ret = do_button_check(items,button,last_button,&i); if (ret == ACTION_UNKNOWN) { context = get_next_context(items,i); if (context != (int)CONTEXT_STOPSEARCHING) { i = 0; continue; } } /* Action was found or STOPSEARCHING was specified */ break; } /* DEBUGF("ret = %x\n",ret); */ #ifndef HAS_BUTTON_HOLD if (screen_has_lock && (ret == ACTION_STD_KEYLOCK)) { unlock_combo = button; keys_locked = true; splash(HZ/2, str(LANG_KEYLOCK_ON)); button_clear_queue(); return ACTION_REDRAW; } #endif if ((current_tick - last_action_tick < REPEAT_WINDOW_TICKS) && (ret == last_action)) repeated = true; else repeated = false; last_button = button; last_action = ret; last_data = button_get_data(); last_action_tick = current_tick; return ret; }
/* * int get_action_worker(int context, struct button_mapping *user_mappings, int timeout) This function searches the button list for the given context for the just pressed button. If there is a match it returns the value from the list. If there is no match.. the last item in the list "points" to the next context in a chain so the "chain" is followed until the button is found. putting ACTION_NONE will get CONTEXT_STD which is always the last list checked. Timeout can be TIMEOUT_NOBLOCK to return immediatly TIMEOUT_BLOCK to wait for a button press Any number >0 to wait that many ticks for a press */ static int get_action_worker(int context, int timeout, const struct button_mapping* (*get_context_map)(int) ) { const struct button_mapping *items = NULL; int button; int i=0; int ret = ACTION_UNKNOWN; static int last_context = CONTEXT_STD; send_event(GUI_EVENT_ACTIONUPDATE, NULL); if (timeout == TIMEOUT_NOBLOCK) button = button_get(false); else if (timeout == TIMEOUT_BLOCK) button = button_get(true); else button = button_get_w_tmo(timeout); #if defined(HAVE_GUI_BOOST) && defined(HAVE_ADJUSTABLE_CPU_FREQ) static struct timeout gui_unboost; /* Boost the CPU in case of wheel scrolling activity in the defined contexts. * Call unboost with a timeout of GUI_BOOST_TIMEOUT. */ if ((button&(BUTTON_SCROLL_BACK|BUTTON_SCROLL_FWD)) && (context == CONTEXT_STD || context == CONTEXT_LIST || context == CONTEXT_MAINMENU || context == CONTEXT_TREE)) { gui_boost(true); timeout_register(&gui_unboost, gui_unboost_callback, GUI_BOOST_TIMEOUT, 0); } #endif /* Data from sys events can be pulled with button_get_data * multimedia button presses don't go through the action system */ if (button == BUTTON_NONE || button & (SYS_EVENT|BUTTON_MULTIMEDIA)) { /* no button pressed so no point in waiting for release */ if (button == BUTTON_NONE) wait_for_release = false; return button; } /* the special redraw button should result in a screen refresh */ if (button == BUTTON_REDRAW) return ACTION_REDRAW; /* if action_wait_for_release() was called without a button being pressed * then actually waiting for release would do the wrong thing, i.e. * the next key press is entirely ignored. So, if here comes a normal * button press (neither release nor repeat) the press is a fresh one and * no point in waiting for release * * This logic doesn't work for touchscreen which can send normal * button events repeatedly before the first repeat (as in BUTTON_REPEAT). * These cannot be distinguished from the very first touch * but there's nothing we can do about it here */ if ((button & (BUTTON_REPEAT|BUTTON_REL)) == 0) wait_for_release = false; /* Don't send any buttons through untill we see the release event */ if (wait_for_release) { if (button&BUTTON_REL) { /* remember the button for the below button eating on context * change */ last_button = button; wait_for_release = false; } return ACTION_NONE; } if ((context != last_context) && ((last_button & BUTTON_REL) == 0) #ifdef HAVE_SCROLLWHEEL /* Scrollwheel doesn't generate release events */ && !(last_button & (BUTTON_SCROLL_BACK | BUTTON_SCROLL_FWD)) #endif ) { if (button & BUTTON_REL) { last_button = button; last_action = ACTION_NONE; } /* eat all buttons until the previous button was |BUTTON_REL (also eat the |BUTTON_REL button) */ return ACTION_NONE; /* "safest" return value */ } last_context = context; #ifndef HAS_BUTTON_HOLD screen_has_lock = ((context & ALLOW_SOFTLOCK) == ALLOW_SOFTLOCK); if (is_keys_locked()) { if (button == unlock_combo) { last_button = BUTTON_NONE; keys_locked = false; #if defined(HAVE_TOUCHPAD) || defined(HAVE_TOUCHSCREEN) /* enable back touch device */ button_enable_touch(true); #endif splash(HZ/2, str(LANG_KEYLOCK_OFF)); return ACTION_REDRAW; } else #if (BUTTON_REMOTE != 0) if ((button & BUTTON_REMOTE) == 0) #endif { if ((button & BUTTON_REL)) splash(HZ/2, str(LANG_KEYLOCK_ON)); return ACTION_REDRAW; } } #if defined(HAVE_TOUCHPAD) || defined(HAVE_TOUCHSCREEN) else { /* make sure touchpad get reactivated if we quit the screen */ button_enable_touch(true); } #endif context &= ~ALLOW_SOFTLOCK; #endif /* HAS_BUTTON_HOLD */ #ifdef HAVE_TOUCHSCREEN if (button & BUTTON_TOUCHSCREEN) { repeated = false; short_press = false; if (last_button & BUTTON_TOUCHSCREEN) { if ((button & BUTTON_REL) && ((last_button & BUTTON_REPEAT)==0)) { short_press = true; } else if (button & BUTTON_REPEAT) repeated = true; } last_button = button; return ACTION_TOUCHSCREEN; } #endif #if defined(HAVE_LCD_BITMAP) && !defined(BOOTLOADER) button = button_flip_horizontally(context, button); #endif /* logf("%x,%x",last_button,button); */ while (1) { /* logf("context = %x",context); */ #if (BUTTON_REMOTE != 0) if (button & BUTTON_REMOTE) context |= CONTEXT_REMOTE; #endif if ((context & CONTEXT_PLUGIN) && get_context_map) items = get_context_map(context); else items = get_context_mapping(context); if (items == NULL) break; ret = do_button_check(items,button,last_button,&i); if (ret == ACTION_UNKNOWN) { context = get_next_context(items,i); if (context != (int)CONTEXT_STOPSEARCHING) { i = 0; continue; } } /* Action was found or STOPSEARCHING was specified */ break; } /* DEBUGF("ret = %x\n",ret); */ #ifndef HAS_BUTTON_HOLD if (screen_has_lock && (ret == ACTION_STD_KEYLOCK)) { unlock_combo = button; keys_locked = true; splash(HZ/2, str(LANG_KEYLOCK_ON)); #if defined(HAVE_TOUCHPAD) || defined(HAVE_TOUCHSCREEN) /* disable touch device on keylock */ button_enable_touch(false); #endif button_clear_queue(); return ACTION_REDRAW; } #endif if ((current_tick - last_action_tick < REPEAT_WINDOW_TICKS) && (ret == last_action)) repeated = true; else repeated = false; last_button = button; last_action = ret; last_data = button_get_data(); last_action_tick = current_tick; #if CONFIG_CODEC == SWCODEC /* Produce keyclick */ keyclick_click(false, ret); #endif return ret; }