Index: includes/theme.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/theme.inc,v
retrieving revision 1.422
diff -u -r1.422 theme.inc
--- includes/theme.inc	6 May 2008 12:18:45 -0000	1.422
+++ includes/theme.inc	9 May 2008 19:40:02 -0000
@@ -1534,42 +1534,74 @@
 }
 
 /**
- * Format a username.
+ * Format the user's name for use in a title, node, or comment.
+ *
+ * Utilizes $user->name, or $user->displayed_name, depending on admin settings.
  *
  * @param $object
  *   The user object to format, usually returned from user_load().
+ * @param $displayname
+ *   Defaults to false because core needs usernames within it's admin tables, 
+ *   but themes can specify this parameter if they want to receive displayname.
+ * @param $truncate
+ *   Shortening the length of the returned name can prevent layout breakage.
+ * @param $length
+ *   The number of characters desired in the name. This integer is shortened by 
+ *   3 characters to allow a three-dot ellipse at the end of the truncated name.
  * @return
- *   A string containing an HTML link to the user's page if the passed object
- *   suggests that this is a site user. Otherwise, only the username is returned.
+ *   A string containing $user->name, or $user->displayed_name, depending on
+ *   admin settings. This string is formatted as an an HTML link to the user's
+ *   profile page if the passed object suggests that this is a site user.
+ *   If not a site user, only the string is returned.
  */
-function theme_username($object) {
-
-  if ($object->uid && $object->name) {
-    // Shorten the name when it is too long or it will break many tables.
-    if (drupal_strlen($object->name) > 20) {
-      $name = drupal_substr($object->name, 0, 15) . '...';
-    }
-    else {
-      $name = $object->name;
+function theme_username($object, $displayname = FALSE, $truncate = TRUE, $length = 20) {
+  // Should the displayed_name be absent from the $object, we're theming a node
+  //   or a comment, and need to know it's author.
+  if (variable_get('user_displayed_name', 0) && empty($object->displayed_name) && $displayname) {
+    $author = user_load($object->uid);
+    $name = $author->displayed_name;
+    // If the user has failed to enter a displayed_name, prevent an 'anonymous' displayname.
+    if (empty($object->displayed_name) && !$author->displayed_name) {
+      $name = t(variable_get('user_displayed_name_token', '...'));
     }
+  }
+  // Return the displayed_name if it's there.
+  elseif (variable_get('user_displayed_name', 0) && !empty($object->displayed_name) && $displayname) {
+    $name = $object->displayed_name;
+  }
+  else {
+    $name = $object->name;
+  }
 
-    if (user_access('access user profiles')) {
+  // Shorten the name when it is too long or it may break tables and blocks.
+  if (drupal_strlen($name) > $length && $truncate) {
+    $name = drupal_substr($name, 0, $length-3) . '...';
+  }
+  // If the current user owns this node (or comment), and they haven't created a
+  // Displayed Name yet, give them a call-to-action link to edit their profile. 
+  if ($object->uid && $name) {
+    global $user;
+    if ($object->uid == $user->uid && $name == variable_get('user_displayed_name_token', '...')) {
+      $name .=  '&nbsp;' . l(t('edit name'), 'user/' . $user->uid . '/edit');
+      $output = $name;
+    }
+    elseif (user_access('access user profiles')) {
       $output = l($name, 'user/' . $object->uid, array('attributes' => array('title' => t('View user profile.'))));
     }
     else {
       $output = check_plain($name);
     }
   }
-  else if ($object->name) {
+  elseif ($name) {
     // Sometimes modules display content composed by people who are
     // not registered members of the site (e.g. mailing list or news
     // aggregator modules). This clause enables modules to display
     // the true author of the content.
     if (!empty($object->homepage)) {
-      $output = l($object->name, $object->homepage, array('attributes' => array('rel' => 'nofollow')));
+      $output = l($name, $object->homepage, array('attributes' => array('rel' => 'nofollow')));
     }
     else {
-      $output = check_plain($object->name);
+      $output = check_plain($name);
     }
 
     $output .= ' (' . t('not verified') . ')';
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.961
diff -u -r1.961 node.module
--- modules/node/node.module	6 May 2008 12:18:48 -0000	1.961
+++ modules/node/node.module	9 May 2008 19:40:02 -0000
@@ -2467,14 +2467,14 @@
 }
 
 /**
- * Format the "Submitted by username on date/time" for each node
+ * Format the "Submitted by username on date/time" for each node.
  *
  * @ingroup themeable
  */
 function theme_node_submitted($node) {
-  return t('Submitted by !username on @datetime',
+  return t('Submitted by !name on @datetime',
     array(
-      '!username' => theme('username', $node),
+      '!name' => theme('username', $node, variable_get('user_displayed_name', 0)),
       '@datetime' => format_date($node->created),
     ));
 }
Index: modules/user/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.module,v
retrieving revision 1.907
diff -u -r1.907 user.module
--- modules/user/user.module	7 May 2008 19:34:24 -0000	1.907
+++ modules/user/user.module	9 May 2008 19:40:03 -0000
@@ -7,6 +7,7 @@
  */
 
 define('USERNAME_MAX_LENGTH', 60);
+define('DISPLAYED_NAME_MAX_LENGTH', 60); // TODO: Make this an admin-setting.
 define('EMAIL_MAX_LENGTH', 64);
 
 /**
@@ -370,6 +371,32 @@
   if (strlen($name) > USERNAME_MAX_LENGTH) return t('The username %name is too long: it must be %max characters or less.', array('%name' => $name, '%max' => USERNAME_MAX_LENGTH));
 }
 
+function user_validate_displayed_name($displayed_name) {
+  if (substr($displayed_name, 0, 1) == ' ') {
+    return t('Your Displayed Name cannot begin with a space.');
+  }
+  if (substr($displayed_name, -1) == ' ') {
+    return t('Your Displayed Name cannot end with a space.');
+  }
+  if (strpos($displayed_name, '  ') !== FALSE) {
+    return t('The Displayed Name field is not allowed to have multiple spaces between words.');
+  }
+  if (preg_match('/[\x{80}-\x{A0}' .           // Non-printable ISO-8859-1 + NBSP
+                   '\x{AD}' .                  // Soft-hyphen
+                   '\x{2028}-\x{202F}' .       // Bidirectional text overrides
+                   '\x{205F}-\x{206F}' .       // Various text hinting characters
+                   '\x{FEFF}' .                // Byte order mark
+                   '\x{FF01}-\x{FF60}' .       // Full-width latin
+                   '\x{FFF9}-\x{FFFD}' .       // Replacement characters
+                   '\x{0}]/u',                 // NULL byte
+                   $displayed_name)) {
+    return t('Your Displayed Name contains an illegal character.');
+  }
+  if (strlen($displayed_name) > DISPLAYED_NAME_MAX_LENGTH) {
+    return t('The Displayed Name you entered, "%displayed_name", is too long: it must be %max characters or less.', array('%displayed_name' => $displayed_name, '%max' => DISPLAYED_NAME_MAX_LENGTH));
+  }
+}
+
 function user_validate_mail($mail) {
   if (!$mail) {
     return t('You must enter an e-mail address.');
@@ -552,12 +579,18 @@
  * Implementation of hook_perm().
  */
 function user_perm() {
-   return array(
-     'administer permissions' => t('Manage the permissions assigned to user roles. %warning', array('%warning' => t('Warning: Give to trusted roles only; this permission has security implications.'))),
-     'administer users' => t('Manage or block users, and manage their role assignments.'),
-     'access user profiles' => t('View profiles of users on the site, which may contain personal information.'),
-     'change own username' => t('Select a different username.'),
-   );
+  $perms = array(
+   'administer permissions' => t('Manage the permissions assigned to user roles. %warning', array('%warning' => t('Warning: Give to trusted roles only; this permission has security implications.'))),
+   'administer users' => t('Manage or block users, and manage their role assignments.'),
+   'access user profiles' => t('View profiles of users on the site, which may contain personal information.'),
+   'change own username' => t('Select a different username.'),
+  );
+  // Add "Change own Displayed Name" settings, but only if the admin has enabled that feature.
+  if (variable_get('user_displayed_name', 0) && variable_get('user_displayed_name_editable', 0)) {
+    $perms['change own displayed name'] = t('Allow users to modify their "real name".');
+  }
+
+  return $perms;
 }
 
 /**
@@ -1136,7 +1169,12 @@
   if ($account->uid == $GLOBALS['user']->uid) {
     return t('My account');
   }
-  return $account->name;
+  else if (variable_get('user_displayed_name', 0)) {
+    return $account->displayed_name;
+  }
+  else {
+    return $account->name;
+  }
 }
 
 /**
@@ -1398,6 +1436,35 @@
       '#required' => TRUE,
     );
   }
+  // Figure out whether it's an anonymous user who's registering, a user who's
+  //   editing their own profile, or an admin who's creating new users by hand.
+  if (variable_get('user_displayed_name', 0) && $uid = 1) {
+    $sitecreator = TRUE;
+  }
+  if (variable_get('user_displayed_name_editable', 0) && (user_access('change own displayed name') || $register || $admin || $sitecreator)) {
+    $unique = variable_get('user_displayed_name_unique', 0);
+    // Get the value that was stored in this field from last time...
+    if ($edit['displayed_name']) {
+      $default_displayname = $edit['displayed_name'];
+    }
+    // If the user hasn't saved a Display Name before, default to their username,
+    // but make sure this isn't a site admin who's editing other users.
+    elseif (!$admin && $uid > 0) {
+      global $user;
+      $default_displayname = $user->name;
+    }
+    else {
+      $default_displayname = '';
+    }
+    $form['account']['displayed_name'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Displayed name'),
+      '#default_value' => $default_displayname,
+      '#maxlength' => DISPLAYED_NAME_MAX_LENGTH,
+      '#description' => theme_displayed_name_field_description($unique), // TODO: Figure out why this theme function doesn't work when called as theme('displayed_name_field_description').
+      '#required' => FALSE,
+    );
+  }
   $form['account']['mail'] = array('#type' => 'textfield',
     '#title' => t('E-mail address'),
     '#default_value' => $edit['mail'],
@@ -1501,6 +1568,16 @@
     }
   }
 
+  // Validate the displayed_name.
+  if (isset($edit['account']['displayed_name']) && ((user_access('change own displayed name') || user_access('administer users') || !$user->uid))) {
+    if ($error = user_validate_displayed_name($edit['account']['displayed_name'])) {
+      form_set_error('displayed_name', $error);
+    }
+    elseif (variable_get('user_displayed_name_unique', 0) && db_result(db_query("SELECT COUNT(*) FROM {users} WHERE uid != %d AND LOWER(name) = LOWER('%s')", $uid, $edit['displayed_name'])) > 0) {
+      form_set_error('displayed_name', t('%displayname is already taken by another user. Please choose another.', array('%displayname' => $edit['displayed_name'])));
+    }
+  }
+
   // Validate the e-mail address:
   if ($error = user_validate_mail($edit['mail'])) {
     form_set_error('mail', $error);
@@ -2299,6 +2376,9 @@
 /**
  * Form builder; The user registration form.
  *
+ * This form can be used by a first-time user who's registering,
+ *   or by an admin to create users manually.
+ *
  * @ingroup forms
  * @see user_register_validate()
  * @see user_register_submit()
@@ -2322,23 +2402,24 @@
 
   // Merge in the default user edit fields.
   $form = array_merge($form, user_edit_form($form_state, NULL, NULL, TRUE));
+  // Add a 'Notify User' checkbox if a site admin is creating new users manually.
   if ($admin) {
     $form['account']['notify'] = array(
      '#type' => 'checkbox',
      '#title' => t('Notify user of new account')
     );
+    // Show the Displayed Name field to admins who are creating new user accounts.
     // Redirect back to page which initiated the create request;
     // usually admin/user/user/create.
     $form['destination'] = array('#type' => 'hidden', '#value' => $_GET['q']);
   }
-
   // Create a dummy variable for pass-by-reference parameters.
   $null = NULL;
   $extra = _user_forms($null, NULL, NULL, 'register');
 
   // Remove form_group around default fields if there are no other groups.
   if (!$extra) {
-    foreach (array('name', 'mail', 'pass', 'status', 'roles', 'notify') as $key) {
+    foreach (array('name', 'displayed_name', 'mail', 'pass', 'status', 'roles', 'notify') as $key) {
       if (isset($form['account'][$key])) {
         $form[$key] = $form['account'][$key];
       }
@@ -2357,7 +2438,6 @@
       '#default_value' => variable_get('date_default_timezone', NULL),
       '#id' => 'edit-user-register-timezone',
     );
-
     // Add the JavaScript callback to automatically set the timezone.
     drupal_add_js('
 // Global Killswitch
@@ -2392,3 +2472,19 @@
 
   return empty($groups) ? FALSE : $groups;
 }
+
+/**
+ * THEME FUNCTIONS
+ */
+// When the user is editing their own account, this generates the descriptive
+//   text for the Displayed Name field.
+function theme_displayed_name_field_description($unique = FALSE) {
+  $output = 'This is your real name, as you would like it to appear to others. You may keep it the same as your username, or change it';
+  if ($unique) {
+    $output .= ', but it must be unique within this site';    
+  }
+  $output .= '.';
+  return t($output);
+}
+
+// Do not place any code below these theme functions. It makes them easy for themers to find.
\ No newline at end of file
Index: modules/user/user.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.js,v
retrieving revision 1.6
diff -u -r1.6 user.js
--- modules/user/user.js	12 Sep 2007 18:29:32 -0000	1.6
+++ modules/user/user.js	9 May 2008 19:40:02 -0000
@@ -177,12 +177,28 @@
 
 /**
  * On the admin/user/settings page, conditionally show all of the
- * picture-related form elements depending on the current value of the
- * "Picture support" radio buttons.
+ * related form elements depending on the current value of each
+ * fieldset's disabled/enabled radio buttons. (Use a separate declaration for
+ * each desired form element's toggling action.)
  */
 Drupal.behaviors.userSettings = function (context) {
   $('div.user-admin-picture-radios input[type=radio]:not(.userSettings-processed)', context).addClass('userSettings-processed').click(function () {
     $('div.user-admin-picture-settings', context)[['hide', 'show'][this.value]]();
   });
+  
+  $('div.user-admin-displayname-radios input[type=radio]:not(.userSettings-processed)', context).addClass('userSettings-processed').click(function () {
+    $('div.user-admin-displayname-settings', context)[['hide', 'show'][this.value]]();
+  });
+  
+  // Disable the Enforce Unique checkbox if the Allow Users To Edit checkbox
+  //   defaults to unchecked.
+  if (!$('input#edit-user-displayed-name-editable').attr('checked')) {
+    $('input#edit-user-displayed-name-unique').attr("disabled", "disabled");
+  }
+  // Re-enable the Enforce Unique checkbox.
+  $('input#edit-user-displayed-name-editable').click(function() {
+    $('input#edit-user-displayed-name-unique').removeAttr("disabled");
+  });
+  
+  
 };
-
Index: modules/user/user.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.pages.inc,v
retrieving revision 1.13
diff -u -r1.13 user.pages.inc
--- modules/user/user.pages.inc	14 Apr 2008 17:48:43 -0000	1.13
+++ modules/user/user.pages.inc	9 May 2008 19:40:03 -0000
@@ -147,7 +147,12 @@
  * Menu callback; Displays a user or user profile page.
  */
 function user_view($account) {
-  drupal_set_title(check_plain($account->name));
+  if (variable_get('user_displayed_name', 0) && $account->displayed_name) {
+    drupal_set_title(check_plain($account->displayed_name));
+  }
+  else {
+    drupal_set_title(check_plain($account->name));
+  }
   // Retrieve all profile fields and attach to $account->content.
   user_build_content($account);
 
Index: modules/user/user.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.admin.inc,v
retrieving revision 1.22
diff -u -r1.22 user.admin.inc
--- modules/user/user.admin.inc	7 May 2008 19:34:24 -0000	1.22
+++ modules/user/user.admin.inc	9 May 2008 19:40:02 -0000
@@ -132,6 +132,7 @@
   $header = array(
     array(),
     array('data' => t('Username'), 'field' => 'u.name'),
+    array('data' => t('Displayed Name'), 'field' => 'u.displayed_name'),
     array('data' => t('Status'), 'field' => 'u.status'),
     t('Roles'),
     array('data' => t('Member for'), 'field' => 'u.created', 'sort' => 'desc'),
@@ -139,7 +140,7 @@
     t('Operations')
   );
 
-  $sql = 'SELECT DISTINCT u.uid, u.name, u.status, u.created, u.access FROM {users} u LEFT JOIN {users_roles} ur ON u.uid = ur.uid ' . $filter['join'] . ' WHERE u.uid != 0 ' . $filter['where'];
+  $sql = 'SELECT DISTINCT u.uid, u.name, u.displayed_name, u.status, u.created, u.access FROM {users} u LEFT JOIN {users_roles} ur ON u.uid = ur.uid ' . $filter['join'] . ' WHERE u.uid != 0 ' . $filter['where'];
   $sql .= tablesort_sql($header);
   $query_count = 'SELECT COUNT(DISTINCT u.uid) FROM {users} u LEFT JOIN {users_roles} ur ON u.uid = ur.uid ' . $filter['join'] . ' WHERE u.uid != 0 ' . $filter['where'];
   $result = pager_query($sql, 50, 0, $query_count, $filter['args']);
@@ -400,6 +401,56 @@
     '#rows' => 3,
   );
 
+  // Add some jQuery for the show & hide functionality of these next elements.
+  drupal_add_js(drupal_get_path('module', 'user') . '/user.js');
+
+  // User's displayed name.
+  $displayed_name_support = variable_get('user_displayed_name', 0);
+  $form['displayname'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Displayed name'),
+  );
+  $form['displayname']['user_displayed_name'] = array(
+    '#type' => 'radios',
+    '#title' => t('Use displayed names instead of usernames'),
+    '#default_value' => variable_get('user_displayed_name', 0),
+    '#options' => array(t('Disabled'), t('Enabled')),
+    '#description' => t("Turning this option on will begin showing the user's 'real name', or 'displayed name', rather than the user's login name."),
+    '#prefix' => '<div class="user-admin-displayname-radios">',
+    '#suffix' => '</div>',
+  );
+  // If JS is enabled, and the radio is defaulting to off, hide all
+  // the settings on page load via .css using the js-hide class so
+  // that there's no flicker.
+  $css_class = 'user-admin-displayname-settings';
+  if (!$displayed_name_support) {
+    $css_class .= ' js-hide';
+  }
+  $form['displayname']['settings'] = array(
+    '#prefix' => '<div class="' . $css_class . '">',
+    '#suffix' => '</div>',
+  );
+  $form['displayname']['settings']['user_displayed_name_token'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Default name'),
+    '#default_value' => variable_get('user_displayed_name_token', 'Name withheld'),
+    '#description' => t('Default name to display if users have not chosen a custom Displayed Name.'),
+    '#size' => 20,
+    '#maxlength' => 20,
+  );
+  $form['displayname']['settings']['user_displayed_name_editable'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Allow users to change their own name'),
+    '#default_value' => variable_get('user_displayed_name_editable', 0),
+    '#description' => t('Allow all users to create and edit their Displayed Name. When this option is on, fine-grained settings can be found on the !permissions page.', array('!permissions' => l(t('User Permissions'), 'admin/user/permissions', array('fragment' => 'module-user')))),
+  );
+  $form['displayname']['settings']['user_displayed_name_unique'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Enforce unique displayed name'),
+    '#default_value' => variable_get('user_displayed_name_unique', 0),
+    '#description' => t('Force users to choose a one-of-a-kind nickname, or "real name" within this site. Requires the above setting, "Allow users to change their own name", to be enabled.'),
+  );
+
   // User signatures.
   $form['signatures'] = array(
     '#type' => 'fieldset',
@@ -418,6 +469,7 @@
     file_check_directory($picture_path, 1, 'user_picture_path');
   }
 
+  // User pictures.
   $form['pictures'] = array(
     '#type' => 'fieldset',
     '#title' => t('Pictures'),
@@ -431,7 +483,6 @@
     '#prefix' => '<div class="user-admin-picture-radios">',
     '#suffix' => '</div>',
   );
-  drupal_add_js(drupal_get_path('module', 'user') . '/user.js');
   // If JS is enabled, and the radio is defaulting to off, hide all
   // the settings on page load via .css using the js-hide class so
   // that there's no flicker.
@@ -482,7 +533,32 @@
     '#description' => t("This text is displayed at the picture upload form in addition to the default guidelines. It's useful for helping or instructing your users."),
   );
 
-  return system_settings_form($form);
+  $process_form = system_settings_form($form);
+  array_unshift($process_form['#submit'], 'user_admin_settings_submit');
+  return $process_form;
+}
+
+function user_admin_settings_submit($form, &$form_state) {
+  // Displayname is enabled and editable, and user_perm() will begin showing a 
+  // row for "Change own displayed name", so we need to default the permission
+  // checkbox for logged-in users so the admin can see that something's happened.
+  if ($form['displayname']['user_displayed_name']['#value'] && $form['displayname']['settings']['user_displayed_name_editable']['#value']) {
+    // Make sure the row doen't already exist, as in the case of a user submitting this same form again with differing settings.
+    $query = db_fetch_object(db_query("SELECT rid FROM {role_permission} WHERE permission = 'change own displayed name'"));
+    if (!$query) {
+      db_query("INSERT INTO {role_permission} (rid, permission) VALUES (%d, '%s')", 2, 'change own displayed name');
+    }
+    drupal_set_message(t('Since you enabled the "allow users to edit their own Displayed Name" option, 
+                          please take the time to confirm that your !permissions settings are also correct.', array('!permissions' => l(t('User Permissions'), 'admin/user/permissions', array('fragment' => 'module-user')))));
+  }
+  elseif ($form['displayname']['user_displayed_name']['#value'] && empty($form['displayname']['user_displayed_name_editable']['#value'])) {
+    // If an admin has enabled the Displayed Name option, but disabled the 
+    // 'editable' checkbox, go to the admin/user/permissions form and uncheck all
+    // boxes in the "Change own displayed name" row, because user_perm() will no
+    // longer be showing that row, and we can't have permissions enabled without
+    // being able to see them.
+    db_query("DELETE FROM {role_permission} WHERE permission = 'change own displayed name'");
+  }
 }
 
 /**
Index: modules/user/user.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.install,v
retrieving revision 1.12
diff -u -r1.12 user.install
--- modules/user/user.install	7 May 2008 19:34:24 -0000	1.12
+++ modules/user/user.install	9 May 2008 19:40:02 -0000
@@ -103,6 +103,13 @@
         'default' => '',
         'description' => t('Unique user name.'),
       ),
+      'displayed_name' => array(
+        'type' => 'varchar',
+        'length' => 60,
+        'not null' => FALSE,
+        'default' => '',
+        'description' => t('Real Name of user. Unique or non-unique is admin selectable.')
+      ),
       'pass' => array(
         'type' => 'varchar',
         'length' => 128,
@@ -296,3 +303,18 @@
  * The next series of updates should start at 8000.
  */
 
+/**
+ * Implementation of hook_update.
+ *
+ * Add a field called "displayed_name" to the Users table. Re: issue 102679.
+ */
+function user_update_8000() {
+  $ret = array();
+  db_add_field($ret, 'users', 'displayed_name', array('type' => 'varchar',
+                                                      'length' => 60,
+                                                      'not null' => FALSE,
+                                                      'default' => '',
+                                                      'description' => t('Real Name of user. Unique or non-unique is admin selectable.'),
+                                                      ));
+  return $ret;
+}
Index: modules/comment/comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v
retrieving revision 1.631
diff -u -r1.631 comment.module
--- modules/comment/comment.module	6 May 2008 12:18:47 -0000	1.631
+++ modules/comment/comment.module	9 May 2008 19:40:02 -0000
@@ -1715,9 +1715,9 @@
  * @ingroup themeable
  */
 function theme_comment_submitted($comment) {
-  return t('Submitted by !username on @datetime.',
+  return t('Submitted by !name on @datetime.',
     array(
-      '!username' => theme('username', $comment),
+      '!name' => theme('username', $node, variable_get('user_displayed_name', 0)),
       '@datetime' => format_date($comment->timestamp)
     ));
 }
Index: themes/garland/template.php
===================================================================
RCS file: /cvs/drupal/drupal/themes/garland/template.php,v
retrieving revision 1.18
diff -u -r1.18 template.php
--- themes/garland/template.php	28 Apr 2008 09:25:27 -0000	1.18
+++ themes/garland/template.php	9 May 2008 19:40:03 -0000
@@ -67,9 +67,9 @@
  * Format the "Submitted by username on date/time" for each comment.
  */
 function phptemplate_comment_submitted($comment) {
-  return t('!datetime — !username',
+  return t('!datetime — !name',
     array(
-      '!username' => theme('username', $comment),
+      '!name' => theme('username', $comment, TRUE, FALSE),
       '!datetime' => format_date($comment->timestamp)
     ));
 }
@@ -78,9 +78,9 @@
  * Format the "Submitted by username on date/time" for each node.
  */
 function garland_node_submitted($node) {
-  return t('!datetime — !username',
+  return t('!datetime — !name',
     array(
-      '!username' => theme('username', $node),
+      '!name' => theme('username', $node, TRUE, FALSE),
       '!datetime' => format_date($node->created),
     ));
 }
