/*! * \brief 指定ファイルへの書き込みデータを参照 * \param[in] filename 出力先のファイル名 * \return 書き込みデータ */ std::string output_file::get_file_data( std::string const& filename ) { context_map::const_iterator iter( get_context_map().find( path_name( filename ) ) ), last( get_context_map().end() ); if ( iter != last ) { return iter->second->ostr.str(); } return ""; }
/*! * \brief メモリ上に格納されている書き込みようデータを消去 * \param[in] filename 出力先のファイル名 * \retval true データの消去成功 * \retval false 指定したファイルへの出力データが存在しない */ bool output_file::clear_file_data( std::string const& filename ) { context_map::const_iterator iter( get_context_map().find( path_name( filename ) ) ), last( get_context_map().end() ); if ( iter != last ) { iter->second->ostr.str( "" ); return true; } return false; }
/*! * \brief 出力ストリームの参照 * \return 出力ストリーム * * 設定されているファイルに出力するための出力ストリームを返す。 * 既に出力ストリームが生成されている場合はその参照を返し、そうでなければ新たに出力ストリームを生成する。 * * ファイル名として、"stdout"が設定されていれば標準出力、"stderr"が設定されていれば標準エラー出力になる。 */ std::ostream& output_file::ostr() const { if ( filename_ == "stdout" ) { return std::cout; } else if ( filename_ == "stderr" ) { return std::cerr; } std::string path( path_name( filename_ ) ); context_map::const_iterator iter( get_context_map().find( path ) ); if ( iter == get_context_map().end() ) { std::tr1::shared_ptr< context > ctx( new context ); get_context_map().insert( std::make_pair( path, ctx ) ); return ctx->ostr; } return iter->second->ostr; }
/* * 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; }
/*! * \brief メモリ上に格納されている内容を実際にファイルに出力する。 * * context_map としてメモリ上に格納された内容を、それぞれのファイルに対して出力する。 * 出力するにあたり、まず元のファイルを .org を付けたファイル名に変更する。 * ここで、以前にあった .org は破壊される。 * ファイルを順に書き込み、途中でエラーが発生した場合は、.org を元のファイル名に戻す。 * 途中でひとつでもエラーが発生した場合は、全ファイルについて .org を元に戻す。 * 以前にあった .org は復活しない。 */ void output_file::save() { namespace fs = boost::filesystem; std::vector< std::string > saved_files; try { for ( context_map::const_iterator iter( get_context_map().begin() ), last( get_context_map().end() ); iter != last; ++iter ) { if ( iter->first != "" ) { // fs::path filename( iter->first, fs::native ); fs::path filename( iter->first ); // filesystem3対応 // fs::path backup( iter->first + ".org", fs::native ); fs::path backup( iter->first + ".org" ); // filesystem3対応 bool existed = fs::exists( filename ); try { // std::string file( filename.native_file_string() ); std::string file( filename.string() ); // filesystem3対応 if ( existed ) { fs::rename( filename, backup ); } write( file, iter->second->ostr.str() ); // ここで書き込む saved_files.push_back( file ); fs::remove( backup ); } catch ( ... ) { if ( existed ) { fs::remove( filename ); fs::rename( backup, filename ); } throw; } } } } catch ( ... ) { // すでに書き込んだファイルを元に戻す。 for ( std::vector< std::string >::const_iterator iter( saved_files.begin() ), last( saved_files.end() ); iter != last; ++iter ) { // fs::path filename( *iter, fs::native ); fs::path filename( *iter ); // filesystem3対応 fs::remove( filename ); // fs::path backup( *iter + ".org", fs::native ); fs::path backup( *iter + ".org" ); // filesystem3対応 if ( fs::exists( backup ) ) { fs::rename( backup, filename ); } } throw; } }