diff -pruN gnome-terminal/ChangeLog gnome-terminal-connect/ChangeLog
--- gnome-terminal/ChangeLog	2005-08-08 16:33:32.000000000 +0200
+++ gnome-terminal-connect/ChangeLog	2005-08-14 20:00:10.992749160 +0200
@@ -1,3 +1,61 @@
+2005-08-14  Martin Ejdestig  <mejde@dtek.chalmers.se>
+
+	* src/connect-to-server.c:
+	* src/connect-to-server.h:
+	New files for dialog to connect to SSH and Telnet servers with support
+	for Zeroconf and lock down.
+
+	* src/terminal.c (parse_options_callback) 
+	(option_parsing_results_init, main, handle_new_terminal_event):
+	Add --connect-to-server argument to bring up connect dialog.
+
+	* src/terminal-window.c (terminal_window_init)
+	(update_disconnect_sensitivity, terminal_window_set_active)
+	(connect_to_server_callback, disconnect_from_server_callback):
+	Add Connect to Server... and Disconnect from Server menu items.
+
+	* src/terminal-window.c (terminal_window_finalize)
+	(terminal_window_add_screen, terminal_window_remove_screen)
+	(screen_set_label_icon, screen_get_label_icon, get_connect_icon) 
+	(terminal_window_update_icon, terminal_window_set_connected):
+	* src/terminal-window.h: 
+	Display an icon in the tab label and change the window icon to
+	gnome-terminal-connect.png if screen is connected.
+
+	* src/terminal-screen.c	(terminal_screen_widget_child_died):
+	Special	case if child dies and connected to server.
+
+	* src/encoding.c (update_active_encodings_from_string_list):
+	* src/terminal.c (sync_profile_list):
+	Call terminal_connect_to_server_reread_encodings () when encodings are
+	updated and terminal_connect_to_server_reread_profiles () when profiles
+	are updated.
+
+	* src/terminal-accels.c:
+	* src/terminal-accels.h: 
+	Add ACCEL_PATH_CONNECT_TO_SERVER and ACCEL_PATH_DISCONNECT_FROM_SERVER..
+
+	* src/gnome-terminal.schemas.in:
+	Add global/server_expanded, global/servers_list, 
+	keybindings/connect_to_server and keybindings/connect_to_server.
+
+	* src/gnome-terminal.glade2:
+	Added connect-to-server-dialog and server-editor-dialog.
+
+	* src/Makefile.am:
+	Add connect-to-server.[ch] and gnome-terminal-connect.png.
+
+2005-08-14  Martin Ejdestig  <mejde@dtek.chalmers.se>
+
+	* src/terminal-window.c (new_window_callback, new_tab_callback):
+	* src/terminal-screen.c (new_window_callback, new_tab_callback):
+	* src/terminal.c (new_terminal_with_options, terminal_app_new_terminal):
+	Add encoding argument to terminal_app_new_terminal ().
+
+	* src/terminal.c (terminal_app_get_windows)
+	* src/terminal.h:
+	New function to get the current windows in a TerminalApp.
+
 2005-08-08  Dennis Cranston <dennis_cranston@yahoo.com>
 
 	* src/terminal-window.c: (confirm_close_window): HIG fixes
diff -pruN gnome-terminal/src/connect-to-server.c gnome-terminal-connect/src/connect-to-server.c
--- gnome-terminal/src/connect-to-server.c	1970-01-01 01:00:00.000000000 +0100
+++ gnome-terminal-connect/src/connect-to-server.c	2005-08-14 19:58:55.385243248 +0200
@@ -0,0 +1,2293 @@
+/* dialog for connecting to ssh and telnet servers */
+
+/*
+ * Copyright (C) 2005 Martin Ejdestig <mejde@dtek.chalmers.se>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* Servers are stored in gconf:
+ *   /apps/gnome-terminal/global/server_list
+ *   /apps/gnome-terminal/servers/server_foo
+ *
+ * server_list, similar to profile_list, contains a list of server ids. For each
+ * id there is a directory in /apps/gnome-terminal/servers with the name id
+ * where all server information is stored.
+ *
+ * Servers are stored in memory with a hash table (servers) using id as key.
+ * A hash table (connected_servers) of servers with TerminalScreen pointers as
+ * keys is also used to keep track of which servers are currently in use with
+ * which screens.
+ *
+ * Servers discovered via Zeroconf are stored in gconf with the other servers
+ * in a dir named zc_<service name> and added to the servers hash table.
+ * However, they aren't added to server_list since they are volatile. The gconf
+ * dirs aren't removed when they disappear. That way, any customization like
+ * encoding, user_name, etc are preserved until the servers reappear.
+ */
+
+#include "connect-to-server.h"
+#include "encoding.h"
+#include "terminal.h"
+#include "terminal-profile.h"
+#include "terminal-screen.h"
+#include "terminal-widget.h"
+#include "terminal-window.h"
+#include <gconf/gconf-client.h>
+#include <glade/glade.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <libgnomevfs/gnome-vfs-dns-sd.h>
+#include <string.h>
+
+
+typedef enum
+{
+  /* This has to be kept in sync with the combo box in the glade file. */
+  SERVER_TYPE_SSH,
+  SERVER_TYPE_TELNET
+} ServerType;
+
+static GConfEnumStringPair server_types[] = {
+  { SERVER_TYPE_SSH, "ssh" },
+  { SERVER_TYPE_TELNET, "telnet" },
+  { -1, NULL }
+};
+
+typedef struct
+{
+  unsigned int name : 1;
+  unsigned int server : 1;
+  unsigned int port : 1;
+  unsigned int user_name : 1;
+  unsigned int type : 1;
+  unsigned int encoding : 1;
+  unsigned int profile : 1;
+} ServerSettingMask;
+
+typedef struct
+{
+  char *id;
+
+  char *name;
+  char *server;
+  char *port;
+  char *user_name;
+  ServerType type;
+  char *encoding;
+  char *profile;
+
+  ServerSettingMask locked;
+
+  GtkWidget *dialog;
+  GSList *dialog_encodings;
+  GList *dialog_profiles;
+
+  char *conf_dir;
+  guint notify_id;
+} Server;
+
+enum
+{
+  COLUMN_SERVER,
+  COLUMN_ICON,
+  COLUMN_NAME,
+  COLUMN_LAST
+};
+
+#define DIALOG_GLADE_XML_KEY "glade-xml"
+#define DIALOG_ROW_REFS_KEY "row-refs"
+
+#define CONNECT_TO_SERVER_DIALOG "connect-to-server-dialog"
+#define CONNECT_SERVERS_TREEVIEW "connect-servers-treeview"
+#define CONNECT_NEW_BUTTON "connect-new-button"
+#define CONNECT_EDIT_BUTTON "connect-edit-button"
+#define CONNECT_EDIT_BUTTON "connect-edit-button"
+#define CONNECT_DELETE_BUTTON "connect-delete-button"
+#define CONNECT_CONNECT_BUTTON "connect-connect-button"
+
+#define SERVER_EDITOR_DIALOG "server-editor-dialog"
+#define SERVER_LOCKED_WARNING "server-locked-warning"
+#define SERVER_LOCKED_LABEL "server-locked-label"
+#define SERVER_OPTIONAL_EXPANDER "server-optional-expander"
+#define SERVER_NAME_ENTRY "server-name-entry"
+#define SERVER_SERVER_ENTRY "server-server-entry"
+#define SERVER_PORT_ENTRY "server-port-entry"
+#define SERVER_USER_NAME_ENTRY "server-user-name-entry"
+#define SERVER_TYPE_COMBOBOX "server-type-combobox"
+#define SERVER_ENCODING_COMBOBOX "server-encoding-combobox"
+#define SERVER_PROFILE_COMBOBOX "server-profile-combobox"
+
+#define CONF_SERVER_ID_LIST CONF_GLOBAL_PREFIX"/server_list"
+#define CONF_SERVER_ID_DNS_SD_PREFIX "zc_"
+#define CONF_SERVERS_PREFIX CONF_PREFIX"/servers"
+#define CONF_SERVER_EXPANDED CONF_GLOBAL_PREFIX"/server_expanded"
+
+
+static GConfClient *global_conf = NULL;
+
+static GHashTable *servers = NULL;
+static GHashTable *connected_servers = NULL;
+
+static GtkWidget *connect_dialog = NULL;
+
+static GnomeVFSDNSSDBrowseHandle *dns_sd_browse_handles[2] = { NULL, NULL };
+static GSList *dns_sd_resolve_handles = NULL;
+
+
+static void server_remove_from_connected (Server         *server,
+                                          TerminalScreen *screen,
+                                          gboolean       keep_screen);
+static void server_set_locked (Server            *server,
+                               ServerSettingMask *locked);
+
+static void server_dialog_update_entry (Server     *server,
+                                        const char *text,
+                                        const char *widget);
+static void server_dialog_update_combo_box (Server     *server,
+                                            int         index,
+                                            const char *widget);
+static void server_dialog_update_title (Server *server);
+static void server_dialog_update_sensitive (Server *server);
+static int  server_dialog_encoding_index (Server *server);
+static int  server_dialog_profile_index (Server *server);
+
+static void connect_dialog_list_store_update (GtkWidget *dialog,
+                                              Server *server);
+static void connect_dialog_treeview_select_and_scroll_to (GtkWidget *dialog,
+                                                          Server    *server);
+static void connect_dialog_list_store_append (GtkWidget *dialog,
+                                              Server *server);
+static void connect_dialog_list_store_remove (GtkWidget *dialog,
+                                              Server *server);
+static Server* connect_dialog_get_selected_server (GtkWidget *dialog);
+static void    connect_dialog_update_sensitive (GtkWidget *dialog,
+                                                Server    *server);
+
+
+static GtkWidget*
+get_widget (GtkWidget  *dialog,
+            const char *widget)
+{
+  GladeXML *xml;
+  GtkWidget *w;
+
+  xml = g_object_get_data (G_OBJECT (dialog), DIALOG_GLADE_XML_KEY);
+
+  w = glade_xml_get_widget (xml, widget);
+
+  if (!w)
+    g_error ("No such widget %s", widget);
+
+  return w;
+}
+
+static void
+server_setting_mask_clear (ServerSettingMask *mask)
+{
+  memset (mask, '\0', sizeof (*mask));
+}
+
+static gboolean
+server_setting_mask_equal (const ServerSettingMask *a,
+                           const ServerSettingMask *b)
+{
+  return memcmp (a, b, sizeof (*a)) == 0;
+}
+
+static gboolean
+server_setting_mask_is_empty (const ServerSettingMask *mask)
+{
+  ServerSettingMask empty;
+
+  server_setting_mask_clear (&empty);
+
+  return server_setting_mask_equal (&empty, mask);
+}
+
+/* invalid_chars is from gconf_valid_key () with / added (don't want subdirs) */
+static gboolean
+valid_gconf_key_char (char c)
+{
+  static const char invalid_chars[] = " \t\r\n\"$&<>,/+=#!()'|{}[]?~`;%\\";
+  int i;
+
+  if ((unsigned char) c > 127)
+    return FALSE;
+
+  for (i = 0; invalid_chars[i] != '\0'; i++)
+    if (c == invalid_chars[i])
+      return FALSE;
+
+  return TRUE;
+}
+
+static char*
+server_create_dns_sd_id (const char *name)
+{
+  GString *id;
+  const char *s;
+
+  id = g_string_new (CONF_SERVER_ID_DNS_SD_PREFIX);
+
+  for (s = name; *s != '\0'; s++)
+    {
+      if (valid_gconf_key_char (*s))
+        g_string_append_c (id, *s);
+      else
+        g_string_append_printf (id, "%02x", (unsigned int) *s);
+    }
+
+  return g_string_free (id, FALSE);
+}
+
+static gboolean
+server_is_dns_sd (Server *server)
+{
+  return g_str_has_prefix (server->id, CONF_SERVER_ID_DNS_SD_PREFIX);
+}
+
+static const char*
+server_get_icon_stock_id (Server *server)
+{
+  const char *stock_id;
+
+  if (server_is_dns_sd (server))
+    stock_id = GTK_STOCK_NETWORK;
+  else if (!server_setting_mask_is_empty (&server->locked))
+    /* FIXME: Use proper stock icon when bug #313275 is fixed */
+    stock_id = GTK_STOCK_DIALOG_AUTHENTICATION;
+  else
+    stock_id = NULL;
+
+  return stock_id;
+}
+
+static gboolean
+server_update_str (char       **member,
+                   const char  *new_str)
+{
+  g_return_val_if_fail (new_str, FALSE);
+
+  if (*member && strcmp (*member, new_str) == 0)
+      return FALSE;
+
+  g_free (*member);
+  *member = g_strdup (new_str);
+
+  return TRUE;
+}
+
+static void
+server_update_name (Server     *server,
+                    const char *name)
+{
+  if (!server_update_str (&server->name, name))
+    return;
+
+  server_dialog_update_entry (server, server->name,
+                              SERVER_NAME_ENTRY);
+  server_dialog_update_title (server);
+
+  if (connect_dialog)
+    {
+        connect_dialog_list_store_update (connect_dialog, server);
+
+        /* Make sure server being edited is still visible after name changed */
+        if (server->dialog)
+          connect_dialog_treeview_select_and_scroll_to (connect_dialog, server);
+    }
+}
+
+static void
+server_update_server (Server     *server,
+                      const char *server_str)
+{
+  if (!server_update_str (&server->server, server_str))
+    return;
+
+  server_dialog_update_entry (server, server->server,
+                              SERVER_SERVER_ENTRY);
+
+  if (connect_dialog)
+    if (connect_dialog_get_selected_server (connect_dialog) == server)
+      connect_dialog_update_sensitive (connect_dialog, server);
+}
+
+static void
+server_update_port (Server     *server,
+                    const char *port)
+{
+  if (!server_update_str (&server->port, port))
+    return;
+
+  server_dialog_update_entry (server, server->port,
+                              SERVER_PORT_ENTRY);
+}
+
+static void
+server_update_user_name (Server     *server,
+                         const char *user_name)
+{
+  if (!server_update_str (&server->user_name, user_name))
+    return;
+
+  server_dialog_update_entry (server, server->user_name,
+                              SERVER_USER_NAME_ENTRY);
+}
+
+static void
+server_update_type (Server     *server,
+                    const char *type_str)
+{
+  int type;
+
+  g_return_if_fail (type_str);
+  g_return_if_fail (gconf_string_to_enum (server_types, type_str, &type));
+
+  if (type == server->type)
+    return;
+
+  server->type = type;
+
+  server_dialog_update_combo_box (server, server->type,
+                                  SERVER_TYPE_COMBOBOX);
+}
+
+static void
+server_update_encoding (Server     *server,
+                        const char *encoding)
+{
+  if (!server_update_str (&server->encoding, encoding))
+    return;
+
+  server_dialog_update_combo_box (server, server_dialog_encoding_index (server),
+                                  SERVER_ENCODING_COMBOBOX);
+}
+
+static void
+server_update_profile (Server     *server,
+                       const char *profile)
+{
+  if (!server_update_str (&server->profile, profile))
+    return;
+
+  server_dialog_update_combo_box (server, server_dialog_profile_index (server),
+                                  SERVER_PROFILE_COMBOBOX);
+}
+
+/* Called when a server key is updated in gconf */
+static void
+server_change_notify (GConfClient *client,
+                      guint        cnxn_id,
+                      GConfEntry  *entry,
+                      Server      *server)
+{
+  ServerSettingMask locked;
+  const char *key;
+  GConfValue *val;
+
+  server_setting_mask_clear (&locked);
+
+  key = (const char *) strrchr (gconf_entry_get_key (entry), '/');
+  g_return_if_fail (key);
+  key++;
+
+  val = gconf_entry_get_value (entry);
+
+#define UPDATE_STRING(s)                                                \
+  }                                                                     \
+else if (strcmp (key, #s) == 0)                                         \
+  {                                                                     \
+    const char *setting = NULL;                                         \
+                                                                        \
+    if (val && val->type == GCONF_VALUE_STRING)                         \
+      setting = gconf_value_get_string (val);                           \
+                                                                        \
+    server_update_##s (server, setting);                                \
+                                                                        \
+    locked.s = !gconf_entry_get_is_writable (entry);
+
+ if (0)
+   {
+     ;
+     UPDATE_STRING (name);
+     UPDATE_STRING (server);
+     UPDATE_STRING (port);
+     UPDATE_STRING (user_name);
+     UPDATE_STRING (type);
+     UPDATE_STRING (encoding);
+     UPDATE_STRING (profile);
+   }
+
+#undef UPDATE_STRING
+
+  if (!server_setting_mask_equal (&locked, &server->locked))
+    server_set_locked (server, &locked);
+}
+
+/* Force update of server's members from gconf */
+static void
+server_update (Server *server)
+{
+  ServerSettingMask locked;
+
+  server_setting_mask_clear (&locked);
+
+#define UPDATE_STRING(s)                                                \
+  {                                                                     \
+    char *key = gconf_concat_dir_and_key (server->conf_dir, #s);        \
+    char *val = gconf_client_get_string (global_conf, key, NULL);       \
+                                                                        \
+    server_update_##s (server, val);                                    \
+                                                                        \
+    locked.s = !gconf_client_key_is_writable (global_conf, key, NULL);  \
+                                                                        \
+    g_free (val);                                                       \
+    g_free (key);                                                       \
+  }
+
+  UPDATE_STRING (name);
+  UPDATE_STRING (server);
+  UPDATE_STRING (port);
+  UPDATE_STRING (user_name);
+  UPDATE_STRING (type);
+  UPDATE_STRING (encoding);
+  UPDATE_STRING (profile);
+
+#undef UPDATE_STRING
+
+  if (!server_setting_mask_equal (&locked, &server->locked))
+    server_set_locked (server, &locked);
+}
+
+static Server*
+server_new (const char *id)
+{
+  Server *server;
+  GError *err;
+
+  server = g_new (Server, 1);
+  server->id = g_strdup (id);
+
+  server->name = NULL;
+  server->server = NULL;
+  server->port = NULL;
+  server->user_name = NULL;
+  server->type = -1;
+  server->encoding = NULL;
+  server->profile = NULL;
+
+  server_setting_mask_clear (&server->locked);
+
+  server->dialog = NULL;
+  server->dialog_encodings = NULL;
+  server->dialog_profiles = NULL;
+
+  server->conf_dir = gconf_concat_dir_and_key (CONF_SERVERS_PREFIX, id);
+
+  err = NULL;
+  gconf_client_add_dir (global_conf,
+                        server->conf_dir,
+                        GCONF_CLIENT_PRELOAD_ONELEVEL,
+                        &err);
+  if (err)
+    {
+      g_printerr (_("There was an error loading server config from %s. (%s)\n"),
+                  server->conf_dir, err->message);
+      g_error_free (err);
+    }
+
+  err = NULL;
+  server->notify_id =
+    gconf_client_notify_add (global_conf,
+                             server->conf_dir,
+                             (GConfClientNotifyFunc) server_change_notify,
+                             server,
+                             NULL, &err);
+  if (err)
+    {
+      g_printerr (_("There was an error subscribing to notification of "
+                    "terminal server changes. (%s)\n"), err->message);
+      g_error_free (err);
+    }
+
+  g_hash_table_insert (servers, server->id, server);
+
+  if (connect_dialog)
+    connect_dialog_list_store_append (connect_dialog, server);
+
+  return server;
+}
+
+static void
+server_remove_from_connected_foreach (TerminalScreen *screen,
+                                      Server         *server,
+                                      Server         *remove_server)
+{
+  if (server == remove_server)
+    /* Assumes modifying value while calling g_hash_table_foreach () is ok */
+    server_remove_from_connected (server, screen, TRUE);
+}
+
+static void
+server_free (Server *server)
+{
+  GError *err;
+
+  if (connect_dialog)
+    connect_dialog_list_store_remove (connect_dialog, server);
+
+  g_hash_table_foreach (connected_servers,
+                        (GHFunc) server_remove_from_connected_foreach,
+                        server);
+
+  g_hash_table_remove (servers, server->id);
+
+  gconf_client_notify_remove (global_conf,
+                              server->notify_id);
+  err = NULL;
+  gconf_client_remove_dir (global_conf,
+                           server->conf_dir,
+                           &err);
+  if (err)
+    {
+      g_printerr (_("There was an error while removing the configuration "
+                    "directory %s. (%s)\n"), server->conf_dir, err->message);
+      g_error_free (err);
+    }
+
+  g_free (server->conf_dir);
+
+  if (server->dialog)
+    gtk_widget_destroy (server->dialog);
+
+  if (server->dialog_encodings)
+    {
+      g_slist_foreach (server->dialog_encodings,
+                       (GFunc) terminal_encoding_free, NULL);
+      g_slist_free (server->dialog_encodings);
+    }
+
+  if (server->dialog_profiles)
+    {
+      g_list_foreach (server->dialog_profiles, (GFunc) g_object_unref, NULL);
+      g_list_free (server->dialog_profiles);
+    }
+
+  g_free (server->name);
+  g_free (server->server);
+  g_free (server->port);
+  g_free (server->user_name);
+  g_free (server->encoding);
+  g_free (server->profile);
+
+  g_free (server->id);
+  g_free (server);
+}
+
+static void
+server_set_locked (Server            *server,
+                   ServerSettingMask *locked)
+{
+  server->locked = *locked;
+
+  if (server_is_dns_sd (server))
+    {
+      /* Lock these for dns sd servers no matter what */
+      server->locked.name = TRUE;
+      server->locked.type = TRUE;
+      server->locked.server = TRUE;
+      server->locked.port = TRUE;
+    }
+
+  if (connect_dialog)
+    {
+      if (connect_dialog_get_selected_server (connect_dialog) == server)
+        connect_dialog_update_sensitive (connect_dialog, server);
+
+      connect_dialog_list_store_update (connect_dialog, server);
+    }
+
+  server_dialog_update_sensitive (server);
+}
+
+static void
+server_set_str (Server     *server,
+                const char *member,
+                const char *key,
+                const char *str)
+{
+  char *full_key;
+
+  g_return_if_fail (str);
+
+  if (member && strcmp (member, str) == 0)
+    return;
+
+  full_key = gconf_concat_dir_and_key (server->conf_dir, key);
+
+  gconf_client_set_string (global_conf,
+                           full_key,
+                           str,
+                           NULL);
+  g_free (full_key);
+}
+
+static void
+server_set_name (Server     *server,
+                 const char *name)
+{
+  server_set_str (server, server->name, "name", name);
+}
+
+static void
+server_set_server (Server     *server,
+                   const char *server_str)
+{
+  server_set_str (server, server->server, "server", server_str);
+}
+
+static void
+server_set_port (Server     *server,
+                 const char *port)
+{
+  server_set_str (server, server->port, "port", port);
+}
+
+static void
+server_set_user_name (Server     *server,
+                      const char *user_name)
+{
+  server_set_str (server, server->user_name, "user_name", user_name);
+}
+
+static void
+server_set_type (Server    *server,
+                 ServerType type)
+{
+  char *key;
+  const char *type_str;
+
+  if (server->type == type)
+    return;
+
+  key = gconf_concat_dir_and_key (server->conf_dir, "type");
+  type_str = gconf_enum_to_string (server_types, type);
+
+  gconf_client_set_string (global_conf,
+                           key,
+                           type_str,
+                           NULL);
+  g_free (key);
+}
+
+static void
+server_set_encoding (Server     *server,
+                     const char *encoding)
+{
+  server_set_str (server, server->encoding, "encoding", encoding);
+}
+
+static void
+server_set_profile (Server     *server,
+                    const char *profile)
+{
+  server_set_str (server, server->profile, "profile", profile);
+}
+
+static void
+server_set_defaults (Server *server)
+{
+  const char *encoding, *profile = NULL;
+
+  g_get_charset (&encoding);
+
+  if (terminal_profile_get_default ())
+    profile = terminal_profile_get_name (terminal_profile_get_default ());
+
+  server_set_name (server, _("New Server"));
+  server_set_server (server, "");
+  server_set_port (server, "");
+  server_set_user_name (server, g_get_user_name ());
+  server_set_type (server, SERVER_TYPE_SSH);
+  server_set_encoding (server, encoding);
+  server_set_profile (server, profile);
+}
+
+/* FIXME: Race condition in server id list handling when someone else adds or
+ * removes at the same time; just do what Havoc did with profiles... punt it :)
+ */
+static Server*
+server_create (void)
+{
+  GSList *ids;
+  char *id;
+  int i;
+  Server *server;
+
+  /* Find new id */
+  for (i = 1, id = NULL; id == NULL; i++)
+    {
+      id = g_strdup_printf ("%s_%d", "server", i);
+
+      if (g_hash_table_lookup (servers, id))
+        {
+          g_free (id);
+          id = NULL;
+        }
+    }
+
+  /* Create server with default values */
+  server = server_new (id);
+  server_set_defaults (server);
+
+  /* Save new id list */
+  ids = gconf_client_get_list (global_conf,
+                               CONF_SERVER_ID_LIST,
+                               GCONF_VALUE_STRING,
+                               NULL);
+
+  ids = g_slist_prepend (ids, id);
+
+  gconf_client_set_list (global_conf,
+                         CONF_SERVER_ID_LIST,
+                         GCONF_VALUE_STRING,
+                         ids,
+                         NULL);
+
+  /* Free ids (note that "char *id" is freed along with all other ids) */
+  g_slist_foreach (ids, (GFunc) g_free, NULL);
+  g_slist_free (ids);
+
+  /* No notification is sent for already existing keys with same values as we
+   * set above and there's no guarantee when we will get notified about other
+   * keys. Read it all from gconf now to make sure structure is in sync.
+   */
+  server_update (server);
+
+  return server;
+}
+
+static void
+server_remove (Server *server)
+{
+  GSList *ids, *tmp;
+
+  /* Remove id from id list */
+  ids = gconf_client_get_list (global_conf,
+                               CONF_SERVER_ID_LIST,
+                               GCONF_VALUE_STRING,
+                               NULL);
+
+  for (tmp = ids; tmp; tmp = tmp->next)
+    {
+      char *id = tmp->data;
+
+      if (strcmp (server->id, id) == 0)
+        {
+          g_free (id);
+          ids = g_slist_delete_link (ids, tmp);
+          break;
+        }
+    }
+
+  gconf_client_set_list (global_conf,
+                         CONF_SERVER_ID_LIST,
+                         GCONF_VALUE_STRING,
+                         ids,
+                         NULL);
+
+  g_slist_foreach (ids, (GFunc) g_free, NULL);
+  g_slist_free (ids);
+
+  /* Remove server from gconf and free */
+  gconf_client_recursive_unset (global_conf,
+                                server->conf_dir,
+                                GCONF_UNSET_INCLUDING_SCHEMA_NAMES,
+                                NULL);
+
+  server_free (server);
+}
+
+static Server*
+server_from_conf (const char *id)
+{
+  Server *server;
+
+  server = server_new (id);
+  server_update (server);
+
+  return server;
+}
+
+static Server*
+server_from_dns_sd (const char *name,
+                    ServerType  type,
+                    const char *host,
+                    const char *port,
+                    const char *user_name)
+{
+  ServerSettingMask locked;
+  Server *server;
+  char *id;
+
+  id = server_create_dns_sd_id (name);
+  server = server_new (id);
+  g_free (id);
+
+  if (!gconf_client_dir_exists (global_conf, server->conf_dir, NULL))
+    server_set_defaults (server);  /* We haven't seen this server before */
+
+  server_update (server);          /* Make sure struct is in sync */
+
+  locked = server->locked;
+
+  server_set_name (server, name);
+  locked.name = TRUE;
+  server_set_type (server, type);
+  locked.type = TRUE;
+  server_set_server (server, host);
+  locked.server = TRUE;
+  server_set_port (server, port);
+  locked.port = TRUE;
+
+  if (user_name)
+    {
+      server_set_user_name (server, user_name);
+      locked.user_name = TRUE;
+    }
+
+  server_set_locked (server, &locked);
+
+  return server;
+}
+
+static void
+server_remove_dns_sd (const char *name)
+{
+  char *id;
+  Server *server;
+
+  id = server_create_dns_sd_id (name);
+  server = g_hash_table_lookup (servers, id);
+  g_free (id);
+
+  /* Only free (keep customizations in conf_dir until it shows up again) */
+  if (server)
+    server_free (server);
+}
+
+static char**
+server_build_command (Server *server)
+{
+  const char *program, *program_name, *user_format, *port_format;
+  char *tmp, *user, *port, *cmd;
+  char **argv;
+
+  g_return_val_if_fail (server->server, NULL);
+  g_return_val_if_fail (server->port, NULL);
+  g_return_val_if_fail (server->user_name, NULL);
+
+  switch (server->type)
+    {
+    case SERVER_TYPE_SSH:
+      program = "ssh";
+      program_name = _("SSH");
+      user_format = "-l %s";
+      port_format = "-p %s";
+      break;
+    case SERVER_TYPE_TELNET:
+      program = "telnet";
+      program_name = _("Telnet");
+      user_format = "-l %s";
+      port_format = "%s";
+      break;
+    default:
+      g_return_val_if_reached (NULL);
+      break;
+    }
+
+  /* Make sure program exists */
+  tmp = g_find_program_in_path (program);
+
+  if (!tmp)
+    {
+      terminal_util_show_error_dialog (GTK_WINDOW (connect_dialog), NULL,
+                                       _("Unable to find %s program."),
+                                       program_name);
+      return NULL;
+    }
+
+  g_free (tmp);
+
+  /* Build command */
+  if (strcmp (server->port, "") != 0)
+    port = g_strdup_printf (port_format, server->port);
+  else
+    port = g_strdup ("");
+
+  if (strcmp (server->user_name, "") != 0 &&
+      strcmp (server->user_name, g_get_user_name ()) != 0)
+    user = g_strdup_printf (user_format, server->user_name);
+  else
+    user = g_strdup ("");
+
+  cmd = g_strdup_printf ("%s %s %s %s", program, user, port, server->server);
+
+  if (!g_shell_parse_argv (cmd, NULL, &argv, NULL))
+    {
+      argv = NULL;
+      terminal_util_show_error_dialog (GTK_WINDOW (connect_dialog), NULL,
+                                       _("Error when setting up %s program."),
+                                       program_name);
+    }
+
+  g_free (user);
+  g_free (port);
+  g_free (cmd);
+
+  return argv;
+}
+
+static void
+server_screen_profile_set (TerminalScreen *screen,
+                           Server         *server)
+{
+  TerminalProfile *profile = terminal_screen_get_profile (screen);
+
+  if (!server->locked.profile)
+    server_set_profile (server, terminal_profile_get_name (profile));
+}
+
+static void
+server_screen_encoding_set (TerminalScreen *screen,
+                            Server         *server)
+{
+  GtkWidget *widget = terminal_screen_get_widget (screen);
+
+  if (!server->locked.encoding)
+    server_set_encoding (server, terminal_widget_get_encoding (widget));
+}
+
+static void
+server_add_to_connected (Server         *server,
+                         TerminalScreen *screen)
+{
+  g_hash_table_insert (connected_servers, screen, server);
+
+  g_signal_connect (G_OBJECT (screen),
+                    "profile_set",
+                    G_CALLBACK (server_screen_profile_set),
+                    server);
+
+  g_signal_connect (G_OBJECT (screen),
+                    "encoding_changed",
+                    G_CALLBACK (server_screen_encoding_set),
+                    server);
+}
+
+/* server can be NULL (means it has been removed while connected).
+ * keep_screen means hash entry should be kept but with value set to NULL
+ * (server is about to be removed while screen is still connected).
+ */
+static void
+server_remove_from_connected (Server         *server,
+                              TerminalScreen *screen,
+                              gboolean       keep_screen)
+{
+  if (keep_screen)
+    g_hash_table_insert (connected_servers, screen, NULL);
+  else
+    g_hash_table_remove (connected_servers, screen);
+
+  if (server != NULL)
+    {
+      g_signal_handlers_disconnect_by_func (G_OBJECT (screen),
+                                            G_CALLBACK (server_screen_profile_set),
+                                            server);
+      g_signal_handlers_disconnect_by_func (G_OBJECT (screen),
+                                            G_CALLBACK (server_screen_encoding_set),
+                                            server);
+    }
+}
+
+static gboolean
+server_connect (Server *server)
+{
+  GtkWindow *window;
+  char **cmd;
+  TerminalScreen *screen;
+
+  g_return_val_if_fail (server->encoding, FALSE);
+  g_return_val_if_fail (server->profile, FALSE);
+
+  /* If there is no terminal window we force the opening of a new one */
+  window = NULL;
+
+  if (connect_dialog)
+    {
+      window = gtk_window_get_transient_for (GTK_WINDOW (connect_dialog));
+
+      if (window != NULL && !TERMINAL_IS_WINDOW (window))
+        window = NULL;
+    }
+
+  /* Connect */
+  cmd = server_build_command (server);
+
+  if (!cmd)
+    return FALSE;
+
+  if (window != NULL)
+    {
+      GtkWidget *widget;
+
+      screen = terminal_window_get_active (TERMINAL_WINDOW (window));
+
+      if (terminal_connect_screen_is_connected (screen))
+        terminal_connect_screen_disconnect (screen);
+
+      terminal_screen_set_profile (screen,
+                                   terminal_profile_lookup (server->profile));
+      terminal_screen_set_dynamic_title (screen, server->name);
+
+      widget = terminal_screen_get_widget (screen);
+      terminal_widget_reset (widget, TRUE);
+      terminal_widget_set_encoding (widget, server->encoding);
+
+      terminal_screen_set_override_command (screen, cmd);
+      terminal_screen_launch_child (screen);
+    }
+  else
+    {
+      TerminalApp *app = terminal_app_get ();
+      char *display_name;
+      GList *windows;
+
+      display_name =
+        gdk_screen_make_display_name (gtk_widget_get_screen (connect_dialog));
+
+      terminal_app_new_terminal (app,
+                                 terminal_profile_lookup (server->profile),
+                                 NULL, FALSE, FALSE, FALSE,
+                                 cmd, NULL, server->name, NULL,
+                                 NULL, 1.0, NULL, display_name, -1,
+                                 server->encoding);
+      g_free (display_name);
+
+      windows = terminal_app_get_windows (app);
+      window = g_list_first (windows)->data;    /* There can be only one */
+      screen = terminal_window_get_active (TERMINAL_WINDOW (window));
+    }
+
+  g_strfreev (cmd);
+
+  server_add_to_connected (server, screen);
+
+  terminal_window_set_connected (TERMINAL_WINDOW (window), screen, TRUE);
+
+  return TRUE;
+}
+
+/* server can be NULL (means it has been removed while connected) */
+static void
+server_disconnect (Server         *server,
+                   TerminalScreen *screen)
+{
+  TerminalWindow *window;
+
+  server_remove_from_connected (server, screen, FALSE);
+
+  window = terminal_screen_get_window (screen);
+
+  /* If screen isn't attached to a window it's about to be destroyed */
+  if (window != NULL)
+    {
+      GtkWidget *widget;
+
+      terminal_window_set_connected (window, screen, FALSE);
+
+      terminal_screen_set_dynamic_title (screen, NULL);
+
+      widget = terminal_screen_get_widget (screen);
+      terminal_widget_reset (widget, FALSE);
+
+      terminal_screen_set_override_command (screen, NULL);
+      terminal_screen_launch_child (screen);
+    }
+}
+
+static void
+server_dialog_update_entry (Server     *server,
+                            const char *text,
+                            const char *widget)
+{
+  GtkWidget *w;
+
+  if (!server->dialog)
+    return;
+
+  w = get_widget (server->dialog, widget);
+
+  if (strcmp (text, gtk_entry_get_text (GTK_ENTRY (w))) != 0)
+    gtk_entry_set_text (GTK_ENTRY (w), text);
+}
+
+static void
+server_dialog_update_combo_box (Server     *server,
+                                int         index,
+                                const char *widget)
+{
+  GtkWidget *w;
+
+  if (!server->dialog)
+    return;
+
+  w = get_widget (server->dialog, widget);
+  gtk_combo_box_set_active (GTK_COMBO_BOX (w), index);
+}
+
+static void
+server_dialog_update_title (Server *server)
+{
+  char *s;
+
+  if (!server->dialog)
+    return;
+
+  s = g_strdup_printf (_("Editing Server \"%s\""), server->name);
+  gtk_window_set_title (GTK_WINDOW (server->dialog), s);
+  g_free (s);
+}
+
+static void
+server_dialog_update_sensitive (Server *server)
+{
+  GtkWidget *w;
+
+  if (!server->dialog)
+    return;
+
+  w = get_widget (server->dialog, SERVER_NAME_ENTRY);
+  gtk_widget_set_sensitive (w, !server->locked.name);
+
+  w = get_widget (server->dialog, SERVER_SERVER_ENTRY);
+  gtk_widget_set_sensitive (w, !server->locked.server);
+
+  w = get_widget (server->dialog, SERVER_PORT_ENTRY);
+  gtk_widget_set_sensitive (w, !server->locked.port);
+
+  w = get_widget (server->dialog, SERVER_USER_NAME_ENTRY);
+  gtk_widget_set_sensitive (w, !server->locked.user_name);
+
+  w = get_widget (server->dialog, SERVER_TYPE_COMBOBOX);
+  gtk_widget_set_sensitive (w, !server->locked.type);
+
+  w = get_widget (server->dialog, SERVER_ENCODING_COMBOBOX);
+  gtk_widget_set_sensitive (w, !server->locked.encoding);
+
+  w = get_widget (server->dialog, SERVER_PROFILE_COMBOBOX);
+  gtk_widget_set_sensitive (w, !server->locked.profile);
+
+  /* Show warning if any widget is insensitive due to a setting being locked */
+  w = get_widget (server->dialog, SERVER_LOCKED_WARNING);
+
+  if (server_setting_mask_is_empty (&server->locked))
+    {
+      gtk_widget_hide_all (w);
+    }
+  else
+    {
+      GtkWidget *label;
+      char *text, *markup;
+
+      label = get_widget (server->dialog, SERVER_LOCKED_LABEL);
+
+      if (server_is_dns_sd (server))
+        text = _("Only your network administrator can "
+                 "change some of these settings");
+      else
+        text = _("Only your system administrator can "
+                 "change some of these settings");
+
+      markup = g_strdup_printf ("<b>%s</b>", text);
+      gtk_label_set_markup (GTK_LABEL (label), markup);
+      g_free (markup);
+
+      gtk_widget_show_all (w);
+    }
+}
+
+static int
+server_dialog_encoding_index (Server *server)
+{
+  GSList *tmp;
+  int i;
+
+  if (!server->encoding)
+    return 0;
+
+  for (tmp = server->dialog_encodings, i = 0; tmp; tmp = tmp->next, i++)
+    {
+      TerminalEncoding *enc = tmp->data;
+
+      if (strcmp (server->encoding, enc->charset) == 0)
+        return i;
+    }
+
+  return 0;   /* Current locale always placed first (see encoding.c) */
+}
+
+static int
+server_dialog_profile_index (Server *server)
+{
+  GList *tmp;
+  int i;
+  int def = 0;
+
+  for (tmp = server->dialog_profiles, i = 0; tmp; tmp = tmp->next, i++)
+    {
+      TerminalProfile *profile = tmp->data;
+
+      if (server->profile &&
+          strcmp (server->profile, terminal_profile_get_name (profile)) == 0)
+        return i;
+
+      if (terminal_profile_get_is_default (profile))
+        def = i;
+    }
+
+  return def;
+}
+
+static void
+server_dialog_response (GtkWidget *dialog,
+                        int        id,
+                        Server    *server)
+{
+  if (id == GTK_RESPONSE_HELP)
+    terminal_util_show_help ("gnome-terminal-connect", GTK_WINDOW (dialog));
+  else
+    gtk_widget_destroy (dialog);
+}
+
+static void
+server_dialog_name_changed (GtkWidget *entry,
+                            Server    *server)
+{
+  server_set_name (server, gtk_entry_get_text (GTK_ENTRY (entry)));
+}
+
+static void
+server_dialog_server_changed (GtkWidget *entry,
+                              Server    *server)
+{
+  server_set_server (server, gtk_entry_get_text (GTK_ENTRY (entry)));
+}
+
+static void
+server_dialog_port_changed (GtkWidget *entry,
+                            Server    *server)
+{
+  server_set_port (server, gtk_entry_get_text (GTK_ENTRY (entry)));
+}
+
+static void
+server_dialog_port_insert_text (GtkWidget   *entry,
+                                const gchar *new_text,
+                                gint         new_text_length,
+                                gint        *position)
+{
+  if (new_text_length != 1 || !g_ascii_isdigit (new_text[0]))
+    {
+      gdk_display_beep (gtk_widget_get_display (entry));
+      g_signal_stop_emission_by_name (entry, "insert_text");
+    }
+}
+
+static void
+server_dialog_user_name_changed (GtkWidget *entry,
+                                 Server    *server)
+{
+  server_set_user_name (server, gtk_entry_get_text (GTK_ENTRY (entry)));
+}
+
+static void
+server_dialog_type_changed (GtkWidget *combobox,
+                            Server    *server)
+{
+  server_set_type (server,
+                   gtk_combo_box_get_active (GTK_COMBO_BOX (combobox)));
+}
+
+/* data is index of separator row (kind of a hack to get around writing
+ * our own model for just a single lousy separator)
+ */
+static gboolean
+server_dialog_is_separator (GtkTreeModel *model,
+                            GtkTreeIter  *iter,
+                            gpointer      data)
+{
+  GtkTreePath *path = gtk_tree_model_get_path (model, iter);
+  int *indices = gtk_tree_path_get_indices (path);
+  gboolean is_sep = GPOINTER_TO_INT (data) == indices[0];
+  gtk_tree_path_free (path);
+
+  return is_sep;
+}
+
+static void
+server_dialog_encoding_fill (Server *server)
+{
+  GtkWidget *w;
+  GSList *tmp;
+  int i;
+
+  if (!server->dialog)
+    return;
+
+  w = get_widget (server->dialog, SERVER_ENCODING_COMBOBOX);
+
+  /* Remove the old */
+  if (server->dialog_encodings)
+    {
+      for (i = g_slist_length (server->dialog_encodings); i > 0; i--)
+        gtk_combo_box_remove_text (GTK_COMBO_BOX (w), 0);
+
+      g_slist_foreach (server->dialog_encodings,
+                       (GFunc) terminal_encoding_free, NULL);
+      g_slist_free (server->dialog_encodings);
+    }
+
+  for (i = 2; i > 0; i--)
+    gtk_combo_box_remove_text (GTK_COMBO_BOX (w), 0);
+
+  /* Add the new */
+  server->dialog_encodings = terminal_get_active_encodings ();
+
+  for (tmp = server->dialog_encodings, i = 0; tmp; tmp = tmp->next, i++)
+    {
+      TerminalEncoding *enc = tmp->data;
+      char *name;
+
+      name = g_strdup_printf ("%s (%s)", enc->name, enc->charset);
+      gtk_combo_box_append_text (GTK_COMBO_BOX (w), name);
+      g_free (name);
+    }
+
+  /* Don't want to write our own model for just a single lousy separator */
+  gtk_combo_box_append_text (GTK_COMBO_BOX (w), "");
+  gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (w),
+                                        server_dialog_is_separator,
+                                        GINT_TO_POINTER (i),
+                                        NULL);
+
+  gtk_combo_box_append_text (GTK_COMBO_BOX (w), _("Add or Remove..."));
+
+  gtk_combo_box_set_active (GTK_COMBO_BOX (w),
+                            server_dialog_encoding_index (server));
+}
+
+static void
+server_dialog_encoding_changed (GtkWidget *combobox,
+                                Server    *server)
+{
+  int i = gtk_combo_box_get_active (GTK_COMBO_BOX (combobox));
+  TerminalEncoding *enc = g_slist_nth_data (server->dialog_encodings, i);
+
+  if (enc)
+    {
+      server_set_encoding (server, enc->charset);
+    }
+  else
+    {
+       /* "Add or Remove...", reset combo box and edit encodings */
+      gtk_combo_box_set_active (GTK_COMBO_BOX (combobox),
+                                server_dialog_encoding_index (server));
+
+      terminal_app_edit_encodings (terminal_app_get (),
+                                   GTK_WINDOW (server->dialog));
+    }
+}
+
+static void
+server_dialog_profile_fill (Server *server)
+{
+  GtkWidget *w;
+  GList *tmp;
+  int i;
+
+  if (!server->dialog)
+    return;
+
+  w = get_widget (server->dialog, SERVER_PROFILE_COMBOBOX);
+
+  /* Remove the old */
+  if (server->dialog_profiles)
+    {
+      for (i = g_list_length (server->dialog_profiles); i > 0; i--)
+        gtk_combo_box_remove_text (GTK_COMBO_BOX (w), 0);
+
+      g_list_foreach (server->dialog_profiles, (GFunc) g_object_unref, NULL);
+      g_list_free (server->dialog_profiles);
+    }
+
+  for (i = 2; i > 0; i--)
+    gtk_combo_box_remove_text (GTK_COMBO_BOX (w), 0);
+
+  /* Add the new */
+  server->dialog_profiles = terminal_profile_get_list ();
+  g_list_foreach (server->dialog_profiles, (GFunc) g_object_ref, NULL);
+
+  for (tmp = server->dialog_profiles, i = 0; tmp; tmp = tmp->next, i++)
+    {
+      TerminalProfile *profile = tmp->data;
+
+      gtk_combo_box_append_text (GTK_COMBO_BOX (w),
+                                 terminal_profile_get_visible_name (profile));
+    }
+
+  /* Don't want to write our own model for just a single lousy separator */
+  gtk_combo_box_append_text (GTK_COMBO_BOX (w), "");
+  gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (w),
+                                        server_dialog_is_separator,
+                                        GINT_TO_POINTER (i),
+                                        NULL);
+
+  gtk_combo_box_append_text (GTK_COMBO_BOX (w), _("Edit Profiles..."));
+
+  gtk_combo_box_set_active (GTK_COMBO_BOX (w),
+                            server_dialog_profile_index (server));
+}
+
+static void
+server_dialog_profile_changed (GtkWidget *combobox,
+                               Server    *server)
+{
+  int i = gtk_combo_box_get_active (GTK_COMBO_BOX (combobox));
+  TerminalProfile *profile = g_list_nth_data (server->dialog_profiles, i);
+
+  if (profile)
+    {
+      server_set_profile (server, terminal_profile_get_name (profile));
+    }
+  else
+    {
+       /* "Edit Profiles...", reset combo box and edit profiles */
+      gtk_combo_box_set_active (GTK_COMBO_BOX (combobox),
+                                server_dialog_profile_index (server));
+
+      terminal_app_manage_profiles (terminal_app_get (),
+                                    GTK_WINDOW (server->dialog));
+    }
+}
+
+static void
+server_dialog_expander_toggled (GtkExpander *expander,
+                                GParamSpec  *pspec,
+                                gpointer     user_data)
+{
+  gconf_client_set_bool (global_conf, CONF_SERVER_EXPANDED,
+                         gtk_expander_get_expanded (expander), NULL);
+}
+
+static void
+server_edit (Server    *server,
+             GtkWindow *transient_parent)
+{
+  if (!server->dialog)
+    {
+      GladeXML *xml;
+      GtkWidget *w;
+      gboolean expanded = FALSE;
+
+      xml = terminal_util_load_glade_file (TERM_GLADE_FILE,
+                                           SERVER_EDITOR_DIALOG,
+                                           transient_parent);
+      if (!xml)
+        return;
+
+      server->dialog = glade_xml_get_widget (xml, SERVER_EDITOR_DIALOG);
+      g_object_add_weak_pointer (G_OBJECT (server->dialog),
+                                 (void **) &server->dialog);
+
+      g_object_set_data_full (G_OBJECT (server->dialog),
+                              DIALOG_GLADE_XML_KEY,
+                              xml,
+                              (GDestroyNotify) g_object_unref);
+
+      gtk_window_set_transient_for (GTK_WINDOW (server->dialog),
+                                    transient_parent);
+
+      gtk_dialog_set_default_response (GTK_DIALOG (server->dialog),
+                                       GTK_RESPONSE_CLOSE);
+
+      terminal_util_set_unique_role (GTK_WINDOW (server->dialog),
+                                     "gnome-terminal-server-editor");
+
+      server_dialog_update_title (server);
+      server_dialog_update_sensitive (server);
+
+      /* Autoconnect isn't too scary for me (glade_xml_signal_autoconnect_full
+       * can be used to pass user_data) but I guess I'll just follow suit.
+       */
+      g_signal_connect (G_OBJECT (server->dialog), "response",
+                        G_CALLBACK (server_dialog_response),
+                        server);
+
+      w = glade_xml_get_widget (xml, SERVER_NAME_ENTRY);
+      gtk_entry_set_text (GTK_ENTRY (w), server->name);
+      g_signal_connect (G_OBJECT (w), "changed",
+                        G_CALLBACK (server_dialog_name_changed),
+                        server);
+
+      w = glade_xml_get_widget (xml, SERVER_SERVER_ENTRY);
+      gtk_entry_set_text (GTK_ENTRY (w), server->server);
+      g_signal_connect (G_OBJECT (w), "changed",
+                        G_CALLBACK (server_dialog_server_changed),
+                        server);
+
+      w = glade_xml_get_widget (xml, SERVER_PORT_ENTRY);
+      gtk_entry_set_text (GTK_ENTRY (w), server->port);
+      g_signal_connect (G_OBJECT (w), "changed",
+                        G_CALLBACK (server_dialog_port_changed),
+                        server);
+      g_signal_connect (G_OBJECT (w), "insert_text",
+                        G_CALLBACK (server_dialog_port_insert_text),
+                        NULL);
+
+      w = glade_xml_get_widget (xml, SERVER_USER_NAME_ENTRY);
+      gtk_entry_set_text (GTK_ENTRY (w), server->user_name);
+      g_signal_connect (G_OBJECT (w), "changed",
+                        G_CALLBACK (server_dialog_user_name_changed),
+                        server);
+
+      w = glade_xml_get_widget (xml, SERVER_TYPE_COMBOBOX);
+      gtk_combo_box_set_active (GTK_COMBO_BOX (w), server->type);
+      g_signal_connect (G_OBJECT (w), "changed",
+                        G_CALLBACK (server_dialog_type_changed),
+                        server);
+
+      w = glade_xml_get_widget (xml, SERVER_ENCODING_COMBOBOX);
+      g_signal_connect (G_OBJECT (w), "changed",
+                        G_CALLBACK (server_dialog_encoding_changed),
+                        server);
+      server_dialog_encoding_fill (server);
+
+      w = glade_xml_get_widget (xml, SERVER_PROFILE_COMBOBOX);
+      g_signal_connect (G_OBJECT (w), "changed",
+                        G_CALLBACK (server_dialog_profile_changed),
+                        server);
+      server_dialog_profile_fill (server);
+
+      /* Get expander state and save it whenever it changes */
+      w = glade_xml_get_widget (xml, SERVER_OPTIONAL_EXPANDER);
+
+      expanded = gconf_client_get_bool (global_conf,
+                                        CONF_SERVER_EXPANDED, NULL);
+      gtk_expander_set_expanded (GTK_EXPANDER (w), expanded);
+
+      g_signal_connect (G_OBJECT (w), "notify::expanded",
+                        G_CALLBACK (server_dialog_expander_toggled), NULL);
+    }
+
+  gtk_window_present (GTK_WINDOW (server->dialog));
+}
+
+static void
+connect_dialog_set_rowrefs (GtkWidget *dialog)
+{
+  GHashTable *rowrefs;
+
+  rowrefs = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                   NULL,
+                                   (GDestroyNotify)gtk_tree_row_reference_free);
+
+  g_object_set_data_full (G_OBJECT (dialog),
+                          DIALOG_ROW_REFS_KEY,
+                          rowrefs,
+                          (GDestroyNotify) g_hash_table_destroy);
+}
+
+static GHashTable*
+connect_dialog_get_rowrefs (GtkWidget *dialog)
+{
+  return g_object_get_data (G_OBJECT (dialog), DIALOG_ROW_REFS_KEY);
+}
+
+static GtkListStore*
+connect_dialog_get_list_store (GtkWidget *dialog)
+{
+  GtkWidget *w = get_widget (dialog, CONNECT_SERVERS_TREEVIEW);
+
+  return GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (w)));
+}
+
+static void
+connect_dialog_list_store_append (GtkWidget *dialog,
+                                  Server    *server)
+{
+  GtkListStore *model;
+  GtkTreeIter iter;
+  GtkTreePath *path;
+  GtkTreeRowReference *rowref;
+
+  model = connect_dialog_get_list_store (dialog);
+
+  gtk_list_store_append (model, &iter);
+  gtk_list_store_set (model, &iter,
+                      COLUMN_SERVER, server,
+                      COLUMN_ICON, server_get_icon_stock_id (server),
+                      COLUMN_NAME, server->name,
+                      -1);
+
+  path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
+  rowref = gtk_tree_row_reference_new (GTK_TREE_MODEL (model), path);
+  gtk_tree_path_free (path);
+
+  g_hash_table_insert (connect_dialog_get_rowrefs (dialog),
+                       server->id, rowref);
+}
+
+static gboolean
+connect_dialog_list_store_find_server (GtkWidget    *dialog,
+                                       GtkListStore **model,
+                                       GtkTreeIter  *iter,
+                                       Server       *server)
+{
+  GtkTreeRowReference *rowref;
+  GtkTreePath *path;
+  gboolean iter_set = FALSE;
+
+  *model = connect_dialog_get_list_store (dialog);
+  rowref = g_hash_table_lookup (connect_dialog_get_rowrefs (dialog),
+                                server->id);
+  path = gtk_tree_row_reference_get_path (rowref);
+
+  if (path)
+    {
+      iter_set = gtk_tree_model_get_iter (GTK_TREE_MODEL (*model), iter, path);
+      gtk_tree_path_free (path);
+    }
+
+  return iter_set;
+}
+
+static void
+connect_dialog_list_store_remove (GtkWidget *dialog,
+                                  Server    *server)
+{
+  GtkListStore *model;
+  GtkTreeIter iter;
+
+  if (connect_dialog_list_store_find_server (dialog, &model, &iter, server))
+    gtk_list_store_remove (model, &iter);
+
+  g_hash_table_remove (connect_dialog_get_rowrefs (dialog),
+                       server->id);
+}
+
+static void
+connect_dialog_list_store_update (GtkWidget *dialog,
+                                  Server    *server)
+{
+  GtkListStore *model;
+  GtkTreeIter iter;
+
+  if (connect_dialog_list_store_find_server (dialog, &model, &iter, server))
+    gtk_list_store_set (model, &iter,
+                        COLUMN_ICON, server_get_icon_stock_id (server),
+                        COLUMN_NAME, server->name,
+                        -1);
+}
+
+static Server*
+connect_dialog_selection_get_server (GtkTreeSelection *selection)
+{
+  GtkTreeModel *model;
+  GtkTreeIter iter;
+  Server *server;
+
+  if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+    return NULL;
+
+  gtk_tree_model_get (model, &iter, COLUMN_SERVER, &server, -1);
+
+  return server;
+}
+
+static Server*
+connect_dialog_get_selected_server (GtkWidget *dialog)
+{
+  GtkWidget *w;
+  GtkTreeSelection *selection;
+
+  w = get_widget (dialog, CONNECT_SERVERS_TREEVIEW);
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (w));
+
+  return connect_dialog_selection_get_server (selection);
+}
+
+static void
+connect_dialog_update_sensitive (GtkWidget *dialog,
+                                 Server    *server)
+{
+  gboolean edit, connect, delete;
+  GtkWidget *w;
+
+  if (server != NULL)
+    {
+      edit = TRUE;
+
+      if (server->server != NULL)
+        connect = strcmp (server->server, "") != 0;
+      else
+        connect = FALSE;
+
+      delete = server_setting_mask_is_empty (&server->locked);
+    }
+  else
+    {
+      edit = FALSE;
+      connect = FALSE;
+      delete = FALSE;
+    }
+
+  w = get_widget (dialog, CONNECT_EDIT_BUTTON);
+  gtk_widget_set_sensitive (w, edit);
+
+  w = get_widget (dialog, CONNECT_CONNECT_BUTTON);
+  gtk_widget_set_sensitive (w, connect);
+
+  w = get_widget (dialog, CONNECT_DELETE_BUTTON);
+  gtk_widget_set_sensitive (w, delete);
+}
+
+static void
+connect_dialog_selection_changed (GtkTreeSelection *selection,
+                                  GtkWidget        *dialog)
+{
+  Server *server = connect_dialog_selection_get_server (selection);
+
+  connect_dialog_update_sensitive (dialog, server);
+}
+
+static void
+connect_dialog_treeview_select_and_scroll_to (GtkWidget *dialog,
+                                              Server    *server)
+{
+  GtkWidget *w;
+  GtkTreeSelection *selection;
+  GtkTreeRowReference *rowref;
+  GtkTreePath *path;
+
+  w = get_widget (dialog, CONNECT_SERVERS_TREEVIEW);
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (w));
+
+  rowref = g_hash_table_lookup (connect_dialog_get_rowrefs (dialog),
+                                server->id);
+  path = gtk_tree_row_reference_get_path (rowref);
+  if (!path)
+    return;
+
+  gtk_tree_selection_select_path (selection, path);
+  gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (w), path, NULL, FALSE, 0, 0);
+  gtk_tree_path_free (path);
+}
+
+static void
+connect_dialog_list_store_append_foreach (char      *id,
+                                          Server    *server,
+                                          GtkWidget *dialog)
+{
+  connect_dialog_list_store_append (dialog, server);
+}
+
+static void
+connect_dialog_treeview_init (GtkWidget *dialog)
+{
+  GtkWidget *w;
+  GtkListStore *model;
+  GtkCellRenderer *renderer;
+  GtkTreeViewColumn *column;
+  GtkTreeSelection *selection;
+
+  w = get_widget (dialog, CONNECT_SERVERS_TREEVIEW);
+
+  model = gtk_list_store_new (COLUMN_LAST,
+                              G_TYPE_POINTER,
+                              G_TYPE_STRING,
+                              G_TYPE_STRING);
+  gtk_tree_view_set_model (GTK_TREE_VIEW (w),
+                           GTK_TREE_MODEL (model));
+
+  connect_dialog_set_rowrefs (dialog);
+  g_hash_table_foreach (servers,
+                        (GHFunc) connect_dialog_list_store_append_foreach,
+                        dialog);
+
+  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
+                                        COLUMN_NAME,
+                                        GTK_SORT_ASCENDING);
+  g_object_unref (model);
+
+  column = gtk_tree_view_column_new();
+  gtk_tree_view_column_set_title(column, _("Name"));
+
+  renderer = gtk_cell_renderer_pixbuf_new();
+  gtk_tree_view_column_pack_start(column, renderer, FALSE);
+  gtk_tree_view_column_set_attributes(column, renderer,
+                                      "stock-id", COLUMN_ICON, NULL);
+
+  renderer = gtk_cell_renderer_text_new();
+  gtk_tree_view_column_pack_start(column, renderer, TRUE);
+  gtk_tree_view_column_set_attributes(column, renderer,
+                                      "text", COLUMN_NAME, NULL);
+
+  gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (w), column);
+
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (w));
+  g_signal_connect (selection, "changed",
+                    G_CALLBACK (connect_dialog_selection_changed), dialog);
+}
+
+static void
+connect_dialog_response (GtkWidget *dialog,
+                         int        id,
+                         gpointer   data)
+{
+  switch (id)
+    {
+    case GTK_RESPONSE_ACCEPT:
+      {
+        Server *server = connect_dialog_get_selected_server (dialog);
+
+        if (server)
+          if (server_connect (server))
+            gtk_widget_destroy (dialog);
+      }
+      break;
+    case GTK_RESPONSE_HELP:
+      terminal_util_show_help ("gnome-terminal-connect", GTK_WINDOW (dialog));
+      break;
+    default:
+      gtk_widget_destroy (dialog);
+
+      if (terminal_app_get_windows (terminal_app_get ()) == NULL)
+        /* Was probably started with --connect-to-server and no windows open */
+        gtk_main_quit ();
+      break;
+    }
+}
+
+static void
+connect_dialog_new_clicked (GtkWidget *button,
+                            GtkWidget *dialog)
+{
+  Server *server;
+
+  server = server_create ();
+
+  connect_dialog_treeview_select_and_scroll_to (dialog, server);
+  server_edit (server, GTK_WINDOW (dialog));
+}
+
+static void
+connect_dialog_edit_clicked (GtkWidget *button,
+                             GtkWidget *dialog)
+{
+  Server *server;
+
+  server = connect_dialog_get_selected_server (dialog);
+
+  if (server)
+    server_edit (server, GTK_WINDOW (dialog));
+}
+
+static void
+connect_dialog_delete_clicked (GtkWidget *button,
+                               GtkWidget *dialog)
+{
+  Server *server;
+
+  server = connect_dialog_get_selected_server (dialog);
+
+  if (server)
+    server_remove (server);
+}
+
+static GtkWidget*
+connect_dialog_new (GtkWindow *transient_parent)
+{
+  GladeXML *xml;
+  GtkWidget *dialog, *w;
+
+  xml = terminal_util_load_glade_file (TERM_GLADE_FILE,
+                                       CONNECT_TO_SERVER_DIALOG,
+                                       transient_parent);
+  if (!xml)
+    return NULL;
+
+  dialog = glade_xml_get_widget (xml, CONNECT_TO_SERVER_DIALOG);
+
+  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
+
+  g_object_set_data_full (G_OBJECT (dialog),
+                          DIALOG_GLADE_XML_KEY,
+                          xml,
+                          (GDestroyNotify) g_object_unref);
+
+  terminal_util_set_unique_role (GTK_WINDOW (dialog),
+                                 "gnome-terminal-connect-to-server");
+
+  connect_dialog_update_sensitive (dialog, NULL);
+  connect_dialog_treeview_init (dialog);
+
+  /* Autoconnect isn't too scary for me (glade_xml_signal_autoconnect_full ()
+   * can be used to pass user_data) but I guess I'll just follow suit.
+   */
+  g_signal_connect (G_OBJECT (dialog), "response",
+                    G_CALLBACK (connect_dialog_response),
+                    NULL);
+
+  w = glade_xml_get_widget (xml, CONNECT_NEW_BUTTON);
+  g_signal_connect (G_OBJECT (w), "clicked",
+                    G_CALLBACK (connect_dialog_new_clicked),
+                    dialog);
+
+  w = glade_xml_get_widget (xml, CONNECT_EDIT_BUTTON);
+  g_signal_connect (G_OBJECT (w), "clicked",
+                    G_CALLBACK (connect_dialog_edit_clicked),
+                    dialog);
+
+  w = glade_xml_get_widget (xml, CONNECT_DELETE_BUTTON);
+  g_signal_connect (G_OBJECT (w), "clicked",
+                    G_CALLBACK (connect_dialog_delete_clicked),
+                    dialog);
+
+  return dialog;
+}
+
+/* RemoveInfo is Needed since GHFunc only takes one user_data argument and we
+ * aren't allowed to call server_free () in server_list_removed_foreach () since
+ * that would modify the server hash table (see g_hash_table_foreach ()). Hence,
+ * we must pass the ids and a list where we store the servers to be freed.
+ * ids_hash is created from the ids list for faster lookup.
+ */
+typedef struct
+{
+  GSList *servers;
+  GHashTable *ids_hash;
+} RemoveInfo;
+
+static void
+server_list_removed_foreach (gpointer   key,
+                             Server     *server,
+                             RemoveInfo *info)
+
+{
+  /* Server should be removed if it isn't in list and isn't from Zeroconf */
+  if (!g_hash_table_lookup (info->ids_hash, server->id) &&
+      !server_is_dns_sd (server))
+    info->servers = g_slist_prepend (info->servers, server);
+}
+
+static void
+server_list_update (GSList *ids)
+{
+  GSList *tmp;
+  RemoveInfo info;
+
+  info.servers = NULL;
+  info.ids_hash = g_hash_table_new (g_str_hash, g_str_equal);
+
+  for (tmp = ids; tmp; tmp = tmp->next)
+    {
+      char *id = tmp->data;
+
+      if (!g_hash_table_lookup (servers, id))
+        server_from_conf (id);
+
+      g_hash_table_insert (info.ids_hash, id, id);
+    }
+
+  g_hash_table_foreach (servers, (GHFunc) server_list_removed_foreach, &info);
+  g_slist_foreach (info.servers, (GFunc) server_free, NULL);
+
+  g_slist_free (info.servers);
+  g_hash_table_destroy (info.ids_hash);
+}
+
+static void
+server_list_notify (GConfClient *client,
+                    guint        cnxn_id,
+                    GConfEntry  *entry,
+                    gpointer     user_data)
+{
+  GConfValue *val;
+  GSList *ids = NULL;
+
+  val = gconf_entry_get_value (entry);
+
+  if (val &&
+      val->type == GCONF_VALUE_LIST &&
+      gconf_value_get_list_type (val) == GCONF_VALUE_STRING)
+    {
+      GSList *tmp;
+
+      for (tmp = gconf_value_get_list (val); tmp; tmp = tmp->next)
+        {
+          GConfValue *v = tmp->data;
+
+          ids = g_slist_prepend (ids, (char *) gconf_value_get_string (v));
+        }
+    }
+
+  server_list_update (ids);
+
+  g_slist_free (ids);
+}
+
+static void
+dns_sd_resolve_callback (GnomeVFSDNSSDResolveHandle *handle,
+                         GnomeVFSResult              result,
+                         const GnomeVFSDNSSDService *service,
+                         const char                 *host,
+                         int                         port,
+                         const GHashTable           *text,
+                         int                         text_raw_len,
+                         const char                 *text_raw,
+                         gpointer                    callback_data)
+{
+  ServerType type;
+  char *user_name = NULL, *port_str;
+
+  dns_sd_resolve_handles = g_slist_remove (dns_sd_resolve_handles, handle);
+
+  if (result != GNOME_VFS_OK)
+    return;
+
+  if (g_str_has_prefix (service->type, "_ssh"))
+    type = SERVER_TYPE_SSH;
+  else if (g_str_has_prefix (service->type, "_telnet"))
+    type = SERVER_TYPE_TELNET;
+  else
+    g_return_if_reached ();
+
+  if (text)
+    user_name = g_hash_table_lookup ((GHashTable *) text, "u");
+
+  port_str = g_strdup_printf ("%d", port);
+  server_from_dns_sd (service->name, type, host, port_str, user_name);
+  g_free (port_str);
+}
+
+static void
+dns_sd_browse_callback (GnomeVFSDNSSDBrowseHandle  *handle,
+                        GnomeVFSDNSSDServiceStatus  status,
+                        const GnomeVFSDNSSDService *service,
+                        gpointer                    callback_data)
+{
+  switch (status)
+    {
+    case GNOME_VFS_DNS_SD_SERVICE_REMOVED:
+      server_remove_dns_sd (service->name);
+      break;
+    case GNOME_VFS_DNS_SD_SERVICE_ADDED:
+      {
+        GnomeVFSDNSSDResolveHandle *resolve_handle;
+
+	if (gnome_vfs_dns_sd_resolve (&resolve_handle,
+				      service->name, service->type,
+                                      service->domain, 10 * 1000,
+				      dns_sd_resolve_callback,
+				      NULL, NULL) == GNOME_VFS_OK)
+          {
+            dns_sd_resolve_handles = g_slist_prepend (dns_sd_resolve_handles,
+                                                      resolve_handle);
+          }
+      }
+      break;
+    default:
+      g_return_if_reached ();
+      break;
+    }
+}
+
+static void
+dns_sd_deinit (void)
+{
+  int i;
+
+  for (i = 0; i < G_N_ELEMENTS (dns_sd_browse_handles); i++)
+    {
+      if (dns_sd_browse_handles[i] != NULL)
+        {
+          gnome_vfs_dns_sd_stop_browse (dns_sd_browse_handles[i]);
+          dns_sd_browse_handles[i] = NULL;
+        }
+    }
+
+  g_slist_foreach (dns_sd_resolve_handles,
+                  (GFunc) gnome_vfs_dns_sd_cancel_resolve, NULL);
+  g_slist_free (dns_sd_resolve_handles);
+  dns_sd_resolve_handles = NULL;
+}
+
+static void
+dns_sd_init (void)
+{
+  int i;
+  char *types[2] = { "_ssh._tcp", "_telnet._tcp" };
+
+  for (i = 0; i < MIN (G_N_ELEMENTS (dns_sd_browse_handles), G_N_ELEMENTS(types)); i++)
+    gnome_vfs_dns_sd_browse (&dns_sd_browse_handles[i],
+                             "local", types[i],
+                             dns_sd_browse_callback,
+                             NULL, NULL);
+
+  g_atexit (dns_sd_deinit);
+}
+
+void
+terminal_connect_to_server_init (GConfClient *conf)
+{
+  GError *err;
+  GSList *ids;
+
+  g_return_if_fail (conf != NULL);
+  g_return_if_fail (global_conf == NULL);
+
+  global_conf = conf;
+  g_object_ref (G_OBJECT (global_conf));
+
+  servers = g_hash_table_new (g_str_hash, g_str_equal);
+
+  connected_servers = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+  /* Get all known servers and listen for changes */
+  ids = gconf_client_get_list (global_conf,
+                               CONF_SERVER_ID_LIST,
+                               GCONF_VALUE_STRING,
+                               NULL);
+
+  server_list_update (ids);
+
+  g_slist_foreach (ids, (GFunc) g_free, NULL);
+  g_slist_free (ids);
+
+  err = NULL;
+  gconf_client_notify_add (global_conf,
+                           CONF_SERVER_ID_LIST,
+                           server_list_notify,
+                           NULL, NULL, &err);
+  if (err)
+    {
+      g_printerr (_("There was an error subscribing to notification of "
+                    "terminal server list changes. (%s)\n"), err->message);
+      g_error_free (err);
+    }
+
+  dns_sd_init ();
+}
+
+void
+terminal_connect_to_server (GtkWindow *transient_parent)
+{
+  GtkWindow *old_transient_parent;
+
+  if (!connect_dialog)
+    {
+      connect_dialog = connect_dialog_new (transient_parent);
+
+      if (!connect_dialog)
+        return;
+
+      g_object_add_weak_pointer (G_OBJECT (connect_dialog),
+                                 (void **) &connect_dialog);
+      old_transient_parent = NULL;
+    }
+  else
+    {
+      old_transient_parent =
+        gtk_window_get_transient_for (GTK_WINDOW (connect_dialog));
+    }
+
+  if (old_transient_parent != transient_parent)
+    {
+      gtk_window_set_transient_for (GTK_WINDOW (connect_dialog),
+                                    transient_parent);
+      gtk_widget_hide (connect_dialog); /* re-show the window on new parent */
+    }
+
+  gtk_window_present (GTK_WINDOW (connect_dialog));
+}
+
+static void
+reread_profiles_foreach (char    *id,
+                         Server  *server,
+                         gpointer data)
+
+{
+  server_dialog_profile_fill (server);
+}
+
+void
+terminal_connect_to_server_reread_profiles (void)
+{
+  if (!servers)
+    return;
+
+  g_hash_table_foreach (servers, (GHFunc) reread_profiles_foreach, NULL);
+}
+
+static void
+reread_encodings_foreach (char    *id,
+                          Server  *server,
+                          gpointer data)
+
+{
+  server_dialog_encoding_fill (server);
+}
+
+void
+terminal_connect_to_server_reread_encodings (void)
+{
+  if (!servers)
+    return;
+
+  g_hash_table_foreach (servers, (GHFunc) reread_encodings_foreach, NULL);
+}
+
+void
+terminal_connect_screen_disconnect (TerminalScreen *screen)
+{
+  Server *server;
+
+  if (g_hash_table_lookup_extended (connected_servers, screen, NULL,
+                                    (gpointer) &server))
+    /* server can be NULL (means it has been removed while connected) */
+    server_disconnect (server, screen);
+}
+
+gboolean
+terminal_connect_screen_is_connected (TerminalScreen *screen)
+{
+  return g_hash_table_lookup_extended (connected_servers, screen, NULL, NULL);
+}
diff -pruN gnome-terminal/src/connect-to-server.h gnome-terminal-connect/src/connect-to-server.h
--- gnome-terminal/src/connect-to-server.h	1970-01-01 01:00:00.000000000 +0100
+++ gnome-terminal-connect/src/connect-to-server.h	2005-08-14 19:58:55.394241880 +0200
@@ -0,0 +1,43 @@
+/* dialog for connecting to ssh and telnet servers */
+
+/*
+ * Copyright (C) 2005 Martin Ejdestig <mejde@dtek.chalmers.se>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef TERMINAL_CONNECT_TO_SERVER_H
+#define TERMINAL_CONNECT_TO_SERVER_H
+
+#include "terminal-screen.h"
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <gconf/gconf-client.h>
+
+G_BEGIN_DECLS
+
+void terminal_connect_to_server_init (GConfClient *conf);
+void terminal_connect_to_server      (GtkWindow *transient_parent);
+
+void terminal_connect_to_server_reread_profiles (void);
+void terminal_connect_to_server_reread_encodings (void);
+
+void     terminal_connect_screen_disconnect   (TerminalScreen *screen);
+gboolean terminal_connect_screen_is_connected (TerminalScreen *screen);
+
+G_END_DECLS
+
+#endif /* TERMINAL_CONNECT_TO_SERVER_H */
diff -pruN gnome-terminal/src/encoding.c gnome-terminal-connect/src/encoding.c
--- gnome-terminal/src/encoding.c	2005-07-02 01:52:47.000000000 +0200
+++ gnome-terminal-connect/src/encoding.c	2005-08-14 19:58:55.097287024 +0200
@@ -22,8 +22,8 @@
 #include "terminal-intl.h"
 #include "terminal.h"
 
+#include "connect-to-server.h"
 #include "encoding.h"
-
 #include "terminal-profile.h"
 
 #include <glade/glade.h>
@@ -393,6 +393,7 @@ update_active_encodings_from_string_list
   g_hash_table_destroy (table);
   
   update_active_encoding_tree_models ();
+  terminal_connect_to_server_reread_encodings ();
 }
 
 GSList*
diff -pruN gnome-terminal/src/gnome-terminal.glade2 gnome-terminal-connect/src/gnome-terminal.glade2
--- gnome-terminal/src/gnome-terminal.glade2	2004-10-31 23:03:53.000000000 +0100
+++ gnome-terminal-connect/src/gnome-terminal.glade2	2005-08-14 19:58:55.113284592 +0200
@@ -3772,4 +3772,779 @@ and operating systems that expect differ
   </child>
 </widget>
 
+<widget class="GtkDialog" id="connect-to-server-dialog">
+  <property name="border_width">5</property>
+  <property name="title" translatable="yes">Connect to Server</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="default_height">300</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">True</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="has_separator">False</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox6">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">6</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog-action_area6">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="connect-help-button">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-help</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-11</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="connect-cancel-button">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-cancel</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-6</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="connect-connect-button">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="has_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-3</property>
+
+	      <child>
+		<widget class="GtkAlignment" id="alignment10103">
+		  <property name="visible">True</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xscale">0</property>
+		  <property name="yscale">0</property>
+		  <property name="top_padding">0</property>
+		  <property name="bottom_padding">0</property>
+		  <property name="left_padding">0</property>
+		  <property name="right_padding">0</property>
+
+		  <child>
+		    <widget class="GtkHBox" id="hbox13">
+		      <property name="visible">True</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">2</property>
+
+		      <child>
+			<widget class="GtkImage" id="image2">
+			  <property name="visible">True</property>
+			  <property name="stock">gtk-connect</property>
+			  <property name="icon_size">4</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label475">
+			  <property name="visible">True</property>
+			  <property name="label">C_onnect</property>
+			  <property name="use_underline">True</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+		    </widget>
+		  </child>
+		</widget>
+	      </child>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="vbox79">
+	  <property name="border_width">5</property>
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">6</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="label467">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">_Servers:</property>
+	      <property name="use_underline">True</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="mnemonic_widget">connect-servers-treeview</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkHBox" id="hbox11">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkScrolledWindow" id="scrolledwindow4">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		  <property name="shadow_type">GTK_SHADOW_IN</property>
+		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+		  <child>
+		    <widget class="GtkTreeView" id="connect-servers-treeview">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="headers_visible">False</property>
+		      <property name="rules_hint">False</property>
+		      <property name="reorderable">False</property>
+		      <property name="enable_search">True</property>
+		    </widget>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkVBox" id="vbox80">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">6</property>
+
+		  <child>
+		    <widget class="GtkButton" id="connect-new-button">
+		      <property name="visible">True</property>
+		      <property name="can_default">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="label">gtk-new</property>
+		      <property name="use_stock">True</property>
+		      <property name="relief">GTK_RELIEF_NORMAL</property>
+		      <property name="focus_on_click">True</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkButton" id="connect-edit-button">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="label">gtk-edit</property>
+		      <property name="use_stock">True</property>
+		      <property name="relief">GTK_RELIEF_NORMAL</property>
+		      <property name="focus_on_click">True</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkButton" id="connect-delete-button">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="label">gtk-delete</property>
+		      <property name="use_stock">True</property>
+		      <property name="relief">GTK_RELIEF_NORMAL</property>
+		      <property name="focus_on_click">True</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+<widget class="GtkDialog" id="server-editor-dialog">
+  <property name="border_width">5</property>
+  <property name="title" translatable="yes"></property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">False</property>
+  <property name="destroy_with_parent">True</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="has_separator">False</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox7">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">6</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog-action_area7">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="server-helpbutton">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-help</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-11</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="server-close-button">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-close</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-7</property>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="vbox81">
+	  <property name="border_width">5</property>
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">12</property>
+
+	  <child>
+	    <widget class="GtkHBox" id="server-locked-warning">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkImage" id="image3">
+		  <property name="visible">True</property>
+		  <property name="stock">gtk-dialog-warning</property>
+		  <property name="icon_size">4</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="server-locked-label">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes"></property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">True</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkTable" id="server-main-table">
+	      <property name="visible">True</property>
+	      <property name="n_rows">4</property>
+	      <property name="n_columns">2</property>
+	      <property name="homogeneous">False</property>
+	      <property name="row_spacing">6</property>
+	      <property name="column_spacing">12</property>
+
+	      <child>
+		<widget class="GtkLabel" id="server-type-label">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">_Type:</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="mnemonic_widget">server-type-combobox</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">1</property>
+		  <property name="bottom_attach">2</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="server-server-label">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">_Server:</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="mnemonic_widget">server-server-entry</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">2</property>
+		  <property name="bottom_attach">3</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="server-name-entry">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">True</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes">New Server</property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">*</property>
+		  <property name="activates_default">False</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">0</property>
+		  <property name="bottom_attach">1</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkComboBox" id="server-type-combobox">
+		  <property name="visible">True</property>
+		  <property name="items" translatable="yes">SSH
+Telnet</property>
+		  <property name="add_tearoffs">False</property>
+		  <property name="focus_on_click">True</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">1</property>
+		  <property name="bottom_attach">2</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options">fill</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="server-server-entry">
+		  <property name="visible">True</property>
+		  <property name="tooltip" translatable="yes">Host or Host:Port</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">True</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes">localhost</property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">*</property>
+		  <property name="activates_default">False</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">2</property>
+		  <property name="bottom_attach">3</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="server-name-label">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">_Name:</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="mnemonic_widget">server-name-entry</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">0</property>
+		  <property name="bottom_attach">1</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="server-user-name-label">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">_User Name:</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="mnemonic_widget">server-user-name-entry</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">3</property>
+		  <property name="bottom_attach">4</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="server-user-name-entry">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">True</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">*</property>
+		  <property name="activates_default">False</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">3</property>
+		  <property name="bottom_attach">4</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkExpander" id="server-optional-expander">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="expanded">True</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkTable" id="table35">
+		  <property name="visible">True</property>
+		  <property name="n_rows">3</property>
+		  <property name="n_columns">2</property>
+		  <property name="homogeneous">False</property>
+		  <property name="row_spacing">6</property>
+		  <property name="column_spacing">12</property>
+
+		  <child>
+		    <widget class="GtkLabel" id="server-port-label">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">_Port:</property>
+		      <property name="use_underline">True</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="mnemonic_widget">server-port-entry</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">0</property>
+		      <property name="right_attach">1</property>
+		      <property name="top_attach">0</property>
+		      <property name="bottom_attach">1</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkEntry" id="server-port-entry">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="editable">True</property>
+		      <property name="visibility">True</property>
+		      <property name="max_length">0</property>
+		      <property name="text" translatable="yes"></property>
+		      <property name="has_frame">True</property>
+		      <property name="invisible_char">*</property>
+		      <property name="activates_default">False</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">1</property>
+		      <property name="right_attach">2</property>
+		      <property name="top_attach">0</property>
+		      <property name="bottom_attach">1</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkLabel" id="server-encoding-label">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">_Encoding:</property>
+		      <property name="use_underline">True</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="mnemonic_widget">server-encoding-combobox</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">0</property>
+		      <property name="right_attach">1</property>
+		      <property name="top_attach">1</property>
+		      <property name="bottom_attach">2</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkComboBox" id="server-encoding-combobox">
+		      <property name="visible">True</property>
+		      <property name="items">Dummy1
+Dummy2</property>
+		      <property name="add_tearoffs">False</property>
+		      <property name="focus_on_click">True</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">1</property>
+		      <property name="right_attach">2</property>
+		      <property name="top_attach">1</property>
+		      <property name="bottom_attach">2</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options">fill</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkLabel" id="server-profile-label">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">P_rofile:</property>
+		      <property name="use_underline">True</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="mnemonic_widget">server-profile-combobox</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">0</property>
+		      <property name="right_attach">1</property>
+		      <property name="top_attach">2</property>
+		      <property name="bottom_attach">3</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkComboBox" id="server-profile-combobox">
+		      <property name="visible">True</property>
+		      <property name="items">Dummy1
+Dummy2</property>
+		      <property name="add_tearoffs">False</property>
+		      <property name="focus_on_click">True</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">1</property>
+		      <property name="right_attach">2</property>
+		      <property name="top_attach">2</property>
+		      <property name="bottom_attach">3</property>
+		      <property name="y_options">fill</property>
+		    </packing>
+		  </child>
+		</widget>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label476">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">_Optional Settings</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		</widget>
+		<packing>
+		  <property name="type">label_item</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
 </glade-interface>
diff -pruN gnome-terminal/src/gnome-terminal.schemas.in gnome-terminal-connect/src/gnome-terminal.schemas.in
--- gnome-terminal/src/gnome-terminal.schemas.in	2005-07-02 01:36:40.000000000 +0200
+++ gnome-terminal-connect/src/gnome-terminal.schemas.in	2005-08-14 19:58:55.156278056 +0200
@@ -110,7 +110,39 @@
          </long>
       </locale>
     </schema>
+
+    <schema>
+      <key>/schemas/apps/gnome-terminal/global/server_expanded</key>
+      <applyto>/apps/gnome-terminal/global/server_expanded</applyto>
+      <owner>gnome-terminal</owner>
+      <type>bool</type>
+      <default>false</default>
+      <locale name="C">
+         <short>Whether server dialogs are expanded by default</short>
+         <long>
+          Whether the Optional Information expander in server editing dialogs
+          should be expanded or not when the dialog is first opened.
+         </long>
+      </locale>
+    </schema>
  
+    <schema>
+      <key>/schemas/apps/gnome-terminal/global/server_list</key>
+      <applyto>/apps/gnome-terminal/global/server_list</applyto>
+      <owner>gnome-terminal</owner>
+      <type>list</type>
+      <list_type>string</list_type>
+      <default>[]</default>
+      <locale name="C">
+         <short>List of servers</short>
+         <long>
+          List of ssh and telnet servers known to gnome-terminal. The list
+          contains strings naming subdirectories relative to
+          /apps/gnome-terminal/servers.
+         </long>
+      </locale>
+    </schema>
+
 
 
 
@@ -665,6 +697,40 @@
     </schema>
 
     <schema>
+      <key>/schemas/apps/gnome-terminal/keybindings/connect_to_server</key>
+      <applyto>/apps/gnome-terminal/keybindings/connect_to_server</applyto>
+      <owner>gnome-terminal</owner>
+      <type>string</type>
+      <default>&lt;Ctrl&gt;&lt;Shift&gt;s</default>
+      <locale name="C">
+         <short>Keyboard shortcut to open connect to server dialog</short>
+         <long>
+          Keyboard shortcut key for opening connect to server dialog. Expressed
+          as a string in the same format used for GTK+ resource files.
+          If you set the option to the special string "disabled", then there 
+          will be no keyboard shortcut for this action.
+         </long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/gnome-terminal/keybindings/disconnect_from_server</key>
+      <applyto>/apps/gnome-terminal/keybindings/disconnect_from_server</applyto>
+      <owner>gnome-terminal</owner>
+      <type>string</type>
+      <default>&lt;Ctrl&gt;&lt;Shift&gt;d</default>
+      <locale name="C">
+         <short>Keyboard shortcut to disconnect from a server</short>
+         <long>
+          Keyboard shortcut key for disconnecting from a server. Expressed
+          as a string in the same format used for GTK+ resource files.
+          If you set the option to the special string "disabled", then there 
+          will be no keyboard shortcut for this action.
+         </long>
+      </locale>
+    </schema>
+
+    <schema>
       <key>/schemas/apps/gnome-terminal/keybindings/new_profile</key>
       <applyto>/apps/gnome-terminal/keybindings/new_profile</applyto>
       <owner>gnome-terminal</owner>
diff -pruN gnome-terminal/src/Makefile.am gnome-terminal-connect/src/Makefile.am
--- gnome-terminal/src/Makefile.am	2005-03-01 02:15:11.000000000 +0100
+++ gnome-terminal-connect/src/Makefile.am	2005-08-14 19:58:55.048294472 +0200
@@ -27,6 +27,8 @@ EGGFILES=			\
 
 ## Terminal
 gnome_terminal_SOURCES=				\
+	connect-to-server.c			\
+	connect-to-server.h			\
 	encoding.c				\
 	encoding.h				\
 	profile-editor.c			\
@@ -60,7 +62,7 @@ schema_in_files = gnome-terminal.schemas
 schema_DATA = gnome-terminal.schemas
 
 icondir = $(datadir)/pixmaps
-icon_DATA = gnome-terminal.png
+icon_DATA = gnome-terminal.png gnome-terminal-connect.png
 
 CLEANFILES = gnome-terminal.schemas
 
diff -pruN gnome-terminal/src/terminal-accels.c gnome-terminal-connect/src/terminal-accels.c
--- gnome-terminal/src/terminal-accels.c	2004-04-26 07:46:24.000000000 +0200
+++ gnome-terminal-connect/src/terminal-accels.c	2005-08-14 19:58:55.243264832 +0200
@@ -32,6 +32,8 @@
 
 #define KEY_NEW_TAB CONF_KEYS_PREFIX"/new_tab"
 #define KEY_NEW_WINDOW CONF_KEYS_PREFIX"/new_window"
+#define KEY_CONNECT_TO_SERVER CONF_KEYS_PREFIX"/connect_to_server"
+#define KEY_DISCONNECT_FROM_SERVER CONF_KEYS_PREFIX"/disconnect_from_server"
 #define KEY_NEW_PROFILE CONF_KEYS_PREFIX"/new_profile"
 #define KEY_CLOSE_TAB CONF_KEYS_PREFIX"/close_tab"
 #define KEY_CLOSE_WINDOW CONF_KEYS_PREFIX"/close_window"
@@ -76,6 +78,10 @@ static KeyEntry file_entries[] =
     KEY_NEW_TAB, ACCEL_PATH_NEW_TAB, 0, 0, NULL, FALSE },
   { N_("New Window"),
     KEY_NEW_WINDOW, ACCEL_PATH_NEW_WINDOW, 0, 0, NULL, FALSE },
+  { N_("Connect to Server"),
+    KEY_CONNECT_TO_SERVER, ACCEL_PATH_CONNECT_TO_SERVER, 0, 0, NULL, FALSE },
+  { N_("Disconnect from Server"),
+    KEY_DISCONNECT_FROM_SERVER, ACCEL_PATH_DISCONNECT_FROM_SERVER, 0, 0, NULL, FALSE },
   { N_("New Profile"),
     KEY_NEW_PROFILE, ACCEL_PATH_NEW_PROFILE, 0, 0, NULL, FALSE },
   { N_("Close Tab"),
diff -pruN gnome-terminal/src/terminal-accels.h gnome-terminal-connect/src/terminal-accels.h
--- gnome-terminal/src/terminal-accels.h	2002-10-05 00:29:01.000000000 +0200
+++ gnome-terminal-connect/src/terminal-accels.h	2005-08-14 19:58:55.252263464 +0200
@@ -31,6 +31,8 @@ GtkAccelGroup* terminal_accels_get_group
 #define ACCEL_PATH_ROOT "<terminal-accels>/menu"
 #define ACCEL_PATH_NEW_TAB ACCEL_PATH_ROOT"/new_tab"
 #define ACCEL_PATH_NEW_WINDOW ACCEL_PATH_ROOT"/new_window"
+#define ACCEL_PATH_CONNECT_TO_SERVER ACCEL_PATH_ROOT"/connect_to_server"
+#define ACCEL_PATH_DISCONNECT_FROM_SERVER ACCEL_PATH_ROOT"/disconnect_from_server"
 #define ACCEL_PATH_NEW_PROFILE ACCEL_PATH_ROOT"/new_profile"
 #define ACCEL_PATH_CLOSE_TAB ACCEL_PATH_ROOT"/close_tab"
 #define ACCEL_PATH_CLOSE_WINDOW ACCEL_PATH_ROOT"/close_window"
diff -pruN gnome-terminal/src/terminal.c gnome-terminal-connect/src/terminal.c
--- gnome-terminal/src/terminal.c	2005-07-02 01:39:27.000000000 +0200
+++ gnome-terminal-connect/src/terminal.c	2005-08-14 19:58:55.353248112 +0200
@@ -28,6 +28,7 @@
 #include "terminal-widget.h"
 #include "profile-editor.h"
 #include "encoding.h"
+#include "connect-to-server.h"
 #include <gconf/gconf-client.h>
 #include <bonobo-activation/bonobo-activation-activate.h>
 #include <bonobo-activation/bonobo-activation-register.h>
@@ -96,6 +97,7 @@ typedef struct
   gboolean default_window_menubar_forced;
   gboolean default_window_menubar_state;
   gboolean default_start_fullscreen;
+  gboolean connect_to_server;
   char *default_geometry;
   char *default_working_dir;
   char **post_execute_args;
@@ -166,6 +168,7 @@ enum {
   OPTION_DEFAULT_WORKING_DIRECTORY,
   OPTION_ZOOM,
   OPTION_ACTIVE,
+  OPTION_CONNECT_TO_SERVER,
   OPTION_COMPAT,
   OPTION_LAST
 };  
@@ -369,6 +372,15 @@ struct poptOption options[] = {  
     N_("Set the last specified tab as the active one in its window"),
     N_("ZOOMFACTOR")
   },
+  {
+    "connect-to-server",
+    '\0',
+    POPT_ARG_NONE,
+    NULL,
+    OPTION_CONNECT_TO_SERVER,
+    N_("Open the connect to server dialog"),
+    NULL
+  },
   
   /*
    * Crappy old compat args
@@ -1154,6 +1166,10 @@ parse_options_callback (poptContext     
         it->active = TRUE;
       }
       break;
+
+    case OPTION_CONNECT_TO_SERVER:
+      results->connect_to_server = TRUE;
+      break;
       
     case OPTION_COMPAT:
       g_printerr (_("Option --%s is no longer supported in this version of gnome-terminal; you might want to create a profile with the desired setting, and use the new --window-with-profile option\n"), opt->longName);
@@ -1223,6 +1239,7 @@ option_parsing_results_init (int *argc, 
   results = g_new0 (OptionParsingResults, 1);
   results->screen_number = -1;
   results->default_working_dir = NULL;
+  results->connect_to_server = FALSE;
   
   /* pre-scan for -x and --execute options (code from old gnome-terminal) */
   results->post_execute_args = NULL;
@@ -1444,7 +1461,8 @@ new_terminal_with_options (OptionParsing
                                          it->zoom : 1.0,
                                          results->startup_id,
                                          results->display_name,
-                                         results->screen_number);
+                                         results->screen_number,
+                                         NULL);
 
               current_window = g_list_last (app->windows)->data;
             }
@@ -1462,7 +1480,8 @@ new_terminal_with_options (OptionParsing
                                          NULL,
                                          it->zoom_set ?
                                          it->zoom : 1.0,
-                                         NULL, NULL, -1);
+                                         NULL, NULL, -1,
+                                         NULL);
             }
           
           if (it->active)
@@ -1604,8 +1623,8 @@ main (int argc, char **argv)
   g_set_application_name (_("Terminal"));
   
   argc_copy = argc;
-  /* we leave empty slots, for --startup-id, --display and --default-working-directory */
-  argv_copy = g_new0 (char *, argc_copy + 7);
+  /* we leave empty slots, for --startup-id, --display, --default-working-directory and --connect-to-server */
+  argv_copy = g_new0 (char *, argc_copy + 9);
   for (i = 0; i < argc_copy; i++)
     argv_copy [i] = g_strdup (argv [i]);
   argv_copy [i] = NULL;
@@ -1685,6 +1704,13 @@ main (int argc, char **argv)
                        "--startup-id", results->startup_id);
         }
 
+      if (results->connect_to_server)
+        {
+          /* we allocated argv_copy with extra space so we could do this */
+          insert_args (&argc_copy, argv_copy,
+                       "--connect-to-server", "");    /* FIXME: "" */
+        }
+
       /* Forward our display to the child */
       insert_args (&argc_copy, argv_copy,
                    "--display", results->display_name);
@@ -1745,6 +1771,8 @@ main (int argc, char **argv)
   terminal_profile_initialize (conf);
   sync_profile_list (FALSE, NULL);
 
+  terminal_connect_to_server_init (conf);
+
   sm_client = gnome_master_client ();
   g_signal_connect (G_OBJECT (sm_client),
                     "save_yourself",
@@ -1755,7 +1783,11 @@ main (int argc, char **argv)
                     G_CALLBACK (client_die_cb),
                     NULL);
 
-  if (new_terminal_with_options (results))
+  if (results->connect_to_server)
+    {
+      terminal_connect_to_server (NULL);
+    }
+  else if (new_terminal_with_options (results))
     {
       option_parsing_results_free (results);
       return 1;
@@ -1895,7 +1927,8 @@ terminal_app_new_terminal (TerminalApp  
                            double           zoom,
                            const char      *startup_id,
                            const char      *display_name,
-                           int              screen_number)
+                           int              screen_number,
+                           const char      *encoding)
 {
   TerminalScreen *screen;
   gboolean window_created;
@@ -1951,6 +1984,14 @@ terminal_app_new_terminal (TerminalApp  
   if (override_command)    
     terminal_screen_set_override_command (screen, override_command);
 
+  if (encoding)
+    {
+      GtkWidget *widget;
+
+      widget = terminal_screen_get_widget (screen);
+      terminal_widget_set_encoding (widget, encoding);
+    }
+
   terminal_screen_set_font_scale (screen, zoom);
   
   terminal_window_add_screen (window, screen);
@@ -1982,6 +2023,12 @@ terminal_app_new_terminal (TerminalApp  
   terminal_screen_launch_child (screen);
 }
 
+GList*
+terminal_app_get_windows (TerminalApp *app)
+{
+  return app->windows;
+}
+
 static GList*
 find_profile_link (GList      *profiles,
                    const char *name)
@@ -2140,6 +2187,8 @@ sync_profile_list (gboolean use_this_lis
 
       tmp_list = tmp_list->next;
     }
+
+  terminal_connect_to_server_reread_profiles ();
 }
 
 static void
@@ -3690,7 +3739,10 @@ handle_new_terminal_event (int          
 
   option_parsing_results_apply_directory_defaults (results);
 
-  new_terminal_with_options (results);
+  if (results->connect_to_server)
+    terminal_connect_to_server (NULL);
+  else
+    new_terminal_with_options (results);
 
   option_parsing_results_free (results);
 }
diff -pruN gnome-terminal/src/terminal.h gnome-terminal-connect/src/terminal.h
--- gnome-terminal/src/terminal.h	2004-10-31 03:32:39.000000000 +0100
+++ gnome-terminal-connect/src/terminal.h	2005-08-14 19:58:55.361246896 +0200
@@ -53,7 +53,10 @@ void terminal_app_new_terminal (Terminal
                                 double           zoom,
                                 const char      *startup_id,
                                 const char      *display_name,
-                                int              screen_number);
+                                int              screen_number,
+                                const char      *encoding);
+
+GList *terminal_app_get_windows (TerminalApp *app);
 
 void terminal_app_manage_profiles (TerminalApp     *app,
                                    GtkWindow       *transient_parent);
diff -pruN gnome-terminal/src/terminal-screen.c gnome-terminal-connect/src/terminal-screen.c
--- gnome-terminal/src/terminal-screen.c	2005-07-02 02:38:04.000000000 +0200
+++ gnome-terminal-connect/src/terminal-screen.c	2005-08-14 19:58:55.292257384 +0200
@@ -27,6 +27,7 @@
 #define GTK_DISABLE_DEPRECATED
 #define GDK_DISABLE_DEPRECATED
 
+#include "connect-to-server.h"
 #include "terminal-intl.h"
 #include "terminal-accels.h"
 #include "terminal-window.h"
@@ -1162,7 +1163,7 @@ new_window_callback (GtkWidget      *men
                              NULL,
                              FALSE, FALSE, FALSE,
                              NULL, NULL, NULL, dir, NULL, 1.0,
-                             NULL, name, -1);
+                             NULL, name, -1, NULL);
 
   g_free (name);
 }
@@ -1180,7 +1181,7 @@ new_tab_callback (GtkWidget      *menu_i
                              screen->priv->window,
                              FALSE, FALSE, FALSE,
                              NULL, NULL, NULL, dir, NULL, 1.0,
-                             NULL, NULL, -1);
+                             NULL, NULL, -1, NULL);
 }
 
 static void
@@ -1913,21 +1914,28 @@ terminal_screen_widget_child_died (GtkWi
   TerminalExitAction action;
 
   screen->priv->child_pid = -1;
-  
-  action = TERMINAL_EXIT_CLOSE;
-  if (screen->priv->profile)
-    action = terminal_profile_get_exit_action (screen->priv->profile);
-  
-  switch (action)
+
+  if (!terminal_connect_screen_is_connected (screen))
     {
-    case TERMINAL_EXIT_CLOSE:
-      terminal_screen_close (screen);
-      break;
-    case TERMINAL_EXIT_RESTART:
-      terminal_screen_launch_child (screen);
-      break;
-    case TERMINAL_EXIT_HOLD:
-      break;
+      action = TERMINAL_EXIT_CLOSE;
+      if (screen->priv->profile)
+        action = terminal_profile_get_exit_action (screen->priv->profile);
+
+      switch (action)
+        {
+        case TERMINAL_EXIT_CLOSE:
+          terminal_screen_close (screen);
+          break;
+        case TERMINAL_EXIT_RESTART:
+          terminal_screen_launch_child (screen);
+          break;
+        case TERMINAL_EXIT_HOLD:
+          break;
+        }
+    }
+  else
+    {
+      terminal_connect_screen_disconnect (screen);
     }
 }
 
diff -pruN gnome-terminal/src/terminal-window.c gnome-terminal-connect/src/terminal-window.c
--- gnome-terminal/src/terminal-window.c	2005-08-08 16:33:32.000000000 +0200
+++ gnome-terminal-connect/src/terminal-window.c	2005-08-14 19:58:55.337250544 +0200
@@ -20,6 +20,7 @@
  * Boston, MA 02111-1307, USA.
  */
 
+#include "connect-to-server.h"
 #include "terminal-intl.h"
 #include "terminal-accels.h"
 #include "terminal-widget.h"
@@ -47,6 +48,7 @@ struct _TerminalWindowPrivate
   GtkWidget *help_menuitem;
   GtkWidget *new_window_menuitem;
   GtkWidget *new_tab_menuitem;
+  GtkWidget *disconnect_menuitem;
   GtkWidget *close_tab_menuitem;
   GtkWidget *copy_menuitem;
   GtkWidget *paste_menuitem;
@@ -65,6 +67,7 @@ struct _TerminalWindowPrivate
   GList *terms;
   TerminalScreen *active_term;
   GdkPixbuf *icon;
+  GdkPixbuf *connect_icon;
   GtkClipboard *clipboard;
   int old_char_width;
   int old_char_height;
@@ -101,18 +104,21 @@ static gboolean terminal_window_delete_e
                                               GdkEvent *event,
                                               gpointer data);
 
-static void       screen_set_scrollbar (TerminalScreen *screen,
-                                        GtkWidget      *scrollbar);
-static void       screen_set_hbox      (TerminalScreen *screen,
-                                        GtkWidget      *hbox);
-static void       screen_set_label     (TerminalScreen *screen,
-                                        GtkWidget      *label);
-static void       screen_set_menuitem  (TerminalScreen *screen,
-                                        GtkWidget      *menuitem);
-static GtkWidget* screen_get_scrollbar (TerminalScreen *screen);
-static GtkWidget* screen_get_hbox      (TerminalScreen *screen);
-static GtkWidget* screen_get_label     (TerminalScreen *screen);
-static GtkWidget* screen_get_menuitem  (TerminalScreen *screen);
+static void       screen_set_scrollbar  (TerminalScreen *screen,
+                                         GtkWidget      *scrollbar);
+static void       screen_set_hbox       (TerminalScreen *screen,
+                                         GtkWidget      *hbox);
+static void       screen_set_label      (TerminalScreen *screen,
+                                         GtkWidget      *label);
+static void       screen_set_label_icon (TerminalScreen *screen,
+                                         GtkWidget      *label);
+static void       screen_set_menuitem   (TerminalScreen *screen,
+                                         GtkWidget      *menuitem);
+static GtkWidget* screen_get_scrollbar  (TerminalScreen *screen);
+static GtkWidget* screen_get_hbox       (TerminalScreen *screen);
+static GtkWidget* screen_get_label      (TerminalScreen *screen);
+static GtkWidget* screen_get_label_icon (TerminalScreen *screen);
+static GtkWidget* screen_get_menuitem   (TerminalScreen *screen);
 
 static TerminalScreen* find_screen_by_hbox (TerminalWindow *window,
                                             GtkWidget      *hbox);
@@ -142,6 +148,10 @@ static void new_window_callback         
                                            TerminalWindow *window);
 static void new_tab_callback              (GtkWidget      *menuitem,
                                            TerminalWindow *window);
+static void connect_to_server_callback    (GtkWidget      *menuitem,
+                                           TerminalWindow *window);
+static void disconnect_from_server_callback (GtkWidget      *menuitem,
+                                             TerminalWindow *window);
 static void close_window_callback         (GtkWidget      *menuitem,
                                            TerminalWindow *window);
 static void close_tab_callback            (GtkWidget      *menuitem,
@@ -853,7 +863,19 @@ terminal_window_init (TerminalWindow *wi
 
   window->priv->new_tab_menuitem =
     append_menuitem (menu, _("Open Ta_b"), NULL, NULL, NULL);
-  
+
+  mi = gtk_separator_menu_item_new ();
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+
+  append_menuitem (menu, _("Connect to _Server..."),
+                   ACCEL_PATH_CONNECT_TO_SERVER,
+                   G_CALLBACK (connect_to_server_callback), window);
+
+  window->priv->disconnect_menuitem =
+    append_menuitem (menu, _("_Disconnect from Server"),
+                     ACCEL_PATH_DISCONNECT_FROM_SERVER,
+                     G_CALLBACK (disconnect_from_server_callback), window);
+
   mi = gtk_separator_menu_item_new ();
   gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
 
@@ -1087,6 +1109,9 @@ terminal_window_finalize (GObject *objec
   if (window->priv->icon)
     g_object_unref (G_OBJECT (window->priv->icon));
 
+  if (window->priv->connect_icon)
+    g_object_unref (G_OBJECT (window->priv->connect_icon));
+
   g_free (window->priv->startup_id);
   
   g_free (window->priv);
@@ -1317,6 +1342,18 @@ icon_title_changed_callback (TerminalScr
     gdk_window_set_icon_name (GTK_WIDGET (window)->window, terminal_screen_get_icon_title (screen));
 }
 
+static void
+update_disconnect_sensitivity (TerminalWindow *window)
+{
+  gboolean can_disconnect = FALSE;
+
+  if (window->priv->active_term)
+    can_disconnect = terminal_connect_screen_is_connected (window->priv->active_term);
+  else
+    can_disconnect = FALSE;
+
+  gtk_widget_set_sensitive (window->priv->disconnect_menuitem, can_disconnect);
+}
 
 static void
 update_copy_sensitivity (TerminalWindow *window)
@@ -1376,7 +1413,9 @@ terminal_window_add_screen (TerminalWind
   GtkWidget *term;
   GtkWidget *hbox;
   GtkWidget *scrollbar;
-  GtkWidget *label;  
+  GtkWidget *label_hbox;
+  GtkWidget *label;
+  GtkWidget *label_icon;
   
   old = terminal_screen_get_window (screen);
 
@@ -1398,14 +1437,20 @@ terminal_window_add_screen (TerminalWind
 
   hbox = gtk_hbox_new (FALSE, 0);
   scrollbar = gtk_vscrollbar_new (NULL);
+
+  label_hbox = gtk_hbox_new (FALSE, 4);
+  label_icon = gtk_image_new ();
+  gtk_box_pack_start (GTK_BOX (label_hbox), label_icon, FALSE, FALSE, 0);
   label = gtk_label_new (terminal_screen_get_title (screen));
   gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
   gtk_widget_show (label);
   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+  gtk_box_pack_start (GTK_BOX (label_hbox), label, TRUE, TRUE, 0);
   
   screen_set_hbox (screen, hbox);
   screen_set_scrollbar (screen, scrollbar);
   screen_set_label (screen, label);
+  screen_set_label_icon (screen, label_icon);
 
   g_signal_connect (G_OBJECT (screen),
                     "profile_set",
@@ -1442,7 +1487,7 @@ terminal_window_add_screen (TerminalWind
   
   gtk_notebook_append_page (GTK_NOTEBOOK (window->priv->notebook),
                             hbox,
-                            label);
+                            label_hbox);
 
   reset_tab_menuitems (window);
   update_tab_sensitivity (window);
@@ -1524,9 +1569,13 @@ terminal_window_remove_screen (TerminalW
 
   screen_set_hbox (screen, NULL);
   screen_set_label (screen, NULL);
+  screen_set_label_icon (screen, NULL);
   screen_set_scrollbar (screen, NULL);
   screen_set_menuitem (screen, NULL);
   
+  if (terminal_connect_screen_is_connected (screen))
+    terminal_connect_screen_disconnect (screen);
+
   g_object_unref (G_OBJECT (screen));
   
   update_notebook (window);
@@ -1732,7 +1781,8 @@ terminal_window_set_active (TerminalWind
   g_print ("setting size after flipping notebook pages\n");
 #endif
   terminal_window_set_size (window, screen, TRUE);
-  
+
+  update_disconnect_sensitivity (window);
   update_copy_sensitivity (window);
   
   fill_in_config_picker_submenu (window);
@@ -1776,6 +1826,15 @@ screen_set_label (TerminalScreen *screen
 }
 
 static void
+screen_set_label_icon (TerminalScreen *screen,
+                       GtkWidget      *label_icon)
+{
+  g_object_set_data (G_OBJECT (screen),
+                     "label_icon",
+                     label_icon);
+}
+
+static void
 screen_set_menuitem  (TerminalScreen *screen,
                       GtkWidget      *menuitem)
 {
@@ -1803,6 +1862,12 @@ screen_get_label (TerminalScreen *screen
 }
 
 static GtkWidget*
+screen_get_label_icon (TerminalScreen *screen)
+{
+  return g_object_get_data (G_OBJECT (screen), "label_icon");
+}
+
+static GtkWidget*
 screen_get_menuitem (TerminalScreen *screen)
 {
   return g_object_get_data (G_OBJECT (screen), "menuitem");
@@ -1925,10 +1990,31 @@ terminal_window_update_scrollbar (Termin
   g_object_unref (G_OBJECT (scrollbar));
 }
 
+static GdkPixbuf*
+get_connect_icon (TerminalWindow *window)
+{
+  if (!window->priv->connect_icon)
+    {
+      const char *filename = TERM_DATADIR"/pixmaps/gnome-terminal-connect.png";
+      GError *err = NULL;
+
+      window->priv->connect_icon = gdk_pixbuf_new_from_file (filename, &err);
+
+      if (!window->priv->connect_icon)
+        {
+          g_printerr (_("Could not load icon \"%s\": %s\n"),
+                      filename, err->message);
+          g_error_free (err);
+        }
+    }
+
+  return window->priv->connect_icon;
+}
+
 void
 terminal_window_update_icon (TerminalWindow *window)
 {
-  GdkPixbuf *new_icon;
+  GdkPixbuf *new_icon = NULL;
   TerminalProfile *profile;
 
   if (window->priv->active_term == NULL)
@@ -1943,8 +2029,15 @@ terminal_window_update_icon (TerminalWin
       gtk_window_set_icon (GTK_WINDOW (window), NULL);
       return;
     }
-  
-  new_icon = terminal_profile_get_icon (profile);
+
+  /* Use connect icon if connected and original icon is set */
+  if (terminal_connect_screen_is_connected (window->priv->active_term) &&
+      (strcmp ("gnome-terminal.png",
+               terminal_profile_get_icon_file (profile)) == 0))
+    new_icon = get_connect_icon (window);
+
+  if (!new_icon)
+    new_icon = terminal_profile_get_icon (profile);
   
   if (window->priv->icon != new_icon)
     {
@@ -2270,7 +2363,7 @@ new_window_callback (GtkWidget      *men
                                  NULL,
                                  FALSE, FALSE, FALSE,
                                  NULL, NULL, NULL, dir, NULL, 1.0,
-                                 NULL, name, -1);
+                                 NULL, name, -1, NULL);
 
       g_free (name);
     }
@@ -2298,10 +2391,25 @@ new_tab_callback (GtkWidget      *menuit
                                  window,
                                  FALSE, FALSE, FALSE,
                                  NULL, NULL, NULL, dir, NULL, 1.0,
-                                 NULL, NULL, -1);
+                                 NULL, NULL, -1, NULL);
     }
 }
 
+static void
+connect_to_server_callback (GtkWidget      *menuitem,
+                            TerminalWindow *window)
+{
+  terminal_connect_to_server (GTK_WINDOW (window));
+}
+
+static void
+disconnect_from_server_callback (GtkWidget      *menuitem,
+                                 TerminalWindow *window)
+{
+  if (window->priv->active_term)
+    terminal_connect_screen_disconnect (window->priv->active_term);
+}
+
 static gboolean
 confirm_close_window (TerminalWindow *window)
 {
@@ -2825,3 +2933,29 @@ terminal_window_set_startup_id (Terminal
   g_free (window->priv->startup_id);
   window->priv->startup_id = g_strdup (startup_id);
 }
+
+void
+terminal_window_set_connected (TerminalWindow *window,
+                               TerminalScreen *screen,
+                               gboolean        connected)
+{
+  GtkWidget *icon;
+
+  icon = screen_get_label_icon (screen);
+
+  if (connected)
+    {
+      gtk_image_set_from_stock (GTK_IMAGE (icon),
+                                GTK_STOCK_CONNECT,
+                                GTK_ICON_SIZE_MENU);
+      gtk_widget_show (icon);
+    }
+  else
+    {
+      gtk_widget_hide (icon);
+      gtk_image_set_from_pixbuf (GTK_IMAGE (icon), NULL);
+    }
+
+  update_disconnect_sensitivity (window);
+  terminal_window_update_icon (window);
+}
diff -pruN gnome-terminal/src/terminal-window.h gnome-terminal-connect/src/terminal-window.h
--- gnome-terminal/src/terminal-window.h	2004-05-09 08:06:10.000000000 +0200
+++ gnome-terminal-connect/src/terminal-window.h	2005-08-14 19:58:55.345249328 +0200
@@ -98,6 +98,10 @@ void terminal_window_reread_profile_list
 void terminal_window_set_startup_id (TerminalWindow *window,
                                      const char     *startup_id);
 
+void terminal_window_set_connected (TerminalWindow *window,
+                                    TerminalScreen *screen,
+                                    gboolean        connected);
+
 G_END_DECLS
 
 #endif /* TERMINAL_WINDOW_H */
