From: Charles Kerr Date: Sat, 28 Mar 2009 16:47:01 +0000 (+0000) Subject: (trunk) more speedlimit work X-Git-Tag: 1.60~209 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f1d92708e795ef2567e5e85831ade83e53b7293e;p=transmission (trunk) more speedlimit work --- diff --git a/doc/rpc-spec.txt b/doc/rpc-spec.txt index bcc6f8902..1b8077bba 100644 --- a/doc/rpc-spec.txt +++ b/doc/rpc-spec.txt @@ -98,18 +98,17 @@ string | value type & description ----------------------------------+------------------------------------------------- "downloadLimit" | number maximum download speed (in K/s) - "downloadLimitHonored" | 'boolean' true if "downloadLimit" is honored - "downloadGlobalHonored" | 'boolean' true if global speed limit is honored + "downloadLimited" | 'boolean' true if "downloadLimit" is honored "files-wanted" | array indices of file(s) to download "files-unwanted" | array indices of file(s) to not download + "honorsSessionLimits" | 'boolean' true if session upload limits are honored "ids" | array torrent list, as described in 3.1 "peer-limit" | number maximum number of peers "priority-high" | array indices of high-priority file(s) "priority-low" | array indices of low-priority file(s) "priority-normal" | array indices of normal-priority file(s) "uploadLimit" | number maximum upload speed (in K/s) - "uploadLimitHonored" | 'boolean' true if "uploadLimit" is honored - "uploadGlobalHonored" | 'boolean' true if global speed limit is honored + "uploadLimited" | 'boolean' true if "uploadLimit" is honored Just as an empty "ids" value is shorthand for "all ids", using an empty array for "files-wanted", "files-unwanted", "priority-high", "priority-low", or @@ -147,8 +146,7 @@ downloadedEver | number | tr_stat downloaders | number | tr_stat downloadLimit | number | tr_torrent - downloadHonorsLimit | 'boolean' | tr_torrent - downloadHonorsGlobalLimit | 'boolean' | tr_torrent + downloadLimited | 'boolean' | tr_torrent error | number | tr_stat errorString | number | tr_stat eta | number | tr_stat @@ -156,6 +154,7 @@ hashString | string | tr_info haveUnchecked | number | tr_stat haveValid | number | tr_stat + honorsSessionLimits | 'boolean' | tr_torrent id | number | tr_torrent isPrivate | 'boolean' | tr_torrent lastAnnounceTime | number | tr_stat @@ -194,8 +193,7 @@ totalSize | number | tr_info uploadedEver | number | tr_stat uploadLimit | number | tr_torrent - uploadHonorsLimit | 'boolean' | tr_torrent - uploadHonorsGlobalLimit | 'boolean' | tr_torrent + uploadLimited | 'boolean' | tr_torrent uploadRatio | 'double' | tr_stat wanted | array (see below) | n/a webseeds | array (see below) | n/a @@ -337,11 +335,12 @@ string | value type & description ---------------------------+------------------------------------------------- - "alt-speed-limit-enabled" | 'boolean' true means enabled - "alt-speed-limit-up" | number max global upload speed (in K/s) - "alt-speed-limit-down" | number max global download speed (in K/s) - "alt-speed-limit-begin" | number minutes after midnight. (ex: 60 means starting at 1 am) - "alt-speed-limit-end" | number minutes after midnight. (ex: 300 means ending at 5 am) + "alt-speed-down" | number max global download speed (in K/s) + "alt-speed-enabled" | 'boolean' true means use the alt speeds + "alt-speed-time-begin" | number when to turn on alt speeds (units: minutes after midnight) + "alt-speed-time-enabled" | 'boolean' true means the scheduled on/off times are used + "alt-speed-time-end" | number when to turn off alt speeds (units: same) + "alt-speed-up" | number max global upload speed (in K/s) "blocklist-enabled" | 'boolean' true means enabled "blocklist-size" | number number of rules in the blocklist "encryption" | string "required", "preferred", "tolerated" @@ -437,19 +436,19 @@ ------+---------+-----------+----------------+------------------------------- 6 | 1.60 | yes | torrent-get | new arg "pieces" | | yes | torrent-set | new arg "ratio" - | | yes | torrent-set | new arg "downloadHonorsLimit" - | | yes | torrent-set | new arg "downloadHonorsGlobalLimit" - | | yes | torrent-set | new arg "uploadHonorsLimit" - | | yes | torrent-set | new arg "uploadHonorsGlobalLimit" - | | yes | torrent-get | new ids option "recently-active" - | | yes | session-get | new arg "alt-speed-limit-enabled" - | | yes | session-get | new arg "alt-speed-limit-up" - | | yes | session-get | new arg "alt-speed-limit-down" - | | yes | session-get | new arg "alt-speed-limit-begin" - | | yes | session-get | new arg "alt-speed-limit-end" + | | yes | torrent-set | new arg "downloadLimited" + | | yes | torrent-set | new arg "uploadLimited" + | | yes | torrent-set | new arg "honorsSessionLImits" + | | yes | session-get | new arg "alt-speed-enabled" + | | yes | session-get | new arg "alt-speed-time-enabled" + | | yes | session-get | new arg "alt-speed-up" + | | yes | session-get | new arg "alt-speed-down" + | | yes | session-get | new arg "alt-speed-begin" + | | yes | session-get | new arg "alt-speed-end" | | yes | session-get | new arg "blocklist-enabled" | | yes | session-get | new arg "blocklist-size" | | yes | session-get | new arg "peer-limit-per-torrent" + | | yes | torrent-get | new ids option "recently-active" | | yes | | new method "torrent-reannounce" | | NO | torrent-get | removed arg "downloadLimitMode" | | NO | torrent-get | removed arg "uploadLimitMode" diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 2ecd739c5..879c2749c 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -60,6 +60,7 @@ noinst_HEADERS = \ tr-prefs.h \ tr-torrent.h \ tr-window.h \ + turtles.h \ ui.h \ util.h diff --git a/gtk/actions.c b/gtk/actions.c index 148fba4dc..dcaf98648 100644 --- a/gtk/actions.c +++ b/gtk/actions.c @@ -20,6 +20,7 @@ #include "tr-prefs.h" #include "lock.h" #include "logo.h" +#include "turtles.h" #define UNUSED G_GNUC_UNUSED @@ -69,10 +70,8 @@ sort_changed_cb( GtkAction * action UNUSED, static GtkToggleActionEntry show_toggle_entries[] = { - { "toggle-main-window", NULL, - N_( "_Main Window" ), NULL, NULL, G_CALLBACK( action_cb ), TRUE }, - { "toggle-message-log", NULL, - N_( "Message _Log" ), NULL, NULL, G_CALLBACK( action_cb ), FALSE } + { "toggle-main-window", NULL, N_( "_Main Window" ), NULL, NULL, G_CALLBACK( action_cb ), TRUE }, + { "toggle-message-log", NULL, N_( "Message _Log" ), NULL, NULL, G_CALLBACK( action_cb ), FALSE } }; static void @@ -141,7 +140,9 @@ BuiltinIconInfo; static const BuiltinIconInfo my_fallback_icons[] = { { tr_icon_logo, "transmission" }, - { tr_icon_lock, "transmission-lock" } + { tr_icon_lock, "transmission-lock" }, + { blue_turtle, "alt-speed-on" }, + { grey_turtle, "alt-speed-off" } }; static void diff --git a/gtk/details.c b/gtk/details.c index 1c98d048b..bf154d517 100644 --- a/gtk/details.c +++ b/gtk/details.c @@ -878,8 +878,7 @@ global_speed_toggled_cb( GtkToggleButton * tb, gpointer gtor ) tr_torrent * tor = tr_torrent_handle( gtor ); const gboolean b = gtk_toggle_button_get_active( tb ); - tr_torrentUseGlobalSpeedLimit( tor, TR_UP, b ); - tr_torrentUseGlobalSpeedLimit( tor, TR_DOWN, b ); + tr_torrentUseSessionLimits( tor, b ); } #define RATIO_MODE_KEY "ratio-mode" @@ -985,12 +984,12 @@ options_page_new( struct ResponseData * data ) t = hig_workarea_create( ); hig_workarea_add_section_title( t, &row, _( "Speed Limits" ) ); - b = tr_torrentIsUsingGlobalSpeedLimit( tor, TR_UP ); + b = tr_torrentUsesSessionLimits( tor ); tb = hig_workarea_add_wide_checkbutton( t, &row, _( "Honor global _limits" ), b ); g_signal_connect( tb, "toggled", G_CALLBACK( global_speed_toggled_cb ), gtor ); tb = gtk_check_button_new_with_mnemonic( _( "Limit _download speed (KB/s):" ) ); - b = tr_torrentIsUsingSpeedLimit( tor, TR_DOWN ); + b = tr_torrentUsesSpeedLimit( tor, TR_DOWN ); gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( tb ), b ); g_signal_connect( tb, "toggled", G_CALLBACK( down_speed_toggled_cb ), gtor ); @@ -1003,7 +1002,7 @@ options_page_new( struct ResponseData * data ) hig_workarea_add_row_w( t, &row, tb, w, NULL ); tb = gtk_check_button_new_with_mnemonic( _( "Limit _upload speed (KB/s):" ) ); - b = tr_torrentIsUsingSpeedLimit( tor, TR_UP ); + b = tr_torrentUsesSpeedLimit( tor, TR_UP ); gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( tb ), b ); g_signal_connect( tb, "toggled", G_CALLBACK( up_speed_toggled_cb ), gtor ); diff --git a/gtk/hig.c b/gtk/hig.c index cf3fa0008..17f62fe0d 100644 --- a/gtk/hig.c +++ b/gtk/hig.c @@ -87,8 +87,7 @@ hig_workarea_add_wide_control( GtkWidget * t, { GtkWidget * r = rowNew( w ); - gtk_table_attach( GTK_TABLE( - t ), r, 0, 2, *row, *row + 1, GTK_FILL, 0, 0, 0 ); + gtk_table_attach( GTK_TABLE( t ), r, 0, 2, *row, *row + 1, GTK_FILL, 0, 0, 0 ); ++ * row; } diff --git a/gtk/main.c b/gtk/main.c index e47394917..4d038f73d 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -436,6 +436,7 @@ main( int argc, /* initialize the libtransmission session */ session = tr_sessionInit( "gtk", configDir, TRUE, pref_get_all( ) ); + pref_flag_set( TR_PREFS_KEY_ALT_SPEED_ENABLED, tr_sessionUsesAltSpeed( session ) ); cbdata->core = tr_core_new( session ); /* create main window now to be a parent to any error dialogs */ @@ -944,54 +945,45 @@ prefschanged( TrCore * core UNUSED, } else if( !strcmp( key, TR_PREFS_KEY_PEER_PORT ) ) { - const int port = pref_int_get( key ); - tr_sessionSetPeerPort( tr, port ); + tr_sessionSetPeerPort( tr, pref_int_get( key ) ); } else if( !strcmp( key, TR_PREFS_KEY_BLOCKLIST_ENABLED ) ) { - const gboolean flag = pref_flag_get( key ); - tr_blocklistSetEnabled( tr, flag ); + tr_blocklistSetEnabled( tr, pref_flag_get( key ) ); } else if( !strcmp( key, PREF_KEY_SHOW_TRAY_ICON ) ) { const int show = pref_flag_get( key ); if( show && !cbdata->icon ) cbdata->icon = tr_icon_new( cbdata->core ); - else if( !show && cbdata->icon ) - { + else if( !show && cbdata->icon ) { g_object_unref( cbdata->icon ); cbdata->icon = NULL; } } else if( !strcmp( key, TR_PREFS_KEY_DSPEED_ENABLED ) ) { - const gboolean b = pref_flag_get( key ); - tr_sessionSetSpeedLimitEnabled( tr, TR_DOWN, b ); + tr_sessionLimitSpeed( tr, TR_DOWN, pref_flag_get( key ) ); } else if( !strcmp( key, TR_PREFS_KEY_DSPEED ) ) { - const int limit = pref_int_get( key ); - tr_sessionSetSpeedLimit( tr, TR_DOWN, limit ); + tr_sessionSetSpeedLimit( tr, TR_DOWN, pref_int_get( key ) ); } else if( !strcmp( key, TR_PREFS_KEY_USPEED_ENABLED ) ) { - const gboolean b = pref_flag_get( key ); - tr_sessionSetSpeedLimitEnabled( tr, TR_UP, b ); + tr_sessionLimitSpeed( tr, TR_UP, pref_flag_get( key ) ); } else if( !strcmp( key, TR_PREFS_KEY_USPEED ) ) { - const int limit = pref_int_get( key ); - tr_sessionSetSpeedLimit( tr, TR_UP, limit ); + tr_sessionSetSpeedLimit( tr, TR_UP, pref_int_get( key ) ); } else if( !strcmp( key, TR_PREFS_KEY_RATIO_ENABLED ) ) { - const gboolean b = pref_flag_get( key ); - tr_sessionSetRatioLimited( tr, b ); + tr_sessionSetRatioLimited( tr, pref_flag_get( key ) ); } else if( !strcmp( key, TR_PREFS_KEY_RATIO ) ) { - const double limit = pref_double_get( key ); - tr_sessionSetRatioLimit( tr, limit ); + tr_sessionSetRatioLimit( tr, pref_double_get( key ) ); } else if( !strcmp( key, TR_PREFS_KEY_PORT_FORWARDING ) ) { @@ -1011,8 +1003,7 @@ prefschanged( TrCore * core UNUSED, } else if( !strcmp( key, TR_PREFS_KEY_RPC_WHITELIST ) ) { - const char * s = pref_string_get( key ); - tr_sessionSetRPCWhitelist( tr, s ); + tr_sessionSetRPCWhitelist( tr, pref_string_get( key ) ); } else if( !strcmp( key, TR_PREFS_KEY_RPC_WHITELIST_ENABLED ) ) { @@ -1020,82 +1011,67 @@ prefschanged( TrCore * core UNUSED, } else if( !strcmp( key, TR_PREFS_KEY_RPC_USERNAME ) ) { - const char * s = pref_string_get( key ); - tr_sessionSetRPCUsername( tr, s ); + tr_sessionSetRPCUsername( tr, pref_string_get( key ) ); } else if( !strcmp( key, TR_PREFS_KEY_RPC_PASSWORD ) ) { - const char * s = pref_string_get( key ); - tr_sessionSetRPCPassword( tr, s ); + tr_sessionSetRPCPassword( tr, pref_string_get( key ) ); } else if( !strcmp( key, TR_PREFS_KEY_RPC_AUTH_REQUIRED ) ) { - const gboolean enabled = pref_flag_get( key ); - tr_sessionSetRPCPasswordEnabled( tr, enabled ); + tr_sessionSetRPCPasswordEnabled( tr, pref_flag_get( key ) ); } else if( !strcmp( key, TR_PREFS_KEY_PROXY ) ) { - const char * s = pref_string_get( key ); - tr_sessionSetProxy( tr, s ); + tr_sessionSetProxy( tr, pref_string_get( key ) ); } else if( !strcmp( key, TR_PREFS_KEY_PROXY_TYPE ) ) { - const int i = pref_int_get( key ); - tr_sessionSetProxyType( tr, i ); + tr_sessionSetProxyType( tr, pref_int_get( key ) ); } else if( !strcmp( key, TR_PREFS_KEY_PROXY_ENABLED ) ) { - const gboolean enabled = pref_flag_get( key ); - tr_sessionSetProxyEnabled( tr, enabled ); + tr_sessionSetProxyEnabled( tr, pref_flag_get( key ) ); } else if( !strcmp( key, TR_PREFS_KEY_PROXY_AUTH_ENABLED ) ) { - const gboolean enabled = pref_flag_get( key ); - tr_sessionSetProxyAuthEnabled( tr, enabled ); + tr_sessionSetProxyAuthEnabled( tr, pref_flag_get( key ) ); } else if( !strcmp( key, TR_PREFS_KEY_PROXY_USERNAME ) ) { - const char * s = pref_string_get( key ); - tr_sessionSetProxyUsername( tr, s ); + tr_sessionSetProxyUsername( tr, pref_string_get( key ) ); } else if( !strcmp( key, TR_PREFS_KEY_PROXY_PASSWORD ) ) { - const char * s = pref_string_get( key ); - tr_sessionSetProxyPassword( tr, s ); + tr_sessionSetProxyPassword( tr, pref_string_get( key ) ); } else if( !strcmp( key, TR_PREFS_KEY_PROXY_PORT ) ) { tr_sessionSetProxyPort( tr, pref_int_get( key ) ); } - else if( !strcmp( key, TR_PREFS_KEY_RPC_PASSWORD ) ) + else if( !strcmp( key, TR_PREFS_KEY_ALT_SPEED_UP ) ) { - const char * s = pref_string_get( key ); - tr_sessionSetProxyPassword( tr, s ); + tr_sessionSetAltSpeed( tr, TR_UP, pref_int_get( key ) ); } - else if( !strcmp( key, TR_PREFS_KEY_ALT_LIMIT_ENABLED ) ) + else if( !strcmp( key, TR_PREFS_KEY_ALT_SPEED_DOWN ) ) { - const gboolean enabled = pref_flag_get( key ); - tr_sessionSetAltSpeedLimitEnabled( tr, enabled ); + tr_sessionSetAltSpeed( tr, TR_DOWN, pref_int_get( key ) ); } - else if( !strcmp( key, TR_PREFS_KEY_ALT_BEGIN ) ) + else if( !strcmp( key, TR_PREFS_KEY_ALT_SPEED_ENABLED ) ) { - const int minutes = pref_int_get( key ); - tr_sessionSetAltSpeedLimitBegin( tr, minutes ); + tr_sessionUseAltSpeed( tr, pref_flag_get( key ) ); } - else if( !strcmp( key, TR_PREFS_KEY_ALT_DL_LIMIT ) ) + else if( !strcmp( key, TR_PREFS_KEY_ALT_SPEED_TIME_BEGIN ) ) { - const int speed = pref_int_get( key ); - tr_sessionSetAltSpeedLimit( tr, TR_DOWN, speed ); + tr_sessionSetAltSpeedBegin( tr, pref_int_get( key ) ); } - else if( !strcmp( key, TR_PREFS_KEY_ALT_END ) ) + else if( !strcmp( key, TR_PREFS_KEY_ALT_SPEED_TIME_END ) ) { - const int minutes = pref_int_get( key ); - tr_sessionSetAltSpeedLimitEnd( tr, minutes ); + tr_sessionSetAltSpeedEnd( tr, pref_int_get( key ) ); } - else if( !strcmp( key, TR_PREFS_KEY_ALT_UL_LIMIT ) ) + else if( !strcmp( key, TR_PREFS_KEY_ALT_SPEED_TIME_ENABLED ) ) { - const int speed = pref_int_get( key ); - tr_sessionSetAltSpeedLimit( tr, TR_UP, speed ); + tr_sessionUseAltSpeedTime( tr, pref_flag_get( key ) ); } } diff --git a/gtk/tr-prefs.c b/gtk/tr-prefs.c index 758fc53c9..2468bf9de 100644 --- a/gtk/tr-prefs.c +++ b/gtk/tr-prefs.c @@ -271,6 +271,7 @@ torrentPage( GObject * core ) const char * s; GtkWidget * t; GtkWidget * w; + GtkWidget * w2; #ifdef HAVE_GIO GtkWidget * l; @@ -304,6 +305,16 @@ torrentPage( GObject * core ) w = new_path_chooser_button( TR_PREFS_KEY_DOWNLOAD_DIR, core ); hig_workarea_add_row( t, &row, _( "_Destination folder:" ), w, NULL ); + hig_workarea_add_section_divider( t, &row ); + hig_workarea_add_section_title( t, &row, _( "Limits" ) ); + + s = _( "_Stop seeding torrents at ratio:" ); + w = new_check_button( s, TR_PREFS_KEY_RATIO_ENABLED, core ); + w2 = new_spin_button_double( TR_PREFS_KEY_RATIO, core, .5, INT_MAX, .05 ); + gtk_widget_set_sensitive( GTK_WIDGET( w2 ), pref_flag_get( TR_PREFS_KEY_RATIO_ENABLED ) ); + g_signal_connect( w, "toggled", G_CALLBACK( target_cb ), w2 ); + hig_workarea_add_row_w( t, &row, w, w2, NULL ); + hig_workarea_finish( t, &row ); return t; } @@ -778,10 +789,7 @@ webPage( GObject * core ) page->whitelist_widgets = g_slist_append( page->whitelist_widgets, w ); v = page->view = GTK_TREE_VIEW( w ); -#if GTK_CHECK_VERSION( 2,12,0 ) - gtk_widget_set_tooltip_text( w, - _( "IP addresses may use wildcards, such as 192.168.*.*" ) ); -#endif + gtr_widget_set_tooltip_text( w, _( "IP addresses may use wildcards, such as 192.168.*.*" ) ); sel = gtk_tree_view_get_selection( v ); g_signal_connect( sel, "changed", G_CALLBACK( onWhitelistSelectionChanged ), page ); @@ -990,7 +998,7 @@ static void refreshSchedSensitivity( struct BandwidthPage * p ) { GSList * l; - const gboolean sched_enabled = pref_flag_get( TR_PREFS_KEY_ALT_LIMIT_ENABLED ); + const gboolean sched_enabled = pref_flag_get( TR_PREFS_KEY_ALT_SPEED_TIME_ENABLED ); for( l = p->sched_widgets; l != NULL; l = l->next ) gtk_widget_set_sensitive( GTK_WIDGET( l->data ), sched_enabled ); @@ -1077,63 +1085,68 @@ bandwidthPage( GObject * core ) int row = 0; const char * s; GtkWidget * t; - GtkWidget * w, * w2, * h, * l; + GtkWidget * w, * w2, * h; + char buf[512]; struct BandwidthPage * page = tr_new0( struct BandwidthPage, 1 ); page->core = TR_CORE( core ); t = hig_workarea_create( ); - hig_workarea_add_section_title( t, &row, _( "Limits" ) ); - - s = _( "Limit _download speed (KB/s):" ); - w = new_check_button( s, TR_PREFS_KEY_DSPEED_ENABLED, core ); - w2 = new_spin_button( TR_PREFS_KEY_DSPEED, core, 0, INT_MAX, 5 ); - gtk_widget_set_sensitive( GTK_WIDGET( w2 ), pref_flag_get( TR_PREFS_KEY_DSPEED_ENABLED ) ); - g_signal_connect( w, "toggled", G_CALLBACK( target_cb ), w2 ); - hig_workarea_add_row_w( t, &row, w, w2, NULL ); - - s = _( "Limit _upload speed (KB/s):" ); - w = new_check_button( s, TR_PREFS_KEY_USPEED_ENABLED, core ); - w2 = new_spin_button( TR_PREFS_KEY_USPEED, core, 0, INT_MAX, 5 ); - gtk_widget_set_sensitive( GTK_WIDGET( w2 ), pref_flag_get( TR_PREFS_KEY_USPEED_ENABLED ) ); - g_signal_connect( w, "toggled", G_CALLBACK( target_cb ), w2 ); - hig_workarea_add_row_w( t, &row, w, w2, NULL ); - - s = _( "_Stop seeding when a torrent's ratio reaches:" ); - w = new_check_button( s, TR_PREFS_KEY_RATIO_ENABLED, core ); - w2 = new_spin_button_double( TR_PREFS_KEY_RATIO, core, .5, INT_MAX, .05 ); - gtk_widget_set_sensitive( GTK_WIDGET( w2 ), pref_flag_get( TR_PREFS_KEY_RATIO_ENABLED ) ); - g_signal_connect( w, "toggled", G_CALLBACK( target_cb ), w2 ); - hig_workarea_add_row_w( t, &row, w, w2, NULL ); + hig_workarea_add_section_title( t, &row, _( "Global Bandwidth Limits" ) ); + + s = _( "Limit _download speed (KB/s):" ); + w = new_check_button( s, TR_PREFS_KEY_DSPEED_ENABLED, core ); + w2 = new_spin_button( TR_PREFS_KEY_DSPEED, core, 0, INT_MAX, 5 ); + gtk_widget_set_sensitive( GTK_WIDGET( w2 ), pref_flag_get( TR_PREFS_KEY_DSPEED_ENABLED ) ); + g_signal_connect( w, "toggled", G_CALLBACK( target_cb ), w2 ); + hig_workarea_add_row_w( t, &row, w, w2, NULL ); + + s = _( "Limit _upload speed (KB/s):" ); + w = new_check_button( s, TR_PREFS_KEY_USPEED_ENABLED, core ); + w2 = new_spin_button( TR_PREFS_KEY_USPEED, core, 0, INT_MAX, 5 ); + gtk_widget_set_sensitive( GTK_WIDGET( w2 ), pref_flag_get( TR_PREFS_KEY_USPEED_ENABLED ) ); + g_signal_connect( w, "toggled", G_CALLBACK( target_cb ), w2 ); + hig_workarea_add_row_w( t, &row, w, w2, NULL ); hig_workarea_add_section_divider( t, &row ); - hig_workarea_add_section_title( t, &row, _( "Scheduled Limits" ) ); - - h = gtk_hbox_new( FALSE, 0 ); - w2 = new_time_combo( core, TR_PREFS_KEY_ALT_BEGIN ); - page->sched_widgets = g_slist_append( page->sched_widgets, w2 ); - gtk_box_pack_start( GTK_BOX( h ), w2, FALSE, FALSE, 0 ); - w2 = gtk_label_new ( _( " and " ) ); - page->sched_widgets = g_slist_append( page->sched_widgets, w2 ); - gtk_box_pack_start( GTK_BOX( h ), w2, FALSE, FALSE, 0 ); - w2 = new_time_combo( core, TR_PREFS_KEY_ALT_END ); - page->sched_widgets = g_slist_append( page->sched_widgets, w2 ); - gtk_box_pack_start( GTK_BOX( h ), w2, FALSE, FALSE, 0 ); - - s = _( "_Limit bandwidth between" ); - w = new_check_button( s, TR_PREFS_KEY_ALT_LIMIT_ENABLED, core ); - g_signal_connect( w, "toggled", G_CALLBACK( onSchedToggled ), page ); - hig_workarea_add_row_w( t, &row, w, h, NULL ); - - w = new_spin_button( TR_PREFS_KEY_ALT_DL_LIMIT, core, 0, INT_MAX, 5 ); - page->sched_widgets = g_slist_append( page->sched_widgets, w ); - l = hig_workarea_add_row( t, &row, _( "Limit d_ownload speed (KB/s):" ), w, NULL ); - page->sched_widgets = g_slist_append( page->sched_widgets, l ); - - w = new_spin_button( TR_PREFS_KEY_ALT_UL_LIMIT, core, 0, INT_MAX, 5 ); - page->sched_widgets = g_slist_append( page->sched_widgets, w ); - l = hig_workarea_add_row( t, &row, _( "Limit u_pload speed (KB/s):" ), w, NULL ); - page->sched_widgets = g_slist_append( page->sched_widgets, l ); + h = gtk_hbox_new( FALSE, GUI_PAD ); + w = gtk_image_new_from_stock( "alt-speed-off", GTK_ICON_SIZE_BUTTON ); + gtk_box_pack_start( GTK_BOX( h ), w, FALSE, FALSE, 0 ); + g_snprintf( buf, sizeof( buf ), "%s", _( "Speed Limit Mode" ) ); + w = gtk_label_new( buf ); + gtk_misc_set_alignment( GTK_MISC( w ), 0.0f, 0.5f ); + gtk_label_set_use_markup( GTK_LABEL( w ), TRUE ); + gtk_box_pack_start( GTK_BOX( h ), w, FALSE, FALSE, 0 ); + hig_workarea_add_section_title_widget( t, &row, h ); + + s = _( "Limit do_wnload speed (KB/s):" ); + w = new_spin_button( TR_PREFS_KEY_ALT_SPEED_DOWN, core, 0, INT_MAX, 5 ); + hig_workarea_add_row( t, &row, s, w, NULL ); + + s = _( "Limit u_pload speed (KB/s):" ); + w = new_spin_button( TR_PREFS_KEY_ALT_SPEED_UP, core, 0, INT_MAX, 5 ); + hig_workarea_add_row( t, &row, s, w, NULL ); + + s = _( "Use Speed Limit Mode between:" ); + h = gtk_hbox_new( FALSE, 0 ); + w2 = new_time_combo( core, TR_PREFS_KEY_ALT_SPEED_TIME_BEGIN ); + page->sched_widgets = g_slist_append( page->sched_widgets, w2 ); + gtk_box_pack_start( GTK_BOX( h ), w2, TRUE, TRUE, 0 ); + w2 = gtk_label_new ( _( " and " ) ); + page->sched_widgets = g_slist_append( page->sched_widgets, w2 ); + gtk_box_pack_start( GTK_BOX( h ), w2, FALSE, FALSE, 0 ); + w2 = new_time_combo( core, TR_PREFS_KEY_ALT_SPEED_TIME_END ); + page->sched_widgets = g_slist_append( page->sched_widgets, w2 ); + gtk_box_pack_start( GTK_BOX( h ), w2, TRUE, TRUE, 0 ); + w = new_check_button( s, TR_PREFS_KEY_ALT_SPEED_TIME_ENABLED, core ); + g_signal_connect( w, "toggled", G_CALLBACK( onSchedToggled ), page ); + hig_workarea_add_row_w( t, &row, w, h, NULL ); + + g_snprintf( buf, sizeof( buf ), "%s", _( "When enabled, Speed Limit Mode overrides the Global Bandwidth Limits" ) ); + w = gtk_label_new( buf ); + gtk_label_set_use_markup( GTK_LABEL( w ), TRUE ); + gtk_misc_set_alignment( GTK_MISC( w ), 0.5f, 0.5f ); + hig_workarea_add_wide_control( t, &row, w ); hig_workarea_finish( t, &row ); g_object_set_data_full( G_OBJECT( t ), "page", page, bandwidthPageFree ); diff --git a/gtk/tr-window.c b/gtk/tr-window.c index 31a4c572d..4693ba56b 100644 --- a/gtk/tr-window.c +++ b/gtk/tr-window.c @@ -83,6 +83,8 @@ typedef struct GtkWidget * dl_lb; GtkWidget * stats_lb; GtkWidget * gutter_lb; + GtkWidget * alt_speed_image[2]; /* 0==off, 1==on */ + GtkWidget * alt_speed_button; GtkTreeSelection * selection; GtkCellRenderer * renderer; GtkTreeViewColumn * column; @@ -193,6 +195,8 @@ makeview( PrivateData * p, return view; } +static void syncAltSpeedButton( PrivateData * p ); + static void prefsChanged( TrCore * core UNUSED, const char * key, @@ -227,6 +231,10 @@ prefsChanged( TrCore * core UNUSED, { tr_window_update( (TrWindow*)wind ); } + else if( !strcmp( key, TR_PREFS_KEY_ALT_SPEED_ENABLED ) ) + { + syncAltSpeedButton( p ); + } } static void @@ -276,6 +284,30 @@ status_menu_toggled_cb( GtkCheckMenuItem * menu_item, } } +static void +syncAltSpeedButton( PrivateData * p ) +{ + const char * tip; + const gboolean b = pref_flag_get( TR_PREFS_KEY_ALT_SPEED_ENABLED ); + GtkWidget * w = p->alt_speed_button; + + gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( w ), b ); + + gtk_button_set_image( GTK_BUTTON( w ), p->alt_speed_image[b?1:0] ); + + tip = b ? _( "Click to disable Speed Limit Mode" ) + : _( "Click to enable Speed Limit Mode" ); + gtr_widget_set_tooltip_text( w, tip ); +} + +static void +alt_speed_toggled_cb( GtkToggleButton * button, gpointer vprivate ) +{ + PrivateData * p = vprivate; + const gboolean b = gtk_toggle_button_get_active( button ); + tr_core_set_pref_bool( p->core, TR_PREFS_KEY_ALT_SPEED_ENABLED, b ); +} + /*** **** FILTER ***/ @@ -500,6 +532,22 @@ onAskTrackerQueryTooltip( GtkWidget * widget UNUSED, #endif +static gboolean +onAltSpeedToggledIdle( gpointer vp ) +{ + PrivateData * p = vp; + gboolean b = tr_sessionUsesAltSpeed( tr_core_session( p->core ) ); + tr_core_set_pref_bool( p->core, TR_PREFS_KEY_ALT_SPEED_ENABLED, b ); + + return FALSE; +} + +static void +onAltSpeedToggled( tr_session * s UNUSED, tr_bool b UNUSED, void * p ) +{ + g_idle_add( onAltSpeedToggledIdle, p ); +} + /*** **** PUBLIC ***/ @@ -619,9 +667,17 @@ tr_window_new( GtkUIManager * ui_mgr, TrCore * core ) /* status */ h = status = p->status = gtk_hbox_new( FALSE, GUI_PAD ); - gtk_container_set_border_width( GTK_CONTAINER( h ), GUI_PAD ); - w = p->gutter_lb = gtk_label_new( "N Torrents" ); + gtk_container_set_border_width( GTK_CONTAINER( h ), GUI_PAD_SMALL ); + p->alt_speed_image[0] = gtk_image_new_from_stock( "alt-speed-off", -1 ); + p->alt_speed_image[1] = gtk_image_new_from_stock( "alt-speed-on", -1 ); + w = p->alt_speed_button = gtk_toggle_button_new( ); + gtk_button_set_relief( GTK_BUTTON( w ), GTK_RELIEF_NONE ); + g_object_ref( G_OBJECT( p->alt_speed_image[0] ) ); + g_object_ref( G_OBJECT( p->alt_speed_image[1] ) ); + g_signal_connect( w, "toggled", G_CALLBACK(alt_speed_toggled_cb ), p ); gtk_box_pack_start( GTK_BOX( h ), w, 0, 0, 0 ); + w = p->gutter_lb = gtk_label_new( "N Torrents" ); + gtk_box_pack_start( GTK_BOX( h ), w, 1, 1, GUI_PAD_BIG ); w = p->ul_lb = gtk_label_new( NULL ); gtk_box_pack_end( GTK_BOX( h ), w, FALSE, FALSE, 0 ); w = gtk_image_new_from_stock( GTK_STOCK_GO_UP, GTK_ICON_SIZE_MENU ); @@ -704,9 +760,12 @@ tr_window_new( GtkUIManager * ui_mgr, TrCore * core ) prefsChanged( core, PREF_KEY_STATUSBAR, self ); prefsChanged( core, PREF_KEY_STATUSBAR_STATS, self ); prefsChanged( core, PREF_KEY_TOOLBAR, self ); + prefsChanged( core, TR_PREFS_KEY_ALT_SPEED_ENABLED, self ); p->pref_handler_id = g_signal_connect( core, "prefs-changed", G_CALLBACK( prefsChanged ), self ); + tr_sessionSetAltSpeedFunc( tr_core_session( core ), onAltSpeedToggled, p ); + filter_entry_changed( GTK_EDITABLE( s ), p ); return self; } diff --git a/gtk/turtles.h b/gtk/turtles.h new file mode 100644 index 000000000..f36566a85 --- /dev/null +++ b/gtk/turtles.h @@ -0,0 +1,78 @@ +/* GdkPixbuf RGBA C-Source image dump 1-byte-run-length-encoded */ + +#ifdef __SUNPRO_C +#pragma align 4 (blue_turtle) +#endif +#ifdef __GNUC__ +static const guint8 blue_turtle[] __attribute__ ((__aligned__ (4))) = +#else +static const guint8 blue_turtle[] = +#endif +{ "" + /* Pixbuf magic (0x47646b50) */ + "GdkP" + /* length: header (24) + pixel_data (315) */ + "\0\0\1S" + /* pixdata_type (0x2010002) */ + "\2\1\0\2" + /* rowstride (80) */ + "\0\0\0P" + /* width (20) */ + "\0\0\0\24" + /* height (14) */ + "\0\0\0\16" + /* pixel_data: */ + "\304\377\377\377\0\3""66\377@77\377p55\3770\205\377\377\377\0\1\0\0\0" + "\0\211\377\377\377\0\2""66\3770<<\377\317\202\77\77\377\377\2>>\377\377" + "::\377\237\204\377\377\377\0\1\0\0\0\0\210\377\377\377\0\14""66\3770" + "BB\377\360FF\377\377II\377\377JJ\377\377HH\377\377DD\377\377==\377\237" + "\377\377\377\0""99\377`\77\77\377\377;;\377\237\207\377\377\377\0\4""5" + "5\377\20FF\377\360KK\377\377OO\377\377\202QQ\377\377\7PP\377\377NN\377" + "\377II\377\377EE\377\377FF\377\377II\377\377[[\377\267\207\377\377\377" + "\0\3EE\377\261NN\377\377TT\377\377\204VV\377\377\3UU\377\377ee\377\331" + "\252\252\377\214\202\377\377\377f\1\377\377\377@\207\377\377\377\0\3" + "\377\377\377F\224\224\377\240YY\377\377\204ZZ\377\377\3XX\377\377kk\377" + "\274\377\377\377\31\202\377\377\377\0\1\0\0\0\0\210\377\377\377\0\2m" + "m\377wvv\377\305\204\377\377\377f\3\230\230\377\237TT\377\377FF\377\237" + "\202\377\377\377\0\1\0\0\0\0\323\377\377\377\0"}; + + +/* GdkPixbuf RGBA C-Source image dump 1-byte-run-length-encoded */ + +#ifdef __SUNPRO_C +#pragma align 4 (grey_turtle) +#endif +#ifdef __GNUC__ +static const guint8 grey_turtle[] __attribute__ ((__aligned__ (4))) = +#else +static const guint8 grey_turtle[] = +#endif +{ "" + /* Pixbuf magic (0x47646b50) */ + "GdkP" + /* length: header (24) + pixel_data (315) */ + "\0\0\1S" + /* pixdata_type (0x2010002) */ + "\2\1\0\2" + /* rowstride (80) */ + "\0\0\0P" + /* width (20) */ + "\0\0\0\24" + /* height (14) */ + "\0\0\0\16" + /* pixel_data: */ + "\304\377\377\377\0\3\3\3\3@\5\5\5p\2\2\2""0\205\377\377\377\0\1\0\0\0" + "\0\211\377\377\377\0\2\3\3\3""0\13\13\13\317\202\17\17\17\377\2\16\16" + "\16\377\11\11\11\237\204\377\377\377\0\1\0\0\0\0\210\377\377\377\0\14" + "\4\4\4""0\23\23\23\360\27\27\27\377\33\33\33\377\34\34\34\377\32\32\32" + "\377\25\25\25\377\14\14\14\237\377\377\377\0\7\7\7`\17\17\17\377\12\12" + "\12\237\207\377\377\377\0\4\2\2\2\20\27\27\27\360\36\36\36\377###\377" + "\202%%%\377\7$$$\377!!!\377\33\33\33\377\26\26\26\377\30\30\30\377\33" + "\33\33\377222\267\207\377\377\377\0\3\26\26\26\261\"\"\"\377)))\377\204" + "+++\377\3***\377\77\77\77\331\225\225\225\214\202\377\377\377f\1\377" + "\377\377@\207\377\377\377\0\3\377\377\377Fyyy\240///\377\204000\377\3" + "...\377FFF\274\377\377\377\31\202\377\377\377\0\1\0\0\0\0\210\377\377" + "\377\0\2HHHwTTT\305\204\377\377\377f\3~~~\237)))\377\27\27\27\237\202" + "\377\377\377\0\1\0\0\0\0\323\377\377\377\0"}; + + diff --git a/gtk/util.c b/gtk/util.c index 4b95ce845..30fc5b6e3 100644 --- a/gtk/util.c +++ b/gtk/util.c @@ -652,3 +652,15 @@ gtr_timeout_add_seconds( guint seconds, GSourceFunc function, gpointer data ) return g_timeout_add( seconds*1000, function, data ); #endif } + + +void +gtr_widget_set_tooltip_text( GtkWidget * w, const char * tip ) +{ +#if GTK_CHECK_VERSION( 2,12,0 ) + gtk_widget_set_tooltip_text( w, tip ); +#else + /* FIXME */ +#endif +} + diff --git a/gtk/util.h b/gtk/util.h index b90d3e2d8..d27b8faec 100644 --- a/gtk/util.h +++ b/gtk/util.h @@ -92,6 +92,8 @@ char* gtr_get_help_url( void ); #ifdef GTK_MAJOR_VERSION +void gtr_widget_set_tooltip_text( GtkWidget * w, const char * tip ); + GtkWidget * gtr_button_new_from_stock( const char * stock, const char * mnemonic ); diff --git a/libtransmission/peer-mgr.c b/libtransmission/peer-mgr.c index 472689836..b309abe92 100644 --- a/libtransmission/peer-mgr.c +++ b/libtransmission/peer-mgr.c @@ -1027,7 +1027,7 @@ peerCallbackFunc( void * vpeer, void * vevent, void * vt ) const time_t now = time( NULL ); tr_torrent * tor = t->tor; - tor->activityDate = now; + tr_torrentSetActivityDate( tor, now ); if( e->wasPieceData ) tor->uploadedCur += e->length; @@ -1062,7 +1062,8 @@ peerCallbackFunc( void * vpeer, void * vevent, void * vt ) { const time_t now = time( NULL ); tr_torrent * tor = t->tor; - tor->activityDate = now; + + tr_torrentSetActivityDate( tor, now ); /* only add this to downloadedCur if we got it from a peer -- * webseeds shouldn't count against our ratio. As one tracker diff --git a/libtransmission/resume.c b/libtransmission/resume.c index 34bea5578..b7fa70dc9 100644 --- a/libtransmission/resume.c +++ b/libtransmission/resume.c @@ -252,8 +252,8 @@ saveSingleSpeedLimit( tr_benc * d, const tr_torrent * tor, tr_direction dir ) { tr_bencDictReserve( d, 3 ); tr_bencDictAddInt( d, KEY_SPEED, tr_torrentGetSpeedLimit( tor, dir ) ); - tr_bencDictAddInt( d, KEY_USE_GLOBAL_SPEED_LIMIT, tr_torrentIsUsingGlobalSpeedLimit( tor, dir ) ); - tr_bencDictAddInt( d, KEY_USE_SPEED_LIMIT, tr_torrentIsUsingSpeedLimit( tor, dir ) ); + tr_bencDictAddInt( d, KEY_USE_GLOBAL_SPEED_LIMIT, tr_torrentUsesSessionLimits( tor ) ); + tr_bencDictAddInt( d, KEY_USE_SPEED_LIMIT, tr_torrentUsesSpeedLimit( tor, dir ) ); } static void @@ -283,7 +283,7 @@ loadSingleSpeedLimit( tr_benc * d, tr_direction dir, tr_torrent * tor ) if( tr_bencDictFindInt( d, KEY_USE_SPEED_LIMIT, &i ) ) tr_torrentUseSpeedLimit( tor, dir, i!=0 ); if( tr_bencDictFindInt( d, KEY_USE_GLOBAL_SPEED_LIMIT, &i ) ) - tr_torrentUseGlobalSpeedLimit( tor, dir, i!=0 ); + tr_torrentUseSessionLimits( tor, i!=0 ); } enum old_speed_modes @@ -317,14 +317,14 @@ loadSpeedLimits( tr_benc * dict, tr_torrent * tor ) if( tr_bencDictFindInt( d, KEY_SPEEDLIMIT_DOWN_SPEED, &i ) ) tr_torrentSetSpeedLimit( tor, TR_DOWN, i ); if( tr_bencDictFindInt( d, KEY_SPEEDLIMIT_DOWN_MODE, &i ) ) { - tr_torrentUseSpeedLimit ( tor, TR_DOWN, i==TR_SPEEDLIMIT_SINGLE ); - tr_torrentUseGlobalSpeedLimit( tor, TR_DOWN, i==TR_SPEEDLIMIT_GLOBAL ); + tr_torrentUseSpeedLimit( tor, TR_DOWN, i==TR_SPEEDLIMIT_SINGLE ); + tr_torrentUseSessionLimits( tor, i==TR_SPEEDLIMIT_GLOBAL ); } if( tr_bencDictFindInt( d, KEY_SPEEDLIMIT_UP_SPEED, &i ) ) tr_torrentSetSpeedLimit( tor, TR_UP, i ); if( tr_bencDictFindInt( d, KEY_SPEEDLIMIT_UP_MODE, &i ) ) { - tr_torrentUseSpeedLimit ( tor, TR_UP, i==TR_SPEEDLIMIT_SINGLE ); - tr_torrentUseGlobalSpeedLimit( tor, TR_UP, i==TR_SPEEDLIMIT_GLOBAL ); + tr_torrentUseSpeedLimit( tor, TR_UP, i==TR_SPEEDLIMIT_SINGLE ); + tr_torrentUseSessionLimits( tor, i==TR_SPEEDLIMIT_GLOBAL ); } ret = TR_FR_SPEEDLIMIT; } @@ -609,7 +609,7 @@ loadFromFile( tr_torrent * tor, if( ( fieldsToLoad & TR_FR_ACTIVITY_DATE ) && tr_bencDictFindInt( &top, KEY_ACTIVITY_DATE, &i ) ) { - tor->activityDate = i; + tr_torrentSetActivityDate( tor, i ); fieldsLoaded |= TR_FR_ACTIVITY_DATE; } diff --git a/libtransmission/rpcimpl.c b/libtransmission/rpcimpl.c index a630a1017..08356015c 100644 --- a/libtransmission/rpcimpl.c +++ b/libtransmission/rpcimpl.c @@ -408,10 +408,8 @@ addField( const tr_torrent * tor, tr_bencDictAddInt( d, key, st->downloaders ); else if( !strcmp( key, "downloadLimit" ) ) tr_bencDictAddInt( d, key, tr_torrentGetSpeedLimit( tor, TR_DOWN ) ); - else if( !strcmp( key, "downloadHonorsLimit" ) ) - tr_bencDictAddInt( d, key, tr_torrentIsUsingSpeedLimit( tor, TR_DOWN ) ); - else if( !strcmp( key, "downloadHonorsGlobalLimit" ) ) - tr_bencDictAddInt( d, key, tr_torrentIsUsingGlobalSpeedLimit( tor, TR_DOWN ) ); + else if( !strcmp( key, "downloadLimited" ) ) + tr_bencDictAddInt( d, key, tr_torrentUsesSpeedLimit( tor, TR_DOWN ) ); else if( !strcmp( key, "error" ) ) tr_bencDictAddInt( d, key, st->error ); else if( !strcmp( key, "errorString" ) ) @@ -426,6 +424,8 @@ addField( const tr_torrent * tor, tr_bencDictAddInt( d, key, st->haveUnchecked ); else if( !strcmp( key, "haveValid" ) ) tr_bencDictAddInt( d, key, st->haveValid ); + else if( !strcmp( key, "honorsSessionLimits" ) ) + tr_bencDictAddInt( d, key, tr_torrentUsesSessionLimits( tor ) ); else if( !strcmp( key, "id" ) ) tr_bencDictAddInt( d, key, st->id ); else if( !strcmp( key, "isPrivate" ) ) @@ -520,10 +520,8 @@ addField( const tr_torrent * tor, tr_bencDictAddDouble( d, key, tr_getRatio( st->uploadedEver, st->downloadedEver ) ); else if( !strcmp( key, "uploadLimit" ) ) tr_bencDictAddInt( d, key, tr_torrentGetSpeedLimit( tor, TR_UP ) ); - else if( !strcmp( key, "uploadHonorsLimit" ) ) - tr_bencDictAddInt( d, key, tr_torrentIsUsingSpeedLimit( tor, TR_UP ) ); - else if( !strcmp( key, "uploadHonorsGlobalLimit" ) ) - tr_bencDictAddInt( d, key, tr_torrentIsUsingGlobalSpeedLimit( tor, TR_UP ) ); + else if( !strcmp( key, "uploadLimited" ) ) + tr_bencDictAddInt( d, key, tr_torrentUsesSpeedLimit( tor, TR_UP ) ); else if( !strcmp( key, "wanted" ) ) { tr_file_index_t i; @@ -689,16 +687,14 @@ torrentSet( tr_session * session, errmsg = setFilePriorities( tor, TR_PRI_NORMAL, files ); if( tr_bencDictFindInt( args_in, "downloadLimit", &tmp ) ) tr_torrentSetSpeedLimit( tor, TR_DOWN, tmp ); - if( tr_bencDictFindInt( args_in, "downloadHonorsLimit", &tmp ) ) + if( tr_bencDictFindInt( args_in, "downloadLimited", &tmp ) ) tr_torrentUseSpeedLimit( tor, TR_DOWN, tmp!=0 ); - if( tr_bencDictFindInt( args_in, "downloadHonorsGlobalLimit", &tmp ) ) - tr_torrentUseGlobalSpeedLimit( tor, TR_DOWN, tmp!=0 ); + if( tr_bencDictFindInt( args_in, "honorsSessionLimits", &tmp ) ) + tr_torrentUseSessionLimits( tor, tmp!=0 ); if( tr_bencDictFindInt( args_in, "uploadLimit", &tmp ) ) tr_torrentSetSpeedLimit( tor, TR_UP, tmp ); - if( tr_bencDictFindInt( args_in, "uploadHonorsLimit", &tmp ) ) + if( tr_bencDictFindInt( args_in, "uploadLimited", &tmp ) ) tr_torrentUseSpeedLimit( tor, TR_UP, tmp!=0 ); - if( tr_bencDictFindInt( args_in, "uploadHonorsGlobalLimit", &tmp ) ) - tr_torrentUseGlobalSpeedLimit( tor, TR_UP, tmp!=0 ); if( tr_bencDictFindDouble( args_in, "ratio-limit", &d ) ) tr_torrentSetRatioLimit( tor, d ); if( tr_bencDictFindInt( args_in, "ratio-limit-mode", &tmp ) ) @@ -864,16 +860,18 @@ sessionSet( tr_session * session, assert( idle_data == NULL ); - if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_ALT_LIMIT_ENABLED, &i ) ) - tr_sessionSetAltSpeedLimitEnabled( session, i!=0 ); - if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_ALT_BEGIN, &i ) ) - tr_sessionSetAltSpeedLimitBegin( session, i ); - if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_ALT_END, &i ) ) - tr_sessionSetAltSpeedLimitEnd( session, i ); - if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_ALT_DL_LIMIT, &i ) ) - tr_sessionSetAltSpeedLimit( session, TR_DOWN, i ); - if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_ALT_UL_LIMIT, &i ) ) - tr_sessionSetAltSpeedLimit( session, TR_UP, i ); + if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_ALT_SPEED_UP, &i ) ) + tr_sessionSetAltSpeed( session, TR_UP, i ); + if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_ALT_SPEED_DOWN, &i ) ) + tr_sessionSetAltSpeed( session, TR_DOWN, i ); + if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_ALT_SPEED_ENABLED, &i ) ) + tr_sessionUseAltSpeed( session, i!=0 ); + if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_ALT_SPEED_TIME_BEGIN, &i ) ) + tr_sessionSetAltSpeedBegin( session, i ); + if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_ALT_SPEED_TIME_END, &i ) ) + tr_sessionSetAltSpeedEnd( session, i ); + if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_ALT_SPEED_TIME_ENABLED, &i ) ) + tr_sessionUseAltSpeedTime( session, i!=0 ); if( tr_bencDictFindInt( args_in, TR_PREFS_KEY_BLOCKLIST_ENABLED, &i ) ) tr_blocklistSetEnabled( session, i!=0 ); if( tr_bencDictFindStr( args_in, TR_PREFS_KEY_DOWNLOAD_DIR, &str ) ) @@ -891,15 +889,15 @@ sessionSet( tr_session * session, if( tr_bencDictFindInt( args_in, "speed-limit-down", &i ) ) tr_sessionSetSpeedLimit( session, TR_DOWN, i ); if( tr_bencDictFindInt( args_in, "speed-limit-down-enabled", &i ) ) - tr_sessionSetSpeedLimitEnabled( session, TR_DOWN, i ); + tr_sessionLimitSpeed( session, TR_DOWN, i!=0 ); if( tr_bencDictFindInt( args_in, "speed-limit-up", &i ) ) tr_sessionSetSpeedLimit( session, TR_UP, i ); if( tr_bencDictFindInt( args_in, "speed-limit-up-enabled", &i ) ) - tr_sessionSetSpeedLimitEnabled( session, TR_UP, i ); + tr_sessionLimitSpeed( session, TR_UP, i!=0 ); if( tr_bencDictFindDouble( args_in, "ratio-limit", &d ) ) tr_sessionSetRatioLimit( session, d ); if( tr_bencDictFindInt( args_in, "ratio-limit-enabled", &i ) ) - tr_sessionSetRatioLimited( session, i ); + tr_sessionSetRatioLimited( session, i!=0 ); if( tr_bencDictFindStr( args_in, "encryption", &str ) ) { if( !strcmp( str, "required" ) ) @@ -972,11 +970,12 @@ sessionGet( tr_session * s, tr_benc * d = args_out; assert( idle_data == NULL ); - tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_LIMIT_ENABLED, tr_sessionIsAltSpeedLimitEnabled( s ) ); - tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_UL_LIMIT, tr_sessionGetAltSpeedLimit( s, TR_UP ) ); - tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_DL_LIMIT, tr_sessionGetAltSpeedLimit( s, TR_DOWN ) ); - tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_BEGIN, tr_sessionGetAltSpeedLimitBegin( s ) ); - tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_END, tr_sessionGetAltSpeedLimitEnd( s ) ); + tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_SPEED_UP, tr_sessionGetAltSpeed(s,TR_UP) ); + tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_SPEED_DOWN, tr_sessionGetAltSpeed(s,TR_DOWN) ); + tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_SPEED_ENABLED, tr_sessionUsesAltSpeed(s) ); + tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_SPEED_TIME_BEGIN, tr_sessionGetAltSpeedBegin(s) ); + tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_SPEED_TIME_END,tr_sessionGetAltSpeedEnd(s) ); + tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_SPEED_TIME_ENABLED, tr_sessionUsesAltSpeedTime(s) ); tr_bencDictAddInt( d, TR_PREFS_KEY_BLOCKLIST_ENABLED, tr_blocklistIsEnabled( s ) ); tr_bencDictAddInt( d, "blocklist-size", tr_blocklistGetRuleCount( s ) ); tr_bencDictAddStr( d, TR_PREFS_KEY_DOWNLOAD_DIR, tr_sessionGetDownloadDir( s ) ); @@ -988,9 +987,9 @@ sessionGet( tr_session * s, tr_bencDictAddInt( d, "rpc-version", 4 ); tr_bencDictAddInt( d, "rpc-version-minimum", 1 ); tr_bencDictAddInt( d, "speed-limit-up", tr_sessionGetSpeedLimit( s, TR_UP ) ); - tr_bencDictAddInt( d, "speed-limit-up-enabled", tr_sessionIsSpeedLimitEnabled( s, TR_UP ) ); + tr_bencDictAddInt( d, "speed-limit-up-enabled", tr_sessionIsSpeedLimited( s, TR_UP ) ); tr_bencDictAddInt( d, "speed-limit-down", tr_sessionGetSpeedLimit( s, TR_DOWN ) ); - tr_bencDictAddInt( d, "speed-limit-down-enabled", tr_sessionIsSpeedLimitEnabled( s, TR_DOWN ) ); + tr_bencDictAddInt( d, "speed-limit-down-enabled", tr_sessionIsSpeedLimited( s, TR_DOWN ) ); tr_bencDictAddDouble( d, "ratio-limit", tr_sessionGetRatioLimit( s ) ); tr_bencDictAddInt( d, "ratio-limit-enabled", tr_sessionIsRatioLimited( s ) ); tr_bencDictAddStr( d, "version", LONG_VERSION_STRING ); diff --git a/libtransmission/session.c b/libtransmission/session.c index e4aa773cc..e814f861b 100644 --- a/libtransmission/session.c +++ b/libtransmission/session.c @@ -256,11 +256,12 @@ tr_sessionGetDefaultSettings( tr_benc * d ) tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_WHITELIST, TR_DEFAULT_RPC_WHITELIST ); tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_WHITELIST_ENABLED, TRUE ); tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_PORT, atoi( TR_DEFAULT_RPC_PORT_STR ) ); - tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_LIMIT_ENABLED, FALSE ); - tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_BEGIN, 1320 ); /* 10pm */ - tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_END, 300 ); /* 5am */ - tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_DL_LIMIT, 200 ); /* double the regular default */ - tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_UL_LIMIT, 200 ); /* double the regular default */ + tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_SPEED_ENABLED, FALSE ); + tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_SPEED_UP, 50 ); /* half the regular */ + tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_SPEED_DOWN, 50 ); /* half the regular */ + tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_SPEED_TIME_BEGIN, 540 ); /* 9am */ + tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_SPEED_TIME_ENABLED, FALSE ); + tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_SPEED_TIME_END, 1020 ); /* 5pm */ tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED, 100 ); tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED_ENABLED, 0 ); tr_bencDictAddInt( d, TR_PREFS_KEY_UPLOAD_SLOTS_PER_TORRENT, 14 ); @@ -278,7 +279,7 @@ tr_sessionGetSettings( tr_session * s, struct tr_benc * d ) tr_bencDictAddInt( d, TR_PREFS_KEY_BLOCKLIST_ENABLED, tr_blocklistIsEnabled( s ) ); tr_bencDictAddStr( d, TR_PREFS_KEY_DOWNLOAD_DIR, s->downloadDir ); tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED, tr_sessionGetSpeedLimit( s, TR_DOWN ) ); - tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED_ENABLED, tr_sessionIsSpeedLimitEnabled( s, TR_DOWN ) ); + tr_bencDictAddInt( d, TR_PREFS_KEY_DSPEED_ENABLED, tr_sessionIsSpeedLimited( s, TR_DOWN ) ); tr_bencDictAddInt( d, TR_PREFS_KEY_ENCRYPTION, s->encryptionMode ); tr_bencDictAddInt( d, TR_PREFS_KEY_LAZY_BITFIELD, s->useLazyBitfield ); tr_bencDictAddInt( d, TR_PREFS_KEY_MSGLEVEL, tr_getMessageLevel( ) ); @@ -309,13 +310,14 @@ tr_sessionGetSettings( tr_session * s, struct tr_benc * d ) tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_USERNAME, freeme[n++] = tr_sessionGetRPCUsername( s ) ); tr_bencDictAddStr( d, TR_PREFS_KEY_RPC_WHITELIST, freeme[n++] = tr_sessionGetRPCWhitelist( s ) ); tr_bencDictAddInt( d, TR_PREFS_KEY_RPC_WHITELIST_ENABLED, tr_sessionGetRPCWhitelistEnabled( s ) ); - tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_LIMIT_ENABLED, tr_sessionIsAltSpeedLimitEnabled( s ) ); - tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_BEGIN, tr_sessionGetAltSpeedLimitBegin( s ) ); - tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_END, tr_sessionGetAltSpeedLimitEnd( s ) ); - tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_DL_LIMIT, tr_sessionGetAltSpeedLimit( s, TR_DOWN ) ); - tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_UL_LIMIT, tr_sessionGetAltSpeedLimit( s, TR_UP ) ); + tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_SPEED_ENABLED, tr_sessionUsesAltSpeed( s ) ); + tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_SPEED_UP, tr_sessionGetAltSpeed( s, TR_UP ) ); + tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_SPEED_DOWN, tr_sessionGetAltSpeed( s, TR_DOWN ) ); + tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_SPEED_TIME_BEGIN, tr_sessionGetAltSpeedBegin( s ) ); + tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_SPEED_TIME_ENABLED, tr_sessionUsesAltSpeedTime( s ) ); + tr_bencDictAddInt( d, TR_PREFS_KEY_ALT_SPEED_TIME_END, tr_sessionGetAltSpeedEnd( s ) ); tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED, tr_sessionGetSpeedLimit( s, TR_UP ) ); - tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED_ENABLED, tr_sessionIsSpeedLimitEnabled( s, TR_UP ) ); + tr_bencDictAddInt( d, TR_PREFS_KEY_USPEED_ENABLED, tr_sessionIsSpeedLimited( s, TR_UP ) ); tr_bencDictAddInt( d, TR_PREFS_KEY_UPLOAD_SLOTS_PER_TORRENT, s->uploadSlotsPerTorrent ); for( i=0; ialtTimer != NULL ); - - tr_localtime_r( &now, &tm ); - tv.tv_sec = 60 - tm.tm_sec; - tv.tv_usec = 0; - evtimer_add( session->altTimer, &tv ); -} +static void setAltTimer( tr_session * session ); struct init_data { @@ -589,13 +594,13 @@ tr_sessionInitImpl( void * vdata ) && tr_bencDictFindInt( &settings, TR_PREFS_KEY_USPEED_ENABLED, &j ); assert( found ); tr_sessionSetSpeedLimit( session, TR_UP, i ); - tr_sessionSetSpeedLimitEnabled( session, TR_UP, j ); + tr_sessionLimitSpeed( session, TR_UP, j!=0 ); found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_DSPEED, &i ) && tr_bencDictFindInt( &settings, TR_PREFS_KEY_DSPEED_ENABLED, &j ); assert( found ); tr_sessionSetSpeedLimit( session, TR_DOWN, i ); - tr_sessionSetSpeedLimitEnabled( session, TR_DOWN, j ); + tr_sessionLimitSpeed( session, TR_DOWN, j!=0 ); found = tr_bencDictFindDouble( &settings, TR_PREFS_KEY_RATIO, &d ) && tr_bencDictFindInt( &settings, TR_PREFS_KEY_RATIO_ENABLED, &j ); @@ -604,25 +609,38 @@ tr_sessionInitImpl( void * vdata ) tr_sessionSetRatioLimited( session, j ); /** - *** Alternate speed limits for off-peak hours + *** Alternate speed limits **/ - found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_LIMIT_ENABLED, &i ); + + found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_SPEED_UP, &i ); + assert( found ); + session->altSpeed[TR_UP] = i; + + found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_SPEED_DOWN, &i ); + assert( found ); + session->altSpeed[TR_DOWN] = i; + + found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_SPEED_TIME_BEGIN, &i ); + assert( found ); + session->altSpeedTimeBegin = i; + + found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_SPEED_TIME_END, &i ); assert( found ); - session->isAltSpeedLimited = i != 0; + session->altSpeedTimeEnd = i; - found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_BEGIN, &i ) - && tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_END, &j ); + found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_SPEED_TIME_ENABLED, &i ); assert( found ); - session->altSpeedBeginTime = i; - session->altSpeedEndTime = j; + tr_sessionUseAltSpeedTime( session, i!=0 ); - found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_DL_LIMIT, &i ) - && tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_UL_LIMIT, &j ); + found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_SPEED_ENABLED, &i ); assert( found ); - session->altSpeedLimit[TR_DOWN] = i; - session->altSpeedLimit[TR_UP] = j; + tr_sessionUseAltSpeed( session, i!=0 ); + + + /** + *** Blocklist + **/ - /* initialize the blocklist */ filename = tr_buildPath( session->configDir, "blocklists", NULL ); tr_mkdirp( filename, 0777 ); tr_free( filename ); @@ -826,54 +844,50 @@ tr_sessionGetRatioLimit( const tr_session * session ) } /*** -**** +**** SPEED LIMITS ***/ +tr_bool +tr_sessionGetActiveSpeedLimit( const tr_session * session, tr_direction dir, int * setme ) +{ + int isLimited = TRUE; + + if( tr_sessionUsesAltSpeed( session ) ) + *setme = tr_sessionGetAltSpeed( session, dir ); + else if( tr_sessionIsSpeedLimited( session, dir ) ) + *setme = tr_sessionGetSpeedLimit( session, dir ); + else + isLimited = FALSE; + + return isLimited; +} + static tr_bool -isAltTime( const tr_session * session ) +isAltTime( const tr_session * s ) { - const time_t now = time( NULL ); - struct tm tm; + tr_bool is; int minutes; - - if( !tr_sessionIsAltSpeedLimitEnabled( session ) ) - return FALSE; + struct tm tm; + const time_t now = time( NULL ); + const int begin = s->altSpeedTimeBegin; + const int end = s->altSpeedTimeEnd; tr_localtime_r( &now, &tm ); minutes = tm.tm_hour*60 + tm.tm_min; - if( session->altSpeedBeginTime <= session->altSpeedEndTime ) - { - return ( session->altSpeedBeginTime <= minutes ) - && ( minutes < session->altSpeedEndTime ); - } + if( begin <= end ) + is = ( begin <= minutes ) && ( minutes < end ); else /* goes past midnight */ - { - return ( minutes >= session->altSpeedBeginTime ) - || ( minutes < session->altSpeedEndTime ); - } -} + is = ( begin <= minutes ) || ( minutes < end ); -static int -getActiveSpeedLimit( const tr_session * session, tr_direction dir ) -{ - int val; - - if( tr_sessionIsAltSpeedLimitEnabled( session ) && session->isAltTime ) - val = tr_sessionGetAltSpeedLimit( session, dir ); - else if( tr_sessionIsSpeedLimitEnabled( session, dir ) ) - val = tr_sessionGetSpeedLimit( session, dir ); - else - val = -1; - - return val; + return is; } static void updateBandwidth( tr_session * session, tr_direction dir ) { - const int limit = getActiveSpeedLimit( session, dir ); - const tr_bool isLimited = limit >= 0; + int limit; + const tr_bool isLimited = tr_sessionGetActiveSpeedLimit( session, dir, &limit ); const tr_bool zeroCase = isLimited && !limit; tr_bandwidthSetLimited( session->bandwidth, dir, isLimited && !zeroCase ); @@ -881,164 +895,234 @@ updateBandwidth( tr_session * session, tr_direction dir ) tr_bandwidthSetDesiredSpeed( session->bandwidth, dir, limit ); } +static void +altSpeedToggled( void * vsession ) +{ + tr_session * session = vsession; + + assert( tr_isSession( session ) ); + + updateBandwidth( session, TR_UP ); + updateBandwidth( session, TR_DOWN ); + + if( session->altCallback != NULL ) + (*session->altCallback)( session, session->altSpeedEnabled, session->altCallbackUserData ); +} + +/* tell the alt speed limit timer to fire again at the top of the minute */ +static void +setAltTimer( tr_session * session ) +{ + const time_t now = time( NULL ); + struct tm tm; + struct timeval tv; + + assert( tr_isSession( session ) ); + assert( session->altTimer != NULL ); + + tr_localtime_r( &now, &tm ); + tv.tv_sec = 60 - tm.tm_sec; + tv.tv_usec = 0; + evtimer_add( session->altTimer, &tv ); +} + /* this is called once a minute to: * (1) update session->isAltTime * (2) alter the speed limits when the alt limits go on and off */ static void onAltTimer( int foo UNUSED, short bar UNUSED, void * vsession ) { - tr_bool wasAltTime; tr_session * session = vsession; assert( tr_isSession( session ) ); - wasAltTime = session->isAltTime; - session->isAltTime = isAltTime( session ); - - if( wasAltTime != session->isAltTime ) + if( session->altSpeedTimeEnabled ) { - updateBandwidth( session, TR_UP ); - updateBandwidth( session, TR_DOWN ); + const time_t now = time( NULL ); + struct tm tm; + int currentMinute; + tr_localtime_r( &now, &tm ); + currentMinute = tm.tm_hour*60 + tm.tm_min; - if( session->altCallback != NULL ) - (*session->altCallback)( session, session->isAltTime, session->altCallbackUserData ); + if( currentMinute == session->altSpeedTimeBegin ) + { + tr_sessionUseAltSpeed( session, TRUE ); + } + else if( currentMinute == session->altSpeedTimeEnd ) + { + tr_sessionUseAltSpeed( session, FALSE ); + } } setAltTimer( session ); } +/*** +**** Primary session speed limits +***/ + void -tr_sessionSetSpeedLimitEnabled( tr_session * session, - tr_direction dir, - tr_bool isLimited ) +tr_sessionSetSpeedLimit( tr_session * s, tr_direction d, int KB_s ) { - assert( tr_isSession( session ) ); - assert( tr_isDirection( dir ) ); + assert( tr_isSession( s ) ); + assert( tr_isDirection( d ) ); + assert( KB_s >= 0 ); + + s->speedLimit[d] = KB_s; + + updateBandwidth( s, d ); +} + +int +tr_sessionGetSpeedLimit( const tr_session * s, tr_direction d ) +{ + assert( tr_isSession( s ) ); + assert( tr_isDirection( d ) ); - session->isSpeedLimited[dir] = isLimited; - updateBandwidth( session, dir ); + return s->speedLimit[d]; } void -tr_sessionSetSpeedLimit( tr_session * session, - tr_direction dir, - int desiredSpeed ) +tr_sessionLimitSpeed( tr_session * s, tr_direction d, tr_bool b ) { - assert( tr_isSession( session ) ); - assert( tr_isDirection( dir ) ); + assert( tr_isSession( s ) ); + assert( tr_isDirection( d ) ); + assert( tr_isBool( b ) ); - session->speedLimit[dir] = desiredSpeed; - updateBandwidth( session, dir ); + s->speedLimitEnabled[d] = b; + + updateBandwidth( s, d ); } tr_bool -tr_sessionIsSpeedLimitEnabled( const tr_session * session, tr_direction dir ) +tr_sessionIsSpeedLimited( const tr_session * s, tr_direction d ) { - assert( tr_isSession( session ) ); - assert( tr_isDirection( dir ) ); + assert( tr_isSession( s ) ); + assert( tr_isDirection( d ) ); - return session->isSpeedLimited[dir]; + return s->speedLimitEnabled[d]; } -int -tr_sessionGetSpeedLimit( const tr_session * session, tr_direction dir ) +/*** +**** Alternative speed limits that are used during scheduled times +***/ + +void +tr_sessionSetAltSpeed( tr_session * s, tr_direction d, int KB_s ) { - assert( tr_isSession( session ) ); - assert( tr_isDirection( dir ) ); + assert( tr_isSession( s ) ); + assert( tr_isDirection( d ) ); + assert( KB_s >= 0 ); + + s->altSpeed[d] = KB_s; - return session->speedLimit[dir]; + updateBandwidth( s, d ); } -static void -checkAltTime( void * session ) +int +tr_sessionGetAltSpeed( const tr_session * s, tr_direction d ) { - onAltTimer( 0, 0, session ); + assert( tr_isSession( s ) ); + assert( tr_isDirection( d ) ); + + return s->altSpeed[d]; } void -tr_sessionSetAltSpeedLimitEnabled( tr_session * session, - tr_bool isEnabled ) +tr_sessionUseAltSpeedTime( tr_session * s, tr_bool b ) { - assert( tr_isSession( session ) ); - assert( tr_isBool( isEnabled ) ); + assert( tr_isSession( s ) ); + assert( tr_isBool( b ) ); - session->isAltSpeedLimited = isEnabled; + if( s->altSpeedTimeEnabled != b ) + { + s->altSpeedTimeEnabled = b; - tr_runInEventThread( session, checkAltTime, session ); + if( isAltTime( s ) ) + tr_sessionUseAltSpeed( s, b ); + } } tr_bool -tr_sessionIsAltSpeedLimitEnabled( const tr_session * session ) +tr_sessionUsesAltSpeedTime( const tr_session * s ) { - assert( tr_isSession( session ) ); + assert( tr_isSession( s ) ); - return session->isAltSpeedLimited; + return s->altSpeedTimeEnabled; } void -tr_sessionSetAltSpeedLimit( tr_session * session, - tr_direction dir, - int desiredSpeed ) +tr_sessionSetAltSpeedBegin( tr_session * s, int minutes ) { - assert( tr_isSession( session ) ); - assert( tr_isDirection( dir ) ); - assert( desiredSpeed >= 0 ); + assert( tr_isSession( s ) ); + assert( 0<=minutes && minutes<(60*24) ); - session->altSpeedLimit[dir] = desiredSpeed; + if( s->altSpeedTimeBegin != minutes ) + { + s->altSpeedTimeBegin = minutes; - updateBandwidth( session, dir ); + if( tr_sessionUsesAltSpeedTime( s ) ) + tr_sessionUseAltSpeed( s, isAltTime( s ) ); + } } int -tr_sessionGetAltSpeedLimit( const tr_session * session, - tr_direction dir ) +tr_sessionGetAltSpeedBegin( const tr_session * s ) { - assert( tr_isSession( session ) ); - assert( tr_isDirection( dir ) ); + assert( tr_isSession( s ) ); - return session->altSpeedLimit[dir]; + return s->altSpeedTimeBegin; } void -tr_sessionSetAltSpeedLimitBegin( tr_session * session, int minutesSinceMidnight ) +tr_sessionSetAltSpeedEnd( tr_session * s, int minutes ) { - assert( tr_isSession( session ) ); + assert( tr_isSession( s ) ); + assert( 0<=minutes && minutes<(60*24) ); - session->altSpeedBeginTime = minutesSinceMidnight; + if( s->altSpeedTimeEnd != minutes ) + { + s->altSpeedTimeEnd = minutes; - tr_runInEventThread( session, checkAltTime, session ); + if( tr_sessionUsesAltSpeedTime( s ) ) + tr_sessionUseAltSpeed( s, isAltTime( s ) ); + } } int -tr_sessionGetAltSpeedLimitBegin( const tr_session * session ) +tr_sessionGetAltSpeedEnd( const tr_session * s ) { - assert( tr_isSession( session ) ); + assert( tr_isSession( s ) ); - return session->altSpeedBeginTime; + return s->altSpeedTimeEnd; } void -tr_sessionSetAltSpeedLimitEnd( tr_session * session, int minutesSinceMidnight ) +tr_sessionUseAltSpeed( tr_session * s, tr_bool b ) { - assert( tr_isSession( session ) ); - - session->altSpeedEndTime = minutesSinceMidnight; + assert( tr_isSession( s ) ); + assert( tr_isBool( b ) ); - tr_runInEventThread( session, checkAltTime, session ); + if( s->altSpeedEnabled != b) + { + s->altSpeedEnabled = b; + + tr_runInEventThread( s, altSpeedToggled, s ); + } } -int -tr_sessionGetAltSpeedLimitEnd( const tr_session * session ) +tr_bool +tr_sessionUsesAltSpeed( const tr_session * s ) { - assert( tr_isSession( session ) ); + assert( tr_isSession( s ) ); - return session->altSpeedEndTime; + return s->altSpeedEnabled; } void -tr_sessionSetAltSpeedCallback( tr_session * session, - tr_alt_speed_func func, - void * userData ) +tr_sessionSetAltSpeedFunc( tr_session * session, + tr_altSpeedFunc func, + void * userData ) { assert( tr_isSession( session ) ); @@ -1047,12 +1131,11 @@ tr_sessionSetAltSpeedCallback( tr_session * session, } void -tr_sessionClearAltSpeedCallback( tr_session * session ) +tr_sessionClearAltSpeedFunc( tr_session * session ) { - tr_sessionSetAltSpeedCallback( session, NULL, NULL ); + tr_sessionSetAltSpeedFunc( session, NULL, NULL ); } - /*** **** ***/ diff --git a/libtransmission/session.h b/libtransmission/session.h index db25f23df..f487f9c9c 100644 --- a/libtransmission/session.h +++ b/libtransmission/session.h @@ -68,14 +68,18 @@ struct tr_session tr_bool useLazyBitfield; tr_bool isRatioLimited; - tr_bool isSpeedLimited[2]; + int speedLimit[2]; - tr_bool isAltSpeedLimited; - int altSpeedBeginTime; - int altSpeedEndTime; - int altSpeedLimit[2]; - tr_bool isAltTime; - tr_alt_speed_func * altCallback; + tr_bool speedLimitEnabled[2]; + + int altSpeed[2]; + tr_bool altSpeedEnabled; + + int altSpeedTimeBegin; + int altSpeedTimeEnd; + tr_bool altSpeedTimeEnabled; + + tr_altSpeedFunc * altCallback; void * altCallbackUserData; @@ -145,6 +149,10 @@ struct tr_session double desiredRatio; }; +tr_bool tr_sessionGetActiveSpeedLimit( const tr_session * session, + tr_direction dir, + int * setme ); + const char * tr_sessionFindTorrentFile( const tr_session * session, const char * hashString ); diff --git a/libtransmission/torrent.c b/libtransmission/torrent.c index 45fc5eebf..5b548f135 100644 --- a/libtransmission/torrent.c +++ b/libtransmission/torrent.c @@ -136,7 +136,7 @@ tr_torrentUseSpeedLimit( tr_torrent * tor, tr_direction dir, tr_bool do_use ) } tr_bool -tr_torrentIsUsingSpeedLimit( const tr_torrent * tor, tr_direction dir ) +tr_torrentUsesSpeedLimit( const tr_torrent * tor, tr_direction dir ) { assert( tr_isTorrent( tor ) ); assert( tr_isDirection( dir ) ); @@ -145,21 +145,20 @@ tr_torrentIsUsingSpeedLimit( const tr_torrent * tor, tr_direction dir ) } void -tr_torrentUseGlobalSpeedLimit( tr_torrent * tor, tr_direction dir, tr_bool do_use ) +tr_torrentUseSessionLimits( tr_torrent * tor, tr_bool doUse ) { assert( tr_isTorrent( tor ) ); - assert( tr_isDirection( dir ) ); - tr_bandwidthHonorParentLimits( tor->bandwidth, dir, do_use ); + tr_bandwidthHonorParentLimits( tor->bandwidth, TR_UP, doUse ); + tr_bandwidthHonorParentLimits( tor->bandwidth, TR_DOWN, doUse ); } tr_bool -tr_torrentIsUsingGlobalSpeedLimit( const tr_torrent * tor, tr_direction dir ) +tr_torrentUsesSessionLimits( const tr_torrent * tor ) { assert( tr_isTorrent( tor ) ); - assert( tr_isDirection( dir ) ); - return tr_bandwidthAreParentLimitsHonored( tor->bandwidth, dir ); + return tr_bandwidthAreParentLimitsHonored( tor->bandwidth, TR_UP ); } /*** @@ -208,15 +207,16 @@ tr_bool tr_torrentIsPieceTransferAllowed( const tr_torrent * tor, tr_direction direction ) { + int limit; tr_bool allowed = TRUE; - if( tr_torrentIsUsingSpeedLimit( tor, direction ) ) + if( tr_torrentUsesSpeedLimit( tor, direction ) ) if( tr_torrentGetSpeedLimit( tor, direction ) <= 0 ) allowed = FALSE; - if( tr_torrentIsUsingGlobalSpeedLimit( tor, direction ) ) - if( tr_sessionIsSpeedLimitEnabled( tor->session, direction ) ) - if( tr_sessionGetSpeedLimit( tor->session, direction ) <= 0 ) + if( tr_torrentUsesSessionLimits( tor ) ) + if( tr_sessionGetActiveSpeedLimit( tor->session, direction, &limit ) ) + if( limit <= 0 ) allowed = FALSE; return allowed; @@ -594,10 +594,9 @@ torrentRealInit( tr_session * session, if( !( loaded & TR_FR_SPEEDLIMIT ) ) { - tr_torrentSetSpeedLimit( tor, TR_UP, - tr_sessionGetSpeedLimit( tor->session, TR_UP ) ); - tr_torrentSetSpeedLimit( tor, TR_DOWN, - tr_sessionGetSpeedLimit( tor->session, TR_DOWN ) ); + tr_torrentUseSpeedLimit( tor, TR_UP, FALSE ); + tr_torrentUseSpeedLimit( tor, TR_DOWN, FALSE ); + tr_torrentUseSessionLimits( tor, TRUE ); } if( !( loaded & TR_FR_RATIOLIMIT ) ) diff --git a/libtransmission/transmission.h b/libtransmission/transmission.h index 649bc7055..67851a573 100644 --- a/libtransmission/transmission.h +++ b/libtransmission/transmission.h @@ -151,11 +151,12 @@ static TR_INLINE tr_bool tr_isEncryptionMode( tr_encryption_mode m ) #define TR_DEFAULT_PEER_LIMIT_GLOBAL_STR "240" #define TR_DEFAULT_PEER_LIMIT_TORRENT_STR "60" -#define TR_PREFS_KEY_ALT_LIMIT_ENABLED "alt-speed-limit-enabled" -#define TR_PREFS_KEY_ALT_BEGIN "alt-speed-limit-begin" -#define TR_PREFS_KEY_ALT_DL_LIMIT "alt-speed-limit-down" -#define TR_PREFS_KEY_ALT_END "alt-speed-limit-end" -#define TR_PREFS_KEY_ALT_UL_LIMIT "alt-speed-limit-up" +#define TR_PREFS_KEY_ALT_SPEED_ENABLED "alt-speed-enabled" +#define TR_PREFS_KEY_ALT_SPEED_UP "alt-speed-up" +#define TR_PREFS_KEY_ALT_SPEED_DOWN "alt-speed-down" +#define TR_PREFS_KEY_ALT_SPEED_TIME_BEGIN "alt-speed-time-begin" +#define TR_PREFS_KEY_ALT_SPEED_TIME_ENABLED "alt-speed-time-enabled" +#define TR_PREFS_KEY_ALT_SPEED_TIME_END "alt-speed-time-end" #define TR_PREFS_KEY_BLOCKLIST_ENABLED "blocklist-enabled" #define TR_PREFS_KEY_DOWNLOAD_DIR "download-dir" #define TR_PREFS_KEY_DSPEED "download-limit" @@ -256,9 +257,9 @@ void tr_sessionLoadSettings( struct tr_benc * dictionary, * @param dictionary * @see tr_sessionLoadSettings() */ -void tr_sessionSaveSettings( tr_session * session, - const char * configDir, - struct tr_benc * dictonary ); +void tr_sessionSaveSettings( tr_session * session, + const char * configDir, + const struct tr_benc * dictonary ); /** * Initialize a libtransmission session. @@ -557,97 +558,59 @@ tr_direction; **** ***/ -void tr_sessionSetSpeedLimitEnabled ( tr_session * session, - tr_direction direction, - tr_bool isEnabled ); - -tr_bool tr_sessionIsSpeedLimitEnabled ( const tr_session * session, - tr_direction direction ); - -void tr_sessionSetSpeedLimit ( tr_session * session, - tr_direction direction, - int KiB_sec ); - -int tr_sessionGetSpeedLimit ( const tr_session * session, - tr_direction direction ); - /*** -**** +**** Primary session speed limits ***/ -typedef void ( tr_alt_speed_func )( tr_session * session, - tr_bool isAltActive, - void * userData ); - -/** - * Register to be notified whenever the alternate speed limits go on and off. - * - * func is invoked FROM LIBTRANSMISSION'S THREAD! - * This means func must be fast (to avoid blocking peers), - * shouldn't call libtransmission functions (to avoid deadlock), - * and shouldn't modify client-level memory without using a mutex! - */ -void tr_sessionSetAltSpeedCallback( tr_session * session, - tr_alt_speed_func func, - void * userData ); - -void tr_sessionClearAltSpeedCallback( tr_session * session ); +void tr_sessionSetSpeedLimit ( tr_session *, tr_direction, int KB_s ); +int tr_sessionGetSpeedLimit ( const tr_session *, tr_direction ); +void tr_sessionLimitSpeed ( tr_session *, tr_direction, tr_bool ); +tr_bool tr_sessionIsSpeedLimited ( const tr_session *, tr_direction ); -void tr_sessionSetAltSpeedLimitEnabled( tr_session * session, - tr_bool isEnabled ); -tr_bool tr_sessionIsAltSpeedLimitEnabled( const tr_session * session ); +/*** +**** Alternative speed limits that are used during scheduled times +***/ -void tr_sessionSetAltSpeedLimitBegin( tr_session * session, - int minutesSinceMidnight ); +void tr_sessionSetAltSpeed ( tr_session *, tr_direction, int KB_s ); +int tr_sessionGetAltSpeed ( const tr_session *, tr_direction ); -int tr_sessionGetAltSpeedLimitBegin( const tr_session * session ); +void tr_sessionUseAltSpeed ( tr_session *, tr_bool ); +tr_bool tr_sessionUsesAltSpeed ( const tr_session * ); -void tr_sessionSetAltSpeedLimitEnd( tr_session * session, - int minutesSinceMidnight ); +void tr_sessionUseAltSpeedTime ( tr_session *, tr_bool ); +tr_bool tr_sessionUsesAltSpeedTime ( const tr_session * ); -int tr_sessionGetAltSpeedLimitEnd( const tr_session * session ); +void tr_sessionSetAltSpeedBegin ( tr_session *, int minsSinceMidnight ); +int tr_sessionGetAltSpeedBegin ( const tr_session * ); -void tr_sessionSetAltSpeedLimit( tr_session * session, - tr_direction direction, - int KiB_sec ); +void tr_sessionSetAltSpeedEnd ( tr_session *, int minsSinceMidnight ); +int tr_sessionGetAltSpeedEnd ( const tr_session * ); -int tr_sessionGetAltSpeedLimit( const tr_session * session, - tr_direction direction ); +typedef void ( tr_altSpeedFunc ) ( tr_session *, tr_bool active, void * ); +void tr_sessionClearAltSpeedFunc ( tr_session * ); +void tr_sessionSetAltSpeedFunc ( tr_session *, tr_altSpeedFunc *, void * ); /*** **** ***/ -void tr_sessionSetRatioLimited ( tr_session * session, - tr_bool isEnabled ); - -tr_bool tr_sessionIsRatioLimited ( const tr_session * session); - -void tr_sessionSetRatioLimit ( tr_session * session, - double desiredRatio); - -double tr_sessionGetRatioLimit ( const tr_session * session); +double tr_sessionGetRawSpeed ( const tr_session *, tr_direction ); +double tr_sessionGetPieceSpeed ( const tr_session *, tr_direction ); -tr_bool tr_torrentGetSeedRatio ( const tr_torrent * tor, double * ratio ); -double tr_sessionGetRawSpeed ( const tr_session * session, - tr_direction direction ); +void tr_sessionSetRatioLimited ( tr_session *, tr_bool isLimited ); +tr_bool tr_sessionIsRatioLimited ( const tr_session * ); -double tr_sessionGetPieceSpeed ( const tr_session * session, - tr_direction direction ); +void tr_sessionSetRatioLimit ( tr_session *, double desiredRatio ); +double tr_sessionGetRatioLimit ( const tr_session * ); +void tr_sessionSetPeerLimit( tr_session *, uint16_t maxGlobalPeers ); +uint16_t tr_sessionGetPeerLimit( const tr_session * ); -void tr_sessionSetPeerLimit( tr_session * session, - uint16_t maxGlobalPeers ); - -uint16_t tr_sessionGetPeerLimit( const tr_session * session ); - -void tr_sessionSetPeerLimitPerTorrent( tr_session * session, - uint16_t maxGlobalPeers ); - -uint16_t tr_sessionGetPeerLimitPerTorrent( const tr_session * session ); +void tr_sessionSetPeerLimitPerTorrent( tr_session *, uint16_t maxGlobalPeers ); +uint16_t tr_sessionGetPeerLimitPerTorrent( const tr_session * ); /** @@ -926,21 +889,20 @@ uint64_t tr_torrentGetBytesLeftToAllocate( const tr_torrent * torrent ); */ int tr_torrentId( const tr_torrent * torrent ); -/**** -***** Speed Limits -****/ - -void tr_torrentSetSpeedLimit( tr_torrent *, tr_direction, int KiB_sec ); - -int tr_torrentGetSpeedLimit( const tr_torrent *, tr_direction ); +/*** +**** Torrent speed limits +**** +***/ -void tr_torrentUseSpeedLimit( tr_torrent *, tr_direction, tr_bool do_use ); +void tr_torrentSetSpeedLimit ( tr_torrent *, tr_direction, int KB_s ); +int tr_torrentGetSpeedLimit ( const tr_torrent *, tr_direction ); -tr_bool tr_torrentIsUsingSpeedLimit( const tr_torrent *, tr_direction ); +void tr_torrentUseSpeedLimit ( tr_torrent *, tr_direction, tr_bool ); +tr_bool tr_torrentUsesSpeedLimit ( const tr_torrent *, tr_direction ); -void tr_torrentUseGlobalSpeedLimit( tr_torrent *, tr_direction, tr_bool do_use ); +void tr_torrentUseSessionLimits ( tr_torrent *, tr_bool ); +tr_bool tr_torrentUsesSessionLimits ( const tr_torrent * ); -tr_bool tr_torrentIsUsingGlobalSpeedLimit ( const tr_torrent *, tr_direction ); /**** ***** Ratio Limits @@ -964,6 +926,9 @@ void tr_torrentSetRatioLimit( tr_torrent * tor, double tr_torrentGetRatioLimit( const tr_torrent * tor ); + +tr_bool tr_torrentGetSeedRatio( const tr_torrent *, double * ratio ); + /**** ***** Peer Limits ****/