Index: includes/theme.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/theme.inc,v
retrieving revision 1.517
diff -u -p -r1.517 theme.inc
--- includes/theme.inc	29 Aug 2009 04:16:14 -0000	1.517
+++ includes/theme.inc	30 Aug 2009 15:47:41 -0000
@@ -1127,112 +1127,113 @@ function drupal_find_theme_templates($ca
 }
 
 /**
- * Retrieve an associative array containing the settings for a theme.
+ * Retrieve a setting for the current theme or for a given theme.
  *
- * The final settings are arrived at by merging the default settings,
- * the site-wide settings, and the settings defined for the specific theme.
- * If no $key was specified, only the site-wide theme defaults are retrieved.
- *
- * The default values for each of settings are also defined in this function.
- * To add new settings, add their default values here, and then add form elements
- * to system_theme_settings() in system.module.
- *
- * @param $key
- *  The template/style value for a given theme.
- *
- * @return
- *   An associative array containing theme settings.
- */
-function theme_get_settings($key = NULL) {
-  $defaults = array(
-    'default_logo'                     =>  1,
-    'logo_path'                        =>  '',
-    'default_favicon'                  =>  1,
-    'favicon_path'                     =>  '',
-    // Use the IANA-registered MIME type for ICO files as default.
-    'favicon_mimetype'                 =>  'image/vnd.microsoft.icon',
-    'main_menu'                        =>  1,
-    'secondary_menu'                   =>  1,
-    'toggle_logo'                      =>  1,
-    'toggle_favicon'                   =>  1,
-    'toggle_name'                      =>  1,
-    'toggle_search'                    =>  0,
-    'toggle_slogan'                    =>  0,
-    'toggle_node_user_picture'         =>  0,
-    'toggle_comment_user_picture'      =>  0,
-    'toggle_comment_user_verification' =>  1,
-    'toggle_main_menu'                 =>  1,
-    'toggle_secondary_menu'            =>  1,
-  );
-
-  $settings = array_merge($defaults, variable_get('theme_settings', array()));
-
-  if ($key) {
-    $settings = array_merge($settings, variable_get(str_replace('/', '_', 'theme_' . $key . '_settings'), array()));
-  }
-
-  // Only offer search box if search.module is enabled.
-  if (!defined('MAINTENANCE_MODE') && module_exists('search') && user_access('search content')) {
-    $settings['toggle_search'] = 1;
-  }
-
-  return $settings;
-}
-
-/**
- * Retrieve a setting for the current theme.
- * This function is designed for use from within themes & engines
- * to determine theme settings made in the admin interface.
- *
- * Caches values for speed (use $refresh = TRUE to refresh cache)
+ * The final setting is arrived at by merging the default settings, the custom
+ * theme settings defined in the theme's .info file, the site-wide settings, and
+ * the settings defined for the specific theme. If an empty string is given for
+ * $key, only the site-wide theme defaults are retrieved.
+ *
+ * The default values for each setting is defined in this function. To add new
+ * settings, add their default values here, and then add form elements to
+ * system_theme_settings() in system.admin.inc.
  *
  * @param $setting_name
  *  The name of the setting to be retrieved.
- *
- * @param $refresh
- *  Whether to reload the cache of settings.
- *
+ * @param $theme
+ *  The name of a given theme; defaults to the current theme.
  * @return
  *   The value of the requested setting, NULL if the setting does not exist.
  */
-function theme_get_setting($setting_name, $refresh = FALSE) {
-  global $theme_key;
-  static $settings;
+function theme_get_setting($setting_name, $theme = NULL) {
+  $cache = &drupal_static(__FUNCTION__, array());
 
-  if (empty($settings) || $refresh) {
-    $settings = theme_get_settings($theme_key);
-
-    $themes = list_themes();
-    $theme_object = $themes[$theme_key];
-
-    if ($settings['toggle_logo']) {
-      if ($settings['default_logo']) {
-        $settings['logo'] = file_create_url(dirname($theme_object->filename) . '/logo.png');
+  // If no key is given, use the current theme if we can determine it.
+  if (is_null($theme)) {
+    $theme = !empty($GLOBALS['theme_key']) ? $GLOBALS['theme_key'] : (!empty($GLOBALS['custom_theme']) ? $GLOBALS['custom_theme'] : '');
+  }
+
+  if (empty($cache[$theme])) {
+    // Set the default settings.
+    $cache[$theme] = array(
+      'default_logo'                     =>  1,
+      'logo_path'                        =>  '',
+      'default_favicon'                  =>  1,
+      'favicon_path'                     =>  '',
+      // Use the IANA-registered MIME type for ICO files as default.
+      'favicon_mimetype'                 =>  'image/vnd.microsoft.icon',
+      'main_menu'                        =>  1,
+      'secondary_menu'                   =>  1,
+      'toggle_logo'                      =>  1,
+      'toggle_favicon'                   =>  1,
+      'toggle_name'                      =>  1,
+      'toggle_search'                    =>  1,
+      'toggle_slogan'                    =>  1,
+      'toggle_node_user_picture'         =>  1,
+      'toggle_comment_user_picture'      =>  1,
+      'toggle_comment_user_verification' =>  1,
+      'toggle_main_menu'                 =>  1,
+      'toggle_secondary_menu'            =>  1,
+    );
+
+    // Get the default values for the custom settings from the .info file.
+    if ($theme) {
+      $themes = list_themes();
+      $theme_object = $themes[$theme];
+
+      // Create a list which includes the current theme and all its base themes.
+      if (isset($theme_object->base_themes)) {
+        $theme_keys = array_keys($theme_object->base_themes);
+        $theme_keys[] = $theme;
       }
-      elseif ($settings['logo_path']) {
-        $settings['logo'] = file_create_url($settings['logo_path']);
+      else {
+        $theme_keys = array($theme);
+      }
+      foreach ($theme_keys as $theme_key) {
+        if (!empty($themes[$theme_key]->info['settings'])) {
+          $cache[$theme] = array_merge($cache[$theme], $themes[$theme_key]->info['settings']);
+        }
       }
     }
 
-    if ($settings['toggle_favicon']) {
-      if ($settings['default_favicon']) {
-        if (file_exists($favicon = dirname($theme_object->filename) . '/favicon.ico')) {
-          $settings['favicon'] = file_create_url($favicon);
+    // Get the saved global settings from the database.
+    $cache[$theme] = array_merge($cache[$theme], variable_get('theme_settings', array()));
+
+    if ($theme) {
+      // Get the saved theme settings from the database.
+      $cache[$theme] = array_merge($cache[$theme], variable_get('theme_' . $theme . '_settings', array()));
+
+      // Generate the path to the logo image.
+      if ($cache[$theme]['toggle_logo']) {
+        if ($cache[$theme]['default_logo']) {
+          $cache[$theme]['logo'] = file_create_url(dirname($theme_object->filename) . '/logo.png');
         }
-        else {
-          $settings['favicon'] = file_create_url('misc/favicon.ico');
+        elseif ($cache[$theme]['logo_path']) {
+          $cache[$theme]['logo'] = file_create_url($cache[$theme]['logo_path']);
         }
       }
-      elseif ($settings['favicon_path']) {
-        $settings['favicon'] = file_create_url($settings['favicon_path']);
-      }
-      else {
-        $settings['toggle_favicon'] = FALSE;
+
+      // Generate the path to the favicon.
+      if ($cache[$theme]['toggle_favicon']) {
+        if ($cache[$theme]['default_favicon']) {
+          if (file_exists($favicon = dirname($theme_object->filename) . '/favicon.ico')) {
+            $cache[$theme]['favicon'] = file_create_url($favicon);
+          }
+          else {
+            $cache[$theme]['favicon'] = file_create_url('misc/favicon.ico');
+          }
+        }
+        elseif ($cache[$theme]['favicon_path']) {
+          $cache[$theme]['favicon'] = file_create_url($cache[$theme]['favicon_path']);
+        }
+        else {
+          $cache[$theme]['toggle_favicon'] = FALSE;
+        }
       }
     }
   }
 
-  return isset($settings[$setting_name]) ? $settings[$setting_name] : NULL;
+  return isset($cache[$theme][$setting_name]) ? $cache[$theme][$setting_name] : NULL;
 }
 
 /**
@@ -2062,7 +2063,7 @@ function template_preprocess_page(&$vari
   $variables['main_menu']         = theme_get_setting('toggle_main_menu') ? menu_main_menu() : array();
   $variables['secondary_menu']    = theme_get_setting('toggle_secondary_menu') ? menu_secondary_menu() : array();
   $variables['action_links']      = menu_local_actions();
-  $variables['search_box']        = (theme_get_setting('toggle_search') ? drupal_render(drupal_get_form('search_theme_form')) : '');
+  $variables['search_box']        = (theme_get_setting('toggle_search') && user_access('search content') ? drupal_render(drupal_get_form('search_theme_form')) : '');
   $variables['site_name']         = (theme_get_setting('toggle_name') ? filter_xss_admin(variable_get('site_name', 'Drupal')) : '');
   $variables['site_slogan']       = (theme_get_setting('toggle_slogan') ? filter_xss_admin(variable_get('site_slogan', '')) : '');
   $variables['tabs']              = theme('menu_local_tasks');
Index: modules/system/system.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.admin.inc,v
retrieving revision 1.197
diff -u -p -r1.197 system.admin.inc
--- modules/system/system.admin.inc	26 Aug 2009 10:53:45 -0000	1.197
+++ modules/system/system.admin.inc	30 Aug 2009 15:47:41 -0000
@@ -384,15 +384,13 @@ function system_theme_settings(&$form_st
     drupal_set_message(t('The directory %directory does not exist or is not writable.', array('%directory' => $directory_path)), 'warning');
   }
 
-  // Default settings are defined in theme_get_settings() in includes/theme.inc
+  // Default settings are defined in theme_get_setting() in includes/theme.inc
   if ($key) {
-    $settings = theme_get_settings($key);
-    $var = str_replace('/', '_', 'theme_' . $key . '_settings');
+    $var = 'theme_' . $key . '_settings';
     $themes = system_get_theme_data();
     $features = $themes[$key]->info['features'];
   }
   else {
-    $settings = theme_get_settings('');
     $var = 'theme_settings';
   }
 
@@ -401,7 +399,7 @@ function system_theme_settings(&$form_st
   // Check for a new uploaded logo, and use that instead.
   if ($file = file_save_upload('logo_upload', array('file_validate_is_image' => array()))) {
     $parts = pathinfo($file->filename);
-    $filename = ($key) ? str_replace('/', '_', $key) . '_logo.' . $parts['extension'] : 'logo.' . $parts['extension'];
+    $filename = ($key) ? $key . '_logo.' . $parts['extension'] : 'logo.' . $parts['extension'];
 
     // The image was saved using file_save_upload() and was added to the
     // files table as a temporary file. We'll make a copy and let the garbage
@@ -416,7 +414,7 @@ function system_theme_settings(&$form_st
   // Check for a new uploaded favicon, and use that instead.
   if ($file = file_save_upload('favicon_upload')) {
     $parts = pathinfo($file->filename);
-    $filename = ($key) ? str_replace('/', '_', $key) . '_favicon.' . $parts['extension'] : 'favicon.' . $parts['extension'];
+    $filename = ($key) ? $key . '_favicon.' . $parts['extension'] : 'favicon.' . $parts['extension'];
 
     // The image was saved using file_save_upload() and was added to the
     // files table as a temporary file. We'll make a copy and let the garbage
@@ -459,7 +457,7 @@ function system_theme_settings(&$form_st
   );
   foreach ($toggles as $name => $title) {
     if ((!$key) || in_array($name, $features)) {
-      $form['theme_settings']['toggle_' . $name] = array('#type' => 'checkbox', '#title' => $title, '#default_value' => $settings['toggle_' . $name]);
+      $form['theme_settings']['toggle_' . $name] = array('#type' => 'checkbox', '#title' => $title, '#default_value' => theme_get_setting('toggle_' . $name, $key));
       // Disable checkboxes for features not supported in the current configuration.
       if (isset($disabled['toggle_' . $name])) {
         $form['theme_settings']['toggle_' . $name]['#disabled'] = TRUE;
@@ -484,14 +482,14 @@ function system_theme_settings(&$form_st
     $form['logo']['default_logo'] = array(
       '#type' => 'checkbox',
       '#title' => t('Use the default logo'),
-      '#default_value' => $settings['default_logo'],
+      '#default_value' => theme_get_setting('default_logo', $key),
       '#tree' => FALSE,
       '#description' => t('Check here if you want the theme to use the logo supplied with it.')
     );
     $form['logo']['logo_path'] = array(
       '#type' => 'textfield',
       '#title' => t('Path to custom logo'),
-      '#default_value' => $settings['logo_path'],
+      '#default_value' => theme_get_setting('logo_path', $key),
       '#description' => t('The path to the file you would like to use as your logo file instead of the default logo.'));
 
     $form['logo']['logo_upload'] = array(
@@ -511,16 +509,15 @@ function system_theme_settings(&$form_st
     $form['favicon']['default_favicon'] = array(
       '#type' => 'checkbox',
       '#title' => t('Use the default shortcut icon.'),
-      '#default_value' => $settings['default_favicon'],
+      '#default_value' => theme_get_setting('default_favicon', $key),
       '#description' => t('Check here if you want the theme to use the default shortcut icon.')
     );
     $form['favicon']['favicon_path'] = array(
       '#type' => 'textfield',
       '#title' => t('Path to custom icon'),
-      '#default_value' => $settings['favicon_path'],
+      '#default_value' => theme_get_setting('favicon_path', $key),
       '#description' => t('The path to the image file you would like to use as your custom shortcut icon.')
     );
-
     $form['favicon']['favicon_upload'] = array(
       '#type' => 'file',
       '#title' => t('Upload icon image'),
@@ -529,43 +526,60 @@ function system_theme_settings(&$form_st
   }
 
   if ($key) {
-    // Include the theme's theme-settings.php file
-    $filename = DRUPAL_ROOT . '/' . str_replace("/$key.info", '', $themes[$key]->filename) . '/theme-settings.php';
-    if (!file_exists($filename) and !empty($themes[$key]->info['base theme'])) {
-      // If the theme doesn't have a theme-settings.php file, use the base theme's.
-      $base = $themes[$key]->info['base theme'];
-      $filename = DRUPAL_ROOT . '/' . str_replace("/$base.info", '', $themes[$base]->filename) . '/theme-settings.php';
-    }
-    if (file_exists($filename)) {
-      require_once $filename;
-    }
-
     // Call engine-specific settings.
     $function = $themes[$key]->prefix . '_engine_settings';
     if (function_exists($function)) {
-      $group = $function($settings, $form);
-      if (!empty($group)) {
-        $form['engine_specific'] = array('#type' => 'fieldset', '#title' => t('Theme-engine-specific settings'), '#description' => t('These settings only exist for all the templates and styles based on the %engine theme engine.', array('%engine' => $themes[$key]->prefix)));
-        $form['engine_specific'] = array_merge($form['engine_specific'], $group);
-      }
+      $form['engine_specific'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Theme-engine-specific settings'),
+        '#description' => t('These settings only exist for the themes based on the %engine theme engine.', array('%engine' => $themes[$key]->prefix)),
+      );
+      $function($form, $form_state);
     }
-    // Call theme-specific settings.
-    $function = $key . '_settings';
-    if (!function_exists($function)) {
-      $function = $themes[$key]->prefix . '_settings';
+
+    // Create a list which includes the current theme and all its base themes.
+    if (isset($themes[$key]->base_themes)) {
+      $theme_keys = array_keys($themes[$key]->base_themes);
+      $theme_keys[] = $key;
     }
-    if (function_exists($function)) {
-      $group = $function($settings, $form);
-      if (!empty($group)) {
-        $form['theme_specific'] = array('#type' => 'fieldset', '#title' => t('Theme-specific settings'), '#description' => t('These settings only exist for the %theme theme and all the styles based on it.', array('%theme' => $themes[$key]->info['name'])));
-        $form['theme_specific'] = array_merge($form['theme_specific'], $group);
+    else {
+      $theme_keys = array($key);
+    }
+
+    // Process the theme and all its base themes.
+    foreach ($theme_keys as $theme) {
+      // Include the theme-settings.php file.
+      $filename = DRUPAL_ROOT . '/' . str_replace("/$theme.info", '', $themes[$theme]->filename) . '/theme-settings.php';
+      if (file_exists($filename)) {
+        require_once $filename;
+      }
+
+      // Save the name of the current theme (if any), so that we can temporarily
+      // override the current theme and allow theme_get_setting() to work
+      // without having to pass the theme name to it.
+      $default_theme = !empty($GLOBALS['theme_key']) ? $GLOBALS['theme_key'] : NULL;
+      $GLOBALS['theme_key'] = $theme;
+
+      // Call theme-specific settings.
+      $function = $theme . '_form_theme_settings_alter';
+      if (function_exists($function)) {
+        $function($form, $form_state);
+      }
+
+      // Restore the original current theme.
+      if (!is_null($default_theme)) {
+        $GLOBALS['theme_key'] = $default_theme;
+      }
+      else {
+        unset($GLOBALS['theme_key']);
       }
     }
   }
 
   $form = system_settings_form($form, FALSE);
   // We don't want to call system_settings_form_submit(), so change #submit.
-  $form['#submit'] = array('system_theme_settings_submit');
+  array_pop($form['#submit']);
+  $form['#submit'][] = 'system_theme_settings_submit';
   return $form;
 }
 
Index: modules/system/system.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.install,v
retrieving revision 1.383
diff -u -p -r1.383 system.install
--- modules/system/system.install	29 Aug 2009 10:38:58 -0000	1.383
+++ modules/system/system.install	30 Aug 2009 15:47:42 -0000
@@ -1982,7 +1982,7 @@ function system_update_7017() {
   }
 
   // Unset deprecated 'toggle_node_info' theme settings.
-  $theme_settings = theme_get_settings();
+  $theme_settings = variable_get('theme_settings', array());
   foreach ($theme_settings as $setting => $value) {
     if (substr($setting, 0, 16) == 'toggle_node_info') {
       unset($theme_settings[$setting]);
Index: profiles/default/default.install
===================================================================
RCS file: /cvs/drupal/drupal/profiles/default/default.install,v
retrieving revision 1.2
diff -u -p -r1.2 default.install
--- profiles/default/default.install	27 Aug 2009 20:25:29 -0000	1.2
+++ profiles/default/default.install	30 Aug 2009 15:47:42 -0000
@@ -159,11 +159,6 @@ function default_install() {
   variable_set('user_picture_file_size', '800');
   variable_set('user_picture_style', 'thumbnail');
 
-  $theme_settings = theme_get_settings();
-  $theme_settings['toggle_node_user_picture'] = '1';
-  $theme_settings['toggle_comment_user_picture'] = '1';
-  variable_set('theme_settings', $theme_settings);
-
   // Create a default vocabulary named "Tags", enabled for the 'article' content type.
   $description = st('Use tags to group articles on similar topics into categories.');
   $help = st('Enter a comma-separated list of words to describe your content.');
