(trunk) more speedlimit work

This commit is contained in:
Charles Kerr 2009-03-28 16:47:01 +00:00
parent bed0681dd9
commit f1d92708e7
18 changed files with 672 additions and 478 deletions

View File

@ -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"

View File

@ -60,6 +60,7 @@ noinst_HEADERS = \
tr-prefs.h \
tr-torrent.h \
tr-window.h \
turtles.h \
ui.h \
util.h

View File

@ -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

View File

@ -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 );

View File

@ -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;
}

View File

@ -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 ) );
}
}

View File

@ -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" ) );
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 _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 );
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, 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 ), "<b>%s</b>", _( "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 );
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 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 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 );
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 );
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 );
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 );
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 );
g_snprintf( buf, sizeof( buf ), "<small>%s</small>", _( "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 );

View File

@ -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;
}

78
gtk/turtles.h Normal file
View File

@ -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"};

View File

@ -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
}

View File

@ -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 );

View File

@ -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

View File

@ -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;
}

View File

@ -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 );

View File

@ -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; i<n; ++i )
@ -356,49 +358,52 @@ tr_sessionLoadSettings( tr_benc * d, const char * configDir, const char * appNam
}
void
tr_sessionSaveSettings( tr_session * session, const char * configDir, tr_benc * settings )
tr_sessionSaveSettings( tr_session * session,
const char * configDir,
const tr_benc * clientSettings )
{
tr_benc fileSettings;
char * filename;
tr_benc settings;
char * filename = tr_buildPath( configDir, "settings.json", NULL );
assert( tr_bencIsDict( settings ) );
assert( tr_bencIsDict( clientSettings ) );
filename = tr_buildPath( configDir, "settings.json", NULL );
tr_bencInitDict( &settings, 0 );
tr_sessionGetSettings( session, settings );
if( tr_bencLoadJSONFile( filename, &fileSettings ) ) {
tr_bencSaveJSONFile( filename, settings );
} else {
tr_bencMergeDicts( &fileSettings, settings );
tr_bencSaveJSONFile( filename, &fileSettings );
tr_bencFree( &fileSettings );
/* the existing file settings are the fallback values */
{
tr_benc fileSettings;
if( !tr_bencLoadJSONFile( filename, &fileSettings ) )
{
tr_bencMergeDicts( &settings, &fileSettings );
tr_bencFree( &fileSettings );
}
}
/* the client's settings override the file settings */
tr_bencMergeDicts( &settings, clientSettings );
/* the session's true values override the file & client settings */
{
tr_benc sessionSettings;
tr_bencInitDict( &sessionSettings, 0 );
tr_sessionGetSettings( session, &sessionSettings );
tr_bencMergeDicts( &settings, &sessionSettings );
tr_bencFree( &sessionSettings );
}
/* save the result */
tr_bencSaveJSONFile( filename, &settings );
tr_inf( "Saved \"%s\"", filename );
/* cleanup */
tr_free( filename );
tr_bencFree( &settings );
}
static void metainfoLookupRescan( tr_session * );
static void tr_sessionInitImpl( void * );
static void onAltTimer( int, short, void* );
/* set the alt-speed timer to go off 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 );
}
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 );
assert( found );
session->isAltSpeedLimited = i != 0;
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_UP, &i );
assert( found );
session->altSpeedBeginTime = i;
session->altSpeedEndTime = j;
session->altSpeed[TR_UP] = i;
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_DOWN, &i );
assert( found );
session->altSpeedLimit[TR_DOWN] = i;
session->altSpeedLimit[TR_UP] = j;
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->altSpeedTimeEnd = i;
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_SPEED_TIME_ENABLED, &i );
assert( found );
tr_sessionUseAltSpeedTime( session, i!=0 );
found = tr_bencDictFindInt( &settings, TR_PREFS_KEY_ALT_SPEED_ENABLED, &i );
assert( found );
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
***/
static tr_bool
isAltTime( const tr_session * session )
tr_bool
tr_sessionGetActiveSpeedLimit( const tr_session * session, tr_direction dir, int * setme )
{
const time_t now = time( NULL );
struct tm tm;
int minutes;
int isLimited = TRUE;
if( !tr_sessionIsAltSpeedLimitEnabled( session ) )
return FALSE;
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 * s )
{
tr_bool is;
int minutes;
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 );
}
void
tr_sessionSetSpeedLimitEnabled( tr_session * session,
tr_direction dir,
tr_bool isLimited )
{
assert( tr_isSession( session ) );
assert( tr_isDirection( dir ) );
/***
**** Primary session speed limits
***/
session->isSpeedLimited[dir] = isLimited;
updateBandwidth( session, dir );
void
tr_sessionSetSpeedLimit( tr_session * s, tr_direction d, int KB_s )
{
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 ) );
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];
}
/***
**** Alternative speed limits that are used during scheduled times
***/
void
tr_sessionSetAltSpeed( tr_session * s, tr_direction d, int KB_s )
{
assert( tr_isSession( s ) );
assert( tr_isDirection( d ) );
assert( KB_s >= 0 );
s->altSpeed[d] = KB_s;
updateBandwidth( s, d );
}
int
tr_sessionGetSpeedLimit( const tr_session * session, tr_direction dir )
tr_sessionGetAltSpeed( 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->speedLimit[dir];
}
static void
checkAltTime( void * session )
{
onAltTimer( 0, 0, session );
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 ) );
assert( tr_isSession( s ) );
assert( tr_isBool( b ) );
session->altSpeedEndTime = minutesSinceMidnight;
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 );
}
/***
****
***/

View File

@ -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 );

View File

@ -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 ) )

View File

@ -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 );
/***
**** Primary session speed limits
***/
tr_bool tr_sessionIsSpeedLimitEnabled ( const tr_session * session,
tr_direction direction );
void tr_sessionSetSpeedLimit ( tr_session *, tr_direction, int KB_s );
int tr_sessionGetSpeedLimit ( const tr_session *, tr_direction );
void tr_sessionSetSpeedLimit ( tr_session * session,
tr_direction direction,
int KiB_sec );
void tr_sessionLimitSpeed ( tr_session *, tr_direction, tr_bool );
tr_bool tr_sessionIsSpeedLimited ( const tr_session *, tr_direction );
int tr_sessionGetSpeedLimit ( const tr_session * session,
tr_direction direction );
/***
**** Alternative speed limits that are used during scheduled times
***/
void tr_sessionSetAltSpeed ( tr_session *, tr_direction, int KB_s );
int tr_sessionGetAltSpeed ( const tr_session *, tr_direction );
void tr_sessionUseAltSpeed ( tr_session *, tr_bool );
tr_bool tr_sessionUsesAltSpeed ( const tr_session * );
void tr_sessionUseAltSpeedTime ( tr_session *, tr_bool );
tr_bool tr_sessionUsesAltSpeedTime ( const tr_session * );
void tr_sessionSetAltSpeedBegin ( tr_session *, int minsSinceMidnight );
int tr_sessionGetAltSpeedBegin ( const tr_session * );
void tr_sessionSetAltSpeedEnd ( tr_session *, int minsSinceMidnight );
int tr_sessionGetAltSpeedEnd ( const tr_session * );
typedef void ( tr_altSpeedFunc ) ( tr_session *, tr_bool active, void * );
void tr_sessionClearAltSpeedFunc ( tr_session * );
void tr_sessionSetAltSpeedFunc ( tr_session *, tr_altSpeedFunc *, void * );
/***
****
***/
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 );
double tr_sessionGetRawSpeed ( const tr_session *, tr_direction );
double tr_sessionGetPieceSpeed ( const tr_session *, tr_direction );
void tr_sessionSetAltSpeedLimitEnabled( tr_session * session,
tr_bool isEnabled );
void tr_sessionSetRatioLimited ( tr_session *, tr_bool isLimited );
tr_bool tr_sessionIsRatioLimited ( const tr_session * );
tr_bool tr_sessionIsAltSpeedLimitEnabled( const tr_session * session );
void tr_sessionSetRatioLimit ( tr_session *, double desiredRatio );
double tr_sessionGetRatioLimit ( const tr_session * );
void tr_sessionSetAltSpeedLimitBegin( tr_session * session,
int minutesSinceMidnight );
void tr_sessionSetPeerLimit( tr_session *, uint16_t maxGlobalPeers );
uint16_t tr_sessionGetPeerLimit( const tr_session * );
int tr_sessionGetAltSpeedLimitBegin( const tr_session * session );
void tr_sessionSetAltSpeedLimitEnd( tr_session * session,
int minutesSinceMidnight );
int tr_sessionGetAltSpeedLimitEnd( const tr_session * session );
void tr_sessionSetAltSpeedLimit( tr_session * session,
tr_direction direction,
int KiB_sec );
int tr_sessionGetAltSpeedLimit( const tr_session * session,
tr_direction direction );
/***
****
***/
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);
tr_bool tr_torrentGetSeedRatio ( const tr_torrent * tor, double * ratio );
double tr_sessionGetRawSpeed ( const tr_session * session,
tr_direction direction );
double tr_sessionGetPieceSpeed ( const tr_session * session,
tr_direction direction );
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
****/
/***
**** Torrent speed limits
****
***/
void tr_torrentSetSpeedLimit( tr_torrent *, tr_direction, int KiB_sec );
void tr_torrentSetSpeedLimit ( tr_torrent *, tr_direction, int KB_s );
int tr_torrentGetSpeedLimit ( const tr_torrent *, tr_direction );
int tr_torrentGetSpeedLimit( 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_torrentUseSpeedLimit( 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_torrentIsUsingSpeedLimit( const tr_torrent *, tr_direction );
void tr_torrentUseGlobalSpeedLimit( tr_torrent *, tr_direction, tr_bool do_use );
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
****/