static int iTCO_wdt_set_heartbeat(int t) { unsigned int val16; unsigned int tmrval; tmrval = seconds_to_ticks(t); /* For TCO v1 the timer counts down twice before rebooting */ /* from the specs: */ /* "Values of 0h-1h are ignored and should not be attempted" */ if (tmrval < 0x02) return -EINVAL; /* Write new heartbeat to watchdog */ spin_lock(&iTCO_wdt_private.io_lock); val16 = inw(TCOv2_TMR); val16 &= 0xfc00; val16 |= tmrval; outw(val16, TCOv2_TMR); val16 = inw(TCOv2_TMR); spin_unlock(&iTCO_wdt_private.io_lock); if ((val16 & 0x3ff) != tmrval) return -EINVAL; heartbeat = t; return 0; }
static int iTCO_wdt_set_heartbeat(int t) { unsigned int val16; unsigned char val8; unsigned int tmrval; tmrval = seconds_to_ticks(t); /* For TCO v1 the timer counts down twice before rebooting */ if (iTCO_wdt_private.iTCO_version == 1) tmrval /= 2; /* from the specs: */ /* "Values of 0h-3h are ignored and should not be attempted" */ if (tmrval < 0x04) return -EINVAL; if (((iTCO_wdt_private.iTCO_version == 2) && (tmrval > 0x3ff)) || ((iTCO_wdt_private.iTCO_version == 1) && (tmrval > 0x03f))) return -EINVAL; iTCO_vendor_pre_set_heartbeat(tmrval); /* Write new heartbeat to watchdog */ if (iTCO_wdt_private.iTCO_version == 2) { spin_lock(&iTCO_wdt_private.io_lock); val16 = inw(TCOv2_TMR); val16 &= 0xfc00; val16 |= tmrval; outw(val16, TCOv2_TMR); val16 = inw(TCOv2_TMR); spin_unlock(&iTCO_wdt_private.io_lock); if ((val16 & 0x3ff) != tmrval) return -EINVAL; } else if (iTCO_wdt_private.iTCO_version == 1) { spin_lock(&iTCO_wdt_private.io_lock); val8 = inb(TCOv1_TMR); val8 &= 0xc0; val8 |= (tmrval & 0xff); outb(val8, TCOv1_TMR); val8 = inb(TCOv1_TMR); spin_unlock(&iTCO_wdt_private.io_lock); if ((val8 & 0x3f) != tmrval) return -EINVAL; } heartbeat = t; return 0; }
static int tco_timer_set_heartbeat(int t) { int ret = 0; unsigned char tmrval; unsigned long flags; u8 val; /* * note seconds_to_ticks(t) > t, so if t > 0x3f, so is * tmrval=seconds_to_ticks(t). Check that the count in seconds isn't * out of range on it's own (to avoid overflow in tmrval). */ if (t < 0 || t > 0x3f) return -EINVAL; tmrval = seconds_to_ticks(t); /* "Values of 0h-3h are ignored and should not be attempted" */ if (tmrval > 0x3f || tmrval < 0x04) return -EINVAL; /* Write new heartbeat to watchdog */ spin_lock_irqsave(&tco_lock, flags); val = inb(TCO_TMR(tcobase)); val &= 0xc0; val |= tmrval; outb(val, TCO_TMR(tcobase)); val = inb(TCO_TMR(tcobase)); if ((val & 0x3f) != tmrval) ret = -EINVAL; spin_unlock_irqrestore(&tco_lock, flags); if (ret) return ret; heartbeat = t; return 0; }
int wikilib_run(void) { int sleep; long time_now; struct wl_input_event ev; int more_events = 0; unsigned long last_event_time = 0; int rc; /* * test searching code... */ article_buf_pointer = NULL; search_init(); history_list_init(); malloc_status_simple(); print_intro(); #ifndef INCLUDED_FROM_KERNEL if (!load_init_article(idx_init_article)) { display_mode = DISPLAY_MODE_ARTICLE; last_display_mode = DISPLAY_MODE_INDEX; } #endif render_string(SUBTITLE_FONT_IDX, -1, 55, MESSAGE_TYPE_A_WORD, strlen(MESSAGE_TYPE_A_WORD), 0); for (;;) { if (more_events) sleep = 0; else sleep = 1; if (!more_events && display_mode == DISPLAY_MODE_ARTICLE && render_article_with_pcf()) sleep = 0; else if (!more_events && display_mode == DISPLAY_MODE_INDEX && render_search_result_with_pcf()) sleep = 0; else if (!more_events && display_mode == DISPLAY_MODE_HISTORY && render_history_with_pcf()) sleep = 0; if (finger_move_speed != 0) { scroll_article(); sleep = 0; } #ifdef INCLUDED_FROM_KERNEL time_now = get_time_ticks(); if(display_mode == DISPLAY_MODE_INDEX) { if (press_delete_button && get_search_string_len()>0) { sleep = 0; if(time_diff(time_now, start_search_time) > seconds_to_ticks(3.5)) { if (!clear_search_string()) { search_string_changed_remove = true; search_reload_ex(SEARCH_RELOAD_NORMAL); } press_delete_button = false; } else if (time_diff(time_now, start_search_time) > seconds_to_ticks(0.5) && time_diff(time_now, last_delete_time) > seconds_to_ticks(0.25)) { if (!search_remove_char(0)) { search_string_changed_remove = true; search_reload_ex(SEARCH_RELOAD_NO_POPULATE); } last_delete_time = time_now; } } } else if (display_mode == DISPLAY_MODE_RESTRICTED) { if (press_delete_button && get_password_string_len()>0) { sleep = 0; time_now = get_time_ticks(); if(time_diff(time_now, start_search_time) > seconds_to_ticks(3.5)) { clear_password_string(); press_delete_button = false; } else if (time_diff(time_now, start_search_time) > seconds_to_ticks(0.5) && time_diff(time_now, last_delete_time) > seconds_to_ticks(0.25)) { password_remove_char(); last_delete_time = time_now; } } } #endif if (!more_events && display_mode == DISPLAY_MODE_INDEX && fetch_search_result(0, 0, 0)) { sleep = 0; } if (keyboard_key_reset_invert(KEYBOARD_RESET_INVERT_CHECK)) // check if need to reset invert sleep = 0; if (check_invert_link()) // check if need to invert link sleep = 0; if (sleep) { if (time_diff(get_time_ticks(), last_event_time) > seconds_to_ticks(15)) rc = history_list_save(HISTORY_SAVE_POWER_OFF); else rc = history_list_save(HISTORY_SAVE_NORMAL); if (rc > 0) { #ifdef INCLUDED_FROM_KERNEL delay_us(200000); // for some reason, save may not work if no delay #endif } else if (rc < 0) sleep = 0; // waiting for last_event_time timeout to save the history } wl_input_wait(&ev, sleep); more_events = 1; switch (ev.type) { case WL_INPUT_EV_TYPE_CURSOR: handle_cursor(&ev); last_event_time = get_time_ticks(); break; case WL_INPUT_EV_TYPE_KEYBOARD: if (ev.key_event.value != 0) { b_show_scroll_bar = 0; handle_key_release(ev.key_event.keycode); } last_event_time = get_time_ticks(); break; case WL_INPUT_EV_TYPE_TOUCH: handle_touch(&ev); last_event_time = ev.touch_event.ticks; break; default: more_events = 0; break; } } /* never reached */ return 0; }
static void handle_touch(struct wl_input_event *ev) { //int offset,offset_count, int article_link_number=-1; int enter_touch_y_pos_record; //int time_diff_search; int mode; struct keyboard_key * key; static int last_5_y[5]; static unsigned long last_5_y_time_ticks[5]; int i; DP(DBG_WL, ("%s() touch event @%d,%d val %d\n", __func__, ev->touch_event.x, ev->touch_event.y, ev->touch_event.value)); mode = keyboard_get_mode(); if (display_mode == DISPLAY_MODE_INDEX && (mode == KEYBOARD_CHAR || mode == KEYBOARD_NUM)) { article_buf_pointer = NULL; key = keyboard_get_data(ev->touch_event.x, ev->touch_event.y); if (ev->touch_event.value == 0) { keyboard_key_reset_invert(KEYBOARD_RESET_INVERT_DELAY); // reset invert with delay enter_touch_y_pos_record = enter_touch_y_pos; enter_touch_y_pos = -1; touch_search = 0; press_delete_button = false; pre_key = NULL; if (key) { if (!touch_down_on_keyboard) { touch_down_on_keyboard = 0; touch_down_on_list = 0; goto out; } handle_search_key(key->key); } else { if (!touch_down_on_list || ev->touch_event.y < RESULT_START - RESULT_HEIGHT) { touch_down_on_keyboard = 0; touch_down_on_list = 0; goto out; } if(search_result_count()==0) goto out; //search_set_selection(last_selection); //search_open_article(last_selection); if(search_result_selected()>=0) { display_mode = DISPLAY_MODE_ARTICLE; last_display_mode = DISPLAY_MODE_INDEX; search_open_article(search_result_selected()); } } touch_down_on_keyboard = 0; touch_down_on_list = 0; } else { if(enter_touch_y_pos<0) //record first touch y pos enter_touch_y_pos = ev->touch_event.y; last_index_y_pos = ev->touch_event.y; start_search_time = ev->touch_event.ticks; last_delete_time = start_search_time; if (key) { if(key->key==8)//press "<" button { press_delete_button = true; } else if(key->key == -42) { mode = keyboard_get_mode(); if(mode == KEYBOARD_CHAR) keyboard_set_mode(KEYBOARD_NUM); else if(mode == KEYBOARD_NUM) keyboard_set_mode(KEYBOARD_CHAR); guilib_fb_lock(); keyboard_paint(); guilib_fb_unlock(); } if (!touch_down_on_keyboard && !touch_down_on_list) touch_down_on_keyboard = 1; if (pre_key && pre_key->key == key->key) goto out; if (touch_down_on_keyboard) { keyboard_key_invert(key); pre_key = key; } } else { if (!touch_down_on_keyboard && !touch_down_on_list) touch_down_on_list = 1; keyboard_key_reset_invert(KEYBOARD_RESET_INVERT_DELAY); // reset invert with delay pre_key = NULL; if (!search_result_count()) goto out; if(touch_search == 0) { //last_search_y_pos = ev->touch_event.y; touch_search = 1; } else { if(search_result_selected()>=0 && abs(ev->touch_event.y-search_touch_pos_y_last)>5) { invert_selection(search_result_selected(),-1, RESULT_START, RESULT_HEIGHT); search_set_selection(-1); } goto out; } int new_selection; if((ev->touch_event.y - RESULT_START)<0) new_selection = -1; else new_selection = ((unsigned int)ev->touch_event.y - RESULT_START) / RESULT_HEIGHT; if (new_selection == search_result_selected()) goto out; unsigned int avail_count = keyboard_get_mode() == KEYBOARD_NONE ? NUMBER_OF_FIRST_PAGE_RESULTS : NUMBER_OF_RESULTS_KEYBOARD; avail_count = search_result_count() > avail_count ? avail_count : search_result_count(); if (new_selection >= avail_count) goto out; if (touch_down_on_keyboard) goto out; //invert_selection(search_result_selected(), new_selection, RESULT_START, RESULT_HEIGHT); invert_selection(-1, new_selection, RESULT_START, RESULT_HEIGHT); last_selection = new_selection ; search_set_selection(new_selection); search_touch_pos_y_last = ev->touch_event.y; } } } else if (display_mode == DISPLAY_MODE_HISTORY && mode == KEYBOARD_CLEAR_HISTORY) { key = keyboard_get_data(ev->touch_event.x, ev->touch_event.y); if (ev->touch_event.value == 0) { #ifdef INCLUDED_FROM_KERNEL delay_us(100000 * 2); #endif keyboard_key_reset_invert(KEYBOARD_RESET_INVERT_NOW); enter_touch_y_pos_record = enter_touch_y_pos; enter_touch_y_pos = -1; touch_search = 0; press_delete_button = false; pre_key = NULL; if (key) { if (!touch_down_on_keyboard) { touch_down_on_keyboard = 0; touch_down_on_list = 0; goto out; } if (key->key == 'Y') { history_clear(); keyboard_set_mode(KEYBOARD_NONE); history_reload(); } else if (key->key == 'N') { keyboard_set_mode(KEYBOARD_NONE); guilib_fb_lock(); draw_clear_history(1); guilib_fb_unlock(); } } else { touch_down_on_keyboard = 0; touch_down_on_list = 0; goto out; } } else { if(enter_touch_y_pos<0) //record first touch y pos enter_touch_y_pos = ev->touch_event.y; last_index_y_pos = ev->touch_event.y; if (key) { if (!touch_down_on_keyboard) touch_down_on_keyboard = 1; if (pre_key && pre_key->key == key->key) goto out; if (touch_down_on_keyboard) { keyboard_key_invert(key); pre_key = key; } } else { touch_down_on_keyboard = 0; keyboard_key_reset_invert(KEYBOARD_RESET_INVERT_DELAY); // reset invert with delay pre_key = NULL; } } } else if (display_mode == DISPLAY_MODE_RESTRICTED) { key = keyboard_get_data(ev->touch_event.x, ev->touch_event.y); if (ev->touch_event.value == 0) { if (key->key == 'Y' || key->key == 'N' || key->key == 'P') { #ifdef INCLUDED_FROM_KERNEL delay_us(100000 * 2); #endif keyboard_key_reset_invert(KEYBOARD_RESET_INVERT_NOW); } else keyboard_key_reset_invert(KEYBOARD_RESET_INVERT_DELAY); // reset invert with delay enter_touch_y_pos_record = enter_touch_y_pos; enter_touch_y_pos = -1; touch_search = 0; press_delete_button = false; pre_key = NULL; if (key) { if (!touch_down_on_keyboard) { touch_down_on_keyboard = 0; goto out; } handle_password_key(key->key); } touch_down_on_keyboard = 0; } else { if(enter_touch_y_pos<0) //record first touch y pos enter_touch_y_pos = ev->touch_event.y; last_index_y_pos = ev->touch_event.y; start_search_time = ev->touch_event.ticks; last_delete_time = start_search_time; if (key) { if(key->key==8)//press "<" button { press_delete_button = true; } else if(key->key == -42) { mode = keyboard_get_mode(); if(mode == KEYBOARD_PASSWORD_CHAR) keyboard_set_mode(KEYBOARD_PASSWORD_NUM); else if(mode == KEYBOARD_PASSWORD_NUM) keyboard_set_mode(KEYBOARD_PASSWORD_CHAR); guilib_fb_lock(); keyboard_paint(); guilib_fb_unlock(); } if (!touch_down_on_keyboard) touch_down_on_keyboard = 1; if (pre_key && pre_key->key == key->key) goto out; if (touch_down_on_keyboard) { keyboard_key_invert(key); pre_key = key; } } else { keyboard_key_reset_invert(KEYBOARD_RESET_INVERT_NOW); pre_key = NULL; search_touch_pos_y_last = ev->touch_event.y; } } } else { if (ev->touch_event.value == 0) { unsigned long diff_ticks = 0; long diff_y = 0; for (i = 4; i > 0; i--) { if (last_5_y[i]) { diff_y = ev->touch_event.y - last_5_y[i]; diff_ticks = time_diff(ev->touch_event.ticks, last_5_y_time_ticks[i]); break; } } if (diff_ticks <= 0 || abs(article_moved_pixels) > SMOOTH_SCROLL_ACTIVATION_OFFSET_HIGH_THRESHOLD || abs(article_moved_pixels) < SMOOTH_SCROLL_ACTIVATION_OFFSET_LOW_THRESHOLD) finger_move_speed = 0; else { // Event timesing is not good for short period due to the events are queued without timestamp finger_move_speed = -(float)diff_y * ((float)seconds_to_ticks(1) / (float)diff_ticks); if (abs(finger_move_speed) > SMOOTH_SCROLL_ACTIVATION_SPPED_THRESHOLD) { if (finger_move_speed > 0) { if (display_mode == DISPLAY_MODE_ARTICLE) finger_move_speed = ARTICLE_SMOOTH_SCROLL_SPEED_FACTOR * (finger_move_speed - SMOOTH_SCROLL_ACTIVATION_SPPED_THRESHOLD); else finger_move_speed = LIST_SMOOTH_SCROLL_SPEED_FACTOR * (finger_move_speed - SMOOTH_SCROLL_ACTIVATION_SPPED_THRESHOLD); } else { if (display_mode == DISPLAY_MODE_ARTICLE) finger_move_speed = ARTICLE_SMOOTH_SCROLL_SPEED_FACTOR * (finger_move_speed + SMOOTH_SCROLL_ACTIVATION_SPPED_THRESHOLD); else finger_move_speed = LIST_SMOOTH_SCROLL_SPEED_FACTOR * (finger_move_speed + SMOOTH_SCROLL_ACTIVATION_SPPED_THRESHOLD); } } else finger_move_speed = 0; } if (finger_move_speed != 0) { time_scroll_article_last = ev->touch_event.ticks; } article_moved = false; if (finger_move_speed == 0 && b_show_scroll_bar) { b_show_scroll_bar = 0; show_scroll_bar(0); // clear scroll bar } article_scroll_pixel = INITIAL_ARTICLE_SCROLL_PIXEL; article_moved_pixels = 0; touch_y_last_unreleased = 0; start_move_time = 0; article_link_number = get_activated_article_link_number(); if(article_link_number>=0) { if (link_to_be_inverted >= 0) { if (link_currently_inverted >= 0) invert_link(link_currently_inverted); invert_link(link_to_be_inverted); } if (finger_move_speed == 0) { init_invert_link(); last_display_mode = display_mode; display_mode = DISPLAY_MODE_ARTICLE; open_article_link_with_link_number(article_link_number); } else { if (link_currently_inverted >= 0) invert_link(link_currently_inverted); init_invert_link(); } return; } reset_article_link_number(); article_touch_down_handled = 0; } else { finger_move_speed = 0; if(touch_y_last_unreleased == 0) { touch_y_last_unreleased = ev->touch_event.y; last_unreleased_time = ev->touch_event.ticks; reset_article_link_number(); article_moved_pixels = 0; last_5_y[0] = ev->touch_event.y; last_5_y_time_ticks[0] = ev->touch_event.ticks; for (i = 1; i < 5; i++) last_5_y[i] = 0; } else { article_moved_pixels += touch_y_last_unreleased - ev->touch_event.y; if(abs(touch_y_last_unreleased - ev->touch_event.y) >=article_scroll_pixel) { if (finger_move_speed == 0) display_article_with_pcf(touch_y_last_unreleased - ev->touch_event.y); touch_y_last_unreleased = ev->touch_event.y; for (i = 4; i >= 1; i--) { last_5_y[i] = last_5_y[i-1]; last_5_y_time_ticks[i] = last_5_y_time_ticks[i-1]; } last_5_y[0] = ev->touch_event.y; last_5_y_time_ticks[0] = ev->touch_event.ticks; b_show_scroll_bar = 1; article_scroll_pixel = 1; } else if (article_moved_pixels < article_scroll_pixel && time_diff(get_time_ticks(), last_unreleased_time) > seconds_to_ticks(0.075)) { article_moved_pixels = 0; touch_y_last_unreleased = ev->touch_event.y; last_unreleased_time = ev->touch_event.ticks; last_5_y[0] = ev->touch_event.y; last_5_y_time_ticks[0] = ev->touch_event.ticks; for (i = 1; i < 5; i++) last_5_y[i] = 0; } if (abs(article_moved_pixels) > ARTICLE_MOVED_THRESHOLD) { article_moved = true; reset_article_link_number(); } } if (!article_moved) { article_link_number =isArticleLinkSelected(ev->touch_event.x,ev->touch_event.y); if (article_link_number >= 0) set_article_link_number(article_link_number, ev->touch_event.ticks); else reset_article_link_number(); } if (!article_touch_down_handled) { article_touch_down_pos.x = ev->touch_event.x; article_touch_down_pos.y = ev->touch_event.y; article_touch_down_handled = 1; } } } out: return; }