gnome-mud r788 - in trunk: . src



Author: lharris
Date: Fri Mar 13 23:41:46 2009
New Revision: 788
URL: http://svn.gnome.org/viewvc/gnome-mud?rev=788&view=rev

Log:
Rearchitected Telnet Handler code. Many GObject updates.


Added:
   trunk/src/mud-telnet-charset.c
   trunk/src/mud-telnet-charset.h
   trunk/src/mud-telnet-echo.c
   trunk/src/mud-telnet-echo.h
   trunk/src/mud-telnet-eor.c
   trunk/src/mud-telnet-eor.h
   trunk/src/mud-telnet-handler-interface.c
   trunk/src/mud-telnet-handler-interface.h
   trunk/src/mud-telnet-naws.c
   trunk/src/mud-telnet-naws.h
   trunk/src/mud-telnet-ttype.c
   trunk/src/mud-telnet-ttype.h
Removed:
   trunk/src/mud-telnet-handlers.c
   trunk/src/mud-telnet-handlers.h
Modified:
   trunk/AUTHORS
   trunk/ChangeLog
   trunk/configure.ac
   trunk/src/Makefile.am
   trunk/src/gnome-mud.c
   trunk/src/mud-connection-view.c
   trunk/src/mud-connection-view.h
   trunk/src/mud-connections.c
   trunk/src/mud-parse-alias.c
   trunk/src/mud-parse-alias.h
   trunk/src/mud-parse-base.c
   trunk/src/mud-parse-base.h
   trunk/src/mud-parse-trigger.c
   trunk/src/mud-parse-trigger.h
   trunk/src/mud-profile.c
   trunk/src/mud-profile.h
   trunk/src/mud-regex.c
   trunk/src/mud-regex.h
   trunk/src/mud-telnet-mccp.c
   trunk/src/mud-telnet-mccp.h
   trunk/src/mud-telnet-msp.c
   trunk/src/mud-telnet-msp.h
   trunk/src/mud-telnet-zmp.c
   trunk/src/mud-telnet-zmp.h
   trunk/src/mud-telnet.c
   trunk/src/mud-telnet.h
   trunk/src/mud-tray.c
   trunk/src/mud-window-profile.c
   trunk/src/mud-window.c
   trunk/src/mud-window.h
   trunk/src/utils.c
   trunk/src/utils.h

Modified: trunk/AUTHORS
==============================================================================
--- trunk/AUTHORS	(original)
+++ trunk/AUTHORS	Fri Mar 13 23:41:46 2009
@@ -1,8 +1,9 @@
 AUTHOR
 ---------------
 Robin Ericsson <lobbin localhost nu>
+Les Harris <lharris gnome org>
 
-Recieved Patches and Improvements
+Pre 0.11.0 Patches and Improvements
 ---------------------------------
 David Zanetti <dave lynx co nz>          - fixed bug in load_wizard()
 Ben Gertzfield <che debian org>          - creation of ~/.amcl

Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac	(original)
+++ trunk/configure.ac	Fri Mar 13 23:41:46 2009
@@ -53,6 +53,18 @@
 	AC_MSG_ERROR([gconftool-2 executable not found in your path - should be installed with GConf])
 fi
 
+dnl Checks for programs.
+AC_PROG_CC
+AM_PROG_CC_STDC
+AC_ISC_POSIX
+AC_PROG_LN_S
+AC_PROG_INSTALL
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_HEADER_TIME
+AC_CHECK_HEADERS(strings.h)
+
 dnl pkg-config dep checks
 GMODULE_REQUIRED=2.0.0
 GTK_REQUIRED=2.10.0
@@ -67,16 +79,6 @@
 AC_SUBST(GMUD_CFLAGS)
 AC_SUBST(GMUD_LIBS)
 
-dnl Checks for programs.
-AC_PROG_CC
-AC_ISC_POSIX
-
-dnl Checks for header files.
-AC_HEADER_STDC
-AC_HEADER_TIME
-AC_HEADER_DIRENT
-AC_CHECK_HEADERS(strings.h)
-
 AC_DEFINE(HAVE_LIBSM, 1, [Define this to have session management.])
 
 dnl Check whether to include MCCP code or not
@@ -129,16 +131,6 @@
 fi
 AM_CONDITIONAL(USE_DEBUG_LOGGER, test "x$enable_debug_logger" = xyes)
 
-dnl Checks for programs.
-AC_ISC_POSIX
-AM_PROG_CC_STDC
-AC_PROG_LN_S
-AC_PROG_INSTALL
-
-dnl Checks for typedefs, structures, and compiler characteristics.
-AC_C_CONST
-AC_C_INLINE
-
 AC_CONFIG_FILES([
   Makefile
   gnome-mud.spec

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Fri Mar 13 23:41:46 2009
@@ -21,31 +21,41 @@
 	debug-logger.h				\
 	gnome-mud.c				\
 	gnome-mud.h				\
-	gnome-mud-icons.h \
-	mud-connection-view.c		\
-	mud-connections.c \
-	mud-connections.h \
-	mud-connection-view.h		\
-	mud-log.c					\
-	mud-log.h					\
+	gnome-mud-icons.h			\
+	mud-connection-view.c			\
+	mud-connections.c			\
+	mud-connections.h			\
+	mud-connection-view.h			\
+	mud-log.c				\
+	mud-log.h				\
 	mud-parse-alias.c			\
 	mud-parse-alias.h			\
 	mud-parse-base.c			\
 	mud-parse-base.h			\
 	mud-parse-trigger.c			\
 	mud-parse-trigger.h			\
-	mud-preferences-window.c	\
-	mud-preferences-window.h	\
+	mud-preferences-window.c		\
+	mud-preferences-window.h		\
 	mud-profile.c				\
 	mud-profile.h				\
 	mud-regex.c				\
 	mud-regex.h				\
-	mud-telnet.c                \
-	mud-telnet.h                \
-	mud-telnet-handlers.c		\
-	mud-telnet-handlers.h		\
-	mud-telnet-mccp.c \
-	mud-telnet-mccp.h \
+	mud-telnet.c				\
+	mud-telnet.h				\
+	mud-telnet-handler-interface.c		\
+	mud-telnet-handler-interface.h		\
+	mud-telnet-ttype.c			\
+	mud-telnet-ttype.h			\
+	mud-telnet-naws.c			\
+	mud-telnet-naws.h			\
+	mud-telnet-echo.c			\
+	mud-telnet-echo.h			\
+	mud-telnet-eor.c			\
+	mud-telnet-eor.h			\
+	mud-telnet-charset.c			\
+	mud-telnet-charset.h			\
+	mud-telnet-mccp.c			\
+	mud-telnet-mccp.h			\
 	mud-telnet-msp.c			\
 	mud-telnet-msp.h			\
 	mud-telnet-zmp.c			\
@@ -54,7 +64,8 @@
 	mud-tray.h				\
 	mud-window.c				\
 	mud-window.h				\
-	mud-window-profile.c		\
-	mud-window-profile.h		\
+	mud-window-profile.c			\
+	mud-window-profile.h			\
 	utils.c					\
 	utils.h
+

Modified: trunk/src/gnome-mud.c
==============================================================================
--- trunk/src/gnome-mud.c	(original)
+++ trunk/src/gnome-mud.c	Fri Mar 13 23:41:46 2009
@@ -41,13 +41,14 @@
 #include "utils.h"
 #include "debug-logger.h"
 
-int main (gint argc, char *argv[])
+gint
+main (gint argc, char *argv[])
 {
     MudWindow *window;
     GConfClient *client;
     DebugLogger *logger;
     GError      *err = NULL;
-    gchar       buf[2048];
+    GString *dir;
 
 #ifdef ENABLE_NLS
     /* Initialize internationalization */
@@ -78,17 +79,23 @@
     gconf_client_add_dir(client, "/apps/gnome-mud",
             GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
 
-    g_snprintf(buf, 2048, "%s/.gnome-mud/", g_get_home_dir());
-    if(!g_file_test(buf, G_FILE_TEST_IS_DIR))
-        mkdir(buf, 0777);
-
-    g_snprintf(buf, 2048, "%s/.gnome-mud/logs/", g_get_home_dir());
-    if(!g_file_test(buf, G_FILE_TEST_IS_DIR))
-        mkdir(buf, 0777 );
-
-    g_snprintf(buf, 2048, "%s/.gnome-mud/audio/", g_get_home_dir());
-    if(!g_file_test(buf, G_FILE_TEST_IS_DIR))
-        mkdir(buf, 0777 );
+    dir = g_string_new(NULL);
+    g_string_printf(dir,
+                    "%s%cgnome-mud%clogs",
+                    g_get_user_data_dir(),
+                    G_DIR_SEPARATOR,
+                    G_DIR_SEPARATOR);
+    g_mkdir_with_parents(dir->str, 0755);      
+    g_string_free(dir, TRUE);
+
+    dir = g_string_new(NULL);
+    g_string_printf(dir,
+                    "%s%cgnome-mud%caudio",
+                    g_get_user_data_dir(),
+                    G_DIR_SEPARATOR,
+                    G_DIR_SEPARATOR);
+    g_mkdir_with_parents(dir->str, 0755); 
+    g_string_free(dir, TRUE);
 
     gtk_about_dialog_set_url_hook(utils_activate_url, NULL, NULL);
 
@@ -111,7 +118,7 @@
 #endif
 
     /* Let 'er rip */
-    window = g_object_new(TYPE_MUD_WINDOW, NULL);
+    window = g_object_new(MUD_TYPE_WINDOW, NULL);
 
     gtk_main();
 
@@ -122,3 +129,4 @@
 
     return 0;
 }
+

Modified: trunk/src/mud-connection-view.c
==============================================================================
--- trunk/src/mud-connection-view.c	(original)
+++ trunk/src/mud-connection-view.c	Fri Mar 13 23:41:46 2009
@@ -45,409 +45,585 @@
 
 struct _MudConnectionViewPrivate
 {
-    gint id;
-
-    MudWindow *window;
-    MudTray *tray;
-
-    GtkWidget *terminal;
     GtkWidget *scrollbar;
-    GtkWidget *box;
     GtkWidget *popup_menu;
     GtkWidget *progressbar;
     GtkWidget *dl_label;
     GtkWidget *dl_button;
 
-    MudProfile *profile;
-    MudLog *log;
-
+    GString *processed;
+    
     gulong signal;
     gulong signal_profile_changed;
 
-    gboolean connect_hook;
-    gboolean connected;
-    gchar *connect_string;
-
-    MudParseBase *parse;
-
     GQueue *history;
-    guint current_history_index;
-
-    MudTelnet *telnet;
-    gchar *hostname;
-    guint port;
-
-    gchar *mud_name;
+    gint current_history_index;
 
 #ifdef ENABLE_GST
     GQueue *download_queue;
     GConnHttp *dl_conn;
     gboolean downloading;
 #endif
+};
 
-    GString *processed;
+/* Property Identifiers */
+enum
+{
+    PROP_MUD_CONNECTION_VIEW_0,
+    PROP_CONNECTION,
+    PROP_NAWS_ENABLED,
+    PROP_LOCAL_ECHO,
+    PROP_REMOTE_ENCODE,
+    PROP_CONNECT_HOOK,
+    PROP_CONNECTED,
+    PROP_CONNECT_STRING,
+    PROP_REMOTE_ENCODING,
+    PROP_PORT,
+    PROP_MUD_NAME,
+    PROP_HOSTNAME,
+    PROP_LOG,
+    PROP_TRAY,
+    PROP_PROFILE,
+    PROP_PARSE_BASE,
+    PROP_TELNET,
+    PROP_WINDOW,
+    PROP_PROFILE_NAME,
+    PROP_LOGGING,
+    PROP_TERMINAL,
+    PROP_VBOX
 };
 
-static void mud_connection_view_init                     (MudConnectionView *connection_view);
-static void mud_connection_view_class_init               (MudConnectionViewClass *klass);
-static void mud_connection_view_finalize                 (GObject *object);
-static void mud_connection_view_set_terminal_colors      (MudConnectionView *view);
-static void mud_connection_view_set_terminal_scrollback  (MudConnectionView *view);
-static void mud_connection_view_set_terminal_scrolloutput(MudConnectionView *view);
-static void mud_connection_view_set_terminal_font        (MudConnectionView *view);
-static void mud_connection_view_profile_changed_cb       (MudProfile *profile, MudProfileMask *mask, MudConnectionView *view);
-static gboolean mud_connection_view_button_press_event   (GtkWidget *widget, GdkEventButton *event, MudConnectionView *view);
-static void mud_connection_view_popup                    (MudConnectionView *view, GdkEventButton *event);
-static void mud_connection_view_reread_profile           (MudConnectionView *view);
-static void mud_connection_view_network_event_cb(GConn *conn, GConnEvent *event, gpointer data);
+/* Create the Type */
+G_DEFINE_TYPE(MudConnectionView, mud_connection_view, G_TYPE_OBJECT);
 
-static void mud_connection_view_resized_cb(MudWindow *window, MudConnectionView *view);
+/* Class Functions */
+static void mud_connection_view_init (MudConnectionView *connection_view);
+static void mud_connection_view_class_init (MudConnectionViewClass *klass);
+static void mud_connection_view_finalize (GObject *object);
+
+static GObject *mud_connection_view_constructor(GType gtype,
+                                                guint n_properties,
+                                                GObjectConstructParam *props);
+
+static void mud_connection_view_set_property(GObject *object,
+                                             guint prop_id,
+                                             const GValue *value,
+                                             GParamSpec *pspec);
+
+static void mud_connection_view_get_property(GObject *object,
+                                             guint prop_id,
+                                             GValue *value,
+                                             GParamSpec *pspec);
+
+/* Callbacks */
+static void mud_connection_view_profile_changed_cb (MudProfile *profile, 
+                                                    MudProfileMask *mask,
+                                                    MudConnectionView *view);
+static gboolean mud_connection_view_button_press_event(GtkWidget *widget, 
+                                                       GdkEventButton *event,
+                                                       MudConnectionView *view);
+static void mud_connection_view_popup(MudConnectionView *view, 
+                                      GdkEventButton *event);
+
+static void popup_menu_detach(GtkWidget *widget, GtkMenu *menu);
+static void mud_connection_view_network_event_cb(GConn *conn, 
+                                                 GConnEvent *event,
+                                                 gpointer data);
+static void mud_connection_view_close_current_cb(GtkWidget *menu_item,
+                                                 MudConnectionView *view);
+static void mud_connection_view_profile_changed_cb(MudProfile *profile,
+                                                   MudProfileMask *mask,
+                                                   MudConnectionView *view);
+
+/* Private Methods */
+static void mud_connection_view_set_terminal_colors(MudConnectionView *view);
+static void mud_connection_view_set_terminal_scrollback(MudConnectionView *view);
+static void mud_connection_view_set_terminal_scrolloutput(MudConnectionView *view);
+static void mud_connection_view_set_terminal_font(MudConnectionView *view);
+static GtkWidget* append_stock_menuitem(GtkWidget *menu, 
+                                        const gchar *text,
+                                        GCallback callback,
+                                        gpointer data);
+static GtkWidget* append_menuitem(GtkWidget *menu,
+                                  const gchar *text,
+                                  GCallback callback,
+                                  gpointer data);
+static void choose_profile_callback(GtkWidget *menu_item,
+                                    MudConnectionView *view);
+static void mud_connection_view_reread_profile(MudConnectionView *view);
+static void mud_connection_view_feed_text(MudConnectionView *view,
+                                          gchar *message);
 
 #ifdef ENABLE_GST
-static void mud_connection_view_http_cb(GConnHttp *conn, GConnHttpEvent *event, gpointer data);
-static void mud_connection_view_cancel_dl_cb(GtkWidget *widget, MudConnectionView *view);
+static void mud_connection_view_http_cb(GConnHttp *conn,
+                                        GConnHttpEvent *event,
+                                        gpointer data);
+static void mud_connection_view_cancel_dl_cb(GtkWidget *widget,
+                                             MudConnectionView *view);
 #endif
 
-GType
-mud_connection_view_get_type (void)
-{
-    static GType object_type = 0;
-
-    g_type_init();
-
-    if (!object_type)
-    {
-        static const GTypeInfo object_info =
-            {
-                sizeof (MudConnectionViewClass),
-                NULL,
-                NULL,
-                (GClassInitFunc) mud_connection_view_class_init,
-                NULL,
-                NULL,
-                sizeof (MudConnectionView),
-                0,
-                (GInstanceInitFunc) mud_connection_view_init,
-            };
-
-        object_type = g_type_register_static(G_TYPE_OBJECT, "MudConnectionView", &object_info, 0);
-    }
-
-    return object_type;
-}
-
-static GtkWidget*
-append_stock_menuitem(GtkWidget *menu, const gchar *text, GCallback callback, gpointer data)
+/* Class Functions */
+static void
+mud_connection_view_class_init (MudConnectionViewClass *klass)
 {
-    GtkWidget *menu_item;
-    GtkWidget *image;
-    GConfClient *client;
-    GError *error;
-    gboolean use_image;
-
-    menu_item = gtk_image_menu_item_new_from_stock(text, NULL);
-    image = gtk_image_menu_item_get_image(GTK_IMAGE_MENU_ITEM(menu_item));
-
-    client = gconf_client_get_default();
-    error = NULL;
-
-    use_image = gconf_client_get_bool(client,
-                                      "/desktop/gnome/interface/menus_have_icons",
-                                      &error);
-    if (error)
-    {
-        g_printerr(_("There was an error loading config value for whether to use image in menus. (%s)\n"),
-                   error->message);
-        g_error_free(error);
-    }
-    else
-    {
-        if (use_image)
-            gtk_widget_show(image);
-        else
-            gtk_widget_hide(image);
-    }
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
 
-    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+    /* Override base object constructor */
+    object_class->constructor = mud_connection_view_constructor;
 
-    if (callback)
-        g_signal_connect(G_OBJECT(menu_item),
-                         "activate",
-                         callback, data);
+    /* Override base object's finalize */
+    object_class->finalize = mud_connection_view_finalize;
 
-    g_object_unref(client);
+    /* Override base object property methods */
+    object_class->set_property = mud_connection_view_set_property;
+    object_class->get_property = mud_connection_view_get_property;
 
-    return menu_item;
-}
+    /* Add private data to class */
+    g_type_class_add_private(klass, sizeof(MudConnectionViewPrivate));
 
-static GtkWidget*
-append_menuitem(GtkWidget *menu, const gchar *text, GCallback callback, gpointer data)
-{
-    GtkWidget *menu_item;
+    /* Create and install properties */
+    
+    // Required construction properties
+    g_object_class_install_property(object_class,
+            PROP_CONNECT_STRING,
+            g_param_spec_string("connect-string",
+                "connect string",
+                "string to send to the mud on connect",
+                NULL,
+                G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
-    menu_item = gtk_menu_item_new_with_mnemonic(text);
-    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+    g_object_class_install_property(object_class,
+            PROP_PORT,
+            g_param_spec_int("port",
+                "port",
+                "the port of the mud",
+                1, 200000,
+                23,
+                G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+    g_object_class_install_property(object_class,
+            PROP_MUD_NAME,
+            g_param_spec_string("mud-name",
+                "mud name",
+                "the name of the mud",
+                NULL,
+                G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
-    if (callback)
-        g_signal_connect(G_OBJECT(menu_item), "activate", callback, data);
+    g_object_class_install_property(object_class,
+            PROP_HOSTNAME,
+            g_param_spec_string("hostname",
+                "hostname",
+                "the host of the mud",
+                NULL,
+                G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
-    return menu_item;
-}
+    g_object_class_install_property(object_class,
+            PROP_WINDOW,
+            g_param_spec_object("window",
+                "window",
+                "the parent mud window object",
+                MUD_TYPE_WINDOW,
+                G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+    g_object_class_install_property(object_class,
+            PROP_PROFILE_NAME,
+            g_param_spec_string("profile-name",
+                "profile name",
+                "the name of the current profile",
+                NULL,
+                G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
-static void
-popup_menu_detach(GtkWidget *widget, GtkMenu *menu)
-{
-    MudConnectionView *view;
+    // Setable properties
+    g_object_class_install_property(object_class,
+            PROP_REMOTE_ENCODE,
+            g_param_spec_boolean("remote-encode",
+                "remote encode",
+                "do we accept encoding negotiation",
+                FALSE,
+                G_PARAM_READWRITE));
+
+    g_object_class_install_property(object_class,
+            PROP_REMOTE_ENCODING,
+            g_param_spec_string("remote-encoding",
+                "remote encoding",
+                "the negotiated encoding of the terminal",
+                NULL,
+                G_PARAM_READWRITE));
 
-    view = g_object_get_data(G_OBJECT(widget), "connection-view");
-    view->priv->popup_menu = NULL;
+    g_object_class_install_property(object_class,
+            PROP_NAWS_ENABLED,
+            g_param_spec_boolean("naws-enabled",
+                "naws enabled",
+                "negoatiate about window size enabled",
+                FALSE,
+                G_PARAM_READWRITE));
+
+    g_object_class_install_property(object_class,
+            PROP_LOCAL_ECHO,
+            g_param_spec_boolean("local-echo",
+                "local echo",
+                "do we display the text sent to the mud",
+                TRUE,
+                G_PARAM_READWRITE));
+
+    // Readable Properties
+    g_object_class_install_property(object_class,
+            PROP_TRAY,
+            g_param_spec_object("tray",
+                "mud tray",
+                "mud status tray icon",
+                MUD_TYPE_TRAY,
+                G_PARAM_READABLE));
+
+    g_object_class_install_property(object_class,
+            PROP_CONNECTION,
+            g_param_spec_pointer("connection",
+                "connection",
+                "the connection to the mud",
+                G_PARAM_READABLE));
+
+    g_object_class_install_property(object_class,
+            PROP_LOGGING,
+            g_param_spec_boolean("logging",
+                "logging",
+                "are we currently logging",
+                FALSE,
+                G_PARAM_READABLE));
+
+    g_object_class_install_property(object_class,
+            PROP_CONNECT_HOOK,
+            g_param_spec_boolean("connect-hook",
+                "connect hook",
+                "do we need to send the connection string",
+                FALSE,
+                G_PARAM_READABLE));
+    
+    g_object_class_install_property(object_class,
+            PROP_CONNECTED,
+            g_param_spec_boolean("connected",
+                "connected",
+                "are we connected to the mud",
+                FALSE,
+                G_PARAM_READABLE));
+
+    g_object_class_install_property(object_class,
+            PROP_LOG,
+            g_param_spec_object("log",
+                "log",
+                "the mud log object",
+                MUD_TYPE_LOG,
+                G_PARAM_READABLE));
+
+    g_object_class_install_property(object_class,
+            PROP_PROFILE,
+            g_param_spec_object("profile",
+                "profile",
+                "the mud profile object",
+                MUD_TYPE_PROFILE,
+                G_PARAM_READABLE));
+
+    g_object_class_install_property(object_class,
+            PROP_TELNET,
+            g_param_spec_object("telnet",
+                "telnet",
+                "the mud telnet object",
+                MUD_TYPE_TELNET,
+                G_PARAM_READABLE));
+
+    g_object_class_install_property(object_class,
+            PROP_PARSE_BASE,
+            g_param_spec_object("parse-base",
+                "parse base",
+                "the parse base object",
+                MUD_TYPE_PARSE_BASE,
+                G_PARAM_READABLE));
+
+    g_object_class_install_property(object_class,
+            PROP_TERMINAL,
+            g_param_spec_object("terminal",
+                "terminal",
+                "the terminal widget",
+                VTE_TYPE_TERMINAL,
+                G_PARAM_READABLE));
+
+    g_object_class_install_property(object_class,
+            PROP_VBOX,
+            g_param_spec_object("ui-vbox",
+                "ui vbox",
+                "main ui vbox",
+                GTK_TYPE_VBOX,
+                G_PARAM_READABLE));
 }
 
 static void
-choose_profile_callback(GtkWidget *menu_item, MudConnectionView *view)
+mud_connection_view_init (MudConnectionView *self)
 {
-    MudProfile *profile;
-
-    if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_item)))
-        return;
-
-    profile = g_object_get_data(G_OBJECT(menu_item), "profile");
+    /* Get our private data */
+    self->priv = MUD_CONNECTION_VIEW_GET_PRIVATE(self);
 
-    g_assert(profile);
-
-    mud_connection_view_set_profile(view, profile);
-    mud_connection_view_reread_profile(view);
-}
-
-static void
-mud_connection_view_close_current_cb(GtkWidget *menu_item, MudConnectionView *view)
-{
-    mud_window_close_current_window(view->priv->window);
-}
+    /* Set some defaults */
+    self->priv->history = g_queue_new();
+    self->priv->current_history_index = 0;
 
+    self->priv->processed = NULL;
 
-static void
-mud_connection_view_str_replace (gchar *buf, const gchar *s, const gchar *repl)
-{
-    gchar out_buf[4608];
-    gchar *pc, *out;
-    gint  len = strlen (s);
-    gboolean found = FALSE;
+    self->connection = NULL;
 
-    for ( pc = buf, out = out_buf; *pc && (out-out_buf) < (4608-len-4);)
-        if ( !strncasecmp(pc, s, len))
-        {
-            out += sprintf (out, "%s", repl);
-            pc += len;
-            found = TRUE;
-        }
-        else
-            *out++ = *pc++;
+    self->naws_enabled = FALSE;
+    self->local_echo = TRUE;
+    self->remote_encode = FALSE;   
+    self->connect_hook = FALSE;
+    self->connected = FALSE;;
 
-    if ( found)
-    {
-        *out = '\0';
-        strcpy (buf, out_buf);
-    }
-}
+    self->connect_string = NULL;
+    self->remote_encoding = NULL;
 
-static void
-mud_connection_view_feed_text(MudConnectionView *view, gchar *message)
-{
-    gint rlen = strlen(message);
-    gchar buf[rlen*2];
+    self->port = 23;
+    self->mud_name = NULL;
+    self->hostname = NULL;
 
-    g_stpcpy(buf, message);
-    mud_connection_view_str_replace(buf, "\r", "");
-    mud_connection_view_str_replace(buf, "\n", "\n\r");
+    self->log = NULL;
+    self->tray = NULL;
+    self->profile = NULL;
+    self->parse = NULL;
+    self->window = NULL;
+    self->telnet = NULL;
 
-    vte_terminal_feed(VTE_TERMINAL(view->priv->terminal), buf, strlen(buf));
+    self->terminal = NULL;
+    self->ui_vbox = NULL;
 }
 
-void
-mud_connection_view_add_text(MudConnectionView *view, gchar *message, enum MudConnectionColorType type)
+static GObject *
+mud_connection_view_constructor (GType gtype,
+                                 guint n_properties,
+                                 GObjectConstructParam *properties)
 {
-    gchar *encoding, *text;
-    const gchar *local_codeset;
-    gchar *profile_name;
+    GtkWidget *box;
+    GtkWidget *dl_vbox;
+    GtkWidget *dl_hbox;
+    GtkWidget *term_box;
+    GtkWidget *main_window;
+    MudTray *tray;
     GConfClient *client;
-    gboolean remote;
-    gsize bytes_read, bytes_written;
-    GError *error = NULL;
 
     gchar key[2048];
     gchar extra_path[512] = "";
+    gchar *buf;
+    gchar *proxy_host;
+    gchar *version;
+    gint xpad, ypad;
+    gint char_width, char_height;
+    gboolean use_proxy;
+    GdkGeometry hints;
+    
+    MudConnectionView *self;
+    GObject *obj;
 
-    client = gconf_client_get_default();
+    MudConnectionViewClass *klass;
+    GObjectClass *parent_class;
 
-    text = g_strdup(message);
+    /* Chain up to parent constructor */
+    klass = MUD_CONNECTION_VIEW_CLASS( g_type_class_peek(MUD_TYPE_CONNECTION_VIEW) );
+    parent_class = G_OBJECT_CLASS( g_type_class_peek_parent(klass) );
+    obj = parent_class->constructor(gtype, n_properties, properties);
 
-    g_snprintf(key, 2048, "/apps/gnome-mud/%s%s", extra_path, "functionality/remote_encoding");
-    remote = gconf_client_get_bool(client, key, NULL);
+    /* Construct the View */
+    self = MUD_CONNECTION_VIEW(obj);
 
-    if(view->remote_encode && remote)
-        encoding = view->remote_encoding;
-    else
+    /* Check for construction properties */
+    if(!self->mud_name)
     {
-        profile_name = mud_profile_get_name(view->priv->profile);
-
-        if (strcmp(profile_name, "Default"))
-        {
-            g_snprintf(extra_path, 512, "profiles/%s/", profile_name);
-        }
-
-        g_snprintf(key, 2048, "/apps/gnome-mud/%s%s", extra_path, "functionality/encoding");
-        encoding = gconf_client_get_string(client, key, NULL);
+        g_printf("ERROR: Tried to instantiate MudConnectionView without passing mud-name.\n");
+        g_error("Tried to instantiate MudConnectionView without passing mud-name.");
     }
-
-    g_get_charset(&local_codeset);
-
-    text = g_convert(message, -1,
-            encoding,
-            local_codeset, 
-            &bytes_read, &bytes_written, &error);
-
-    if(error)
+    
+    if(!self->hostname)
     {
-        text = NULL;
+        g_printf("ERROR: Tried to instantiate MudConnectionView without passing hostname.\n");
+        g_error("Tried to instantiate MudConnectionView without passing hostname.");
     }
 
-    vte_terminal_set_encoding(VTE_TERMINAL(view->priv->terminal), encoding);
-
-    g_free(encoding);
-
-    switch (type)
+    if(!self->window)
     {
-        case Sent:
-            mud_connection_view_feed_text(view, "\e[1;33m");
-            break;
-
-        case Error:
-            mud_connection_view_feed_text(view, "\e[1;31m");
-            break;
-
-        case System:
-            mud_connection_view_feed_text(view, "\e[1;32m");
-            break;
-
-        case Normal:
-        default:
-            break;
+        g_printf("ERROR: Tried to instantiate MudConnectionView without passing parent MudWindow.\n");
+        g_error("Tried to instantiate MudConnectionView without passing parent MudWindow.");
     }
 
-    if(view->local_echo)
-        mud_connection_view_feed_text(view, (!error) ? text : message);
-
-    mud_connection_view_feed_text(view, "\e[0m");
-
-    if(text != NULL)
-        g_free(text);
-
-    g_object_unref(client);
-}
-
-
-static void
-mud_connection_view_init (MudConnectionView *connection_view)
-{
-    GtkWidget *box;
-    GtkWidget *dl_vbox;
-    GtkWidget *dl_hbox;
-    GtkWidget *term_box;
-
-    connection_view->priv = g_new0(MudConnectionViewPrivate, 1);
-
-    connection_view->priv->history = g_queue_new();
-    connection_view->priv->current_history_index = 0;
+    /* Create main VBox, VTE, and scrollbar */
+    box = gtk_vbox_new(FALSE, 0);
+    self->ui_vbox = GTK_VBOX(box);
+    self->terminal = VTE_TERMINAL(vte_terminal_new());
+    self->priv->scrollbar = gtk_vscrollbar_new(NULL);
 
 #ifdef ENABLE_GST
-    connection_view->priv->download_queue = g_queue_new();
-    connection_view->priv->dl_conn = NULL;
-#endif
-
-    connection_view->priv->processed = NULL;
-
-    connection_view->priv->parse = mud_parse_base_new(connection_view);
-
-    connection_view->priv->connect_hook = FALSE;
-
-    box = gtk_vbox_new(FALSE, 0);
+    /* Setup Download UI */
     dl_vbox = gtk_vbox_new(FALSE, 0);
     dl_hbox = gtk_hbox_new(FALSE, 0);
     term_box = gtk_hbox_new(FALSE, 0);
 
-    connection_view->priv->dl_label = gtk_label_new("Downloading...");
-    connection_view->priv->progressbar = gtk_progress_bar_new();
-    gtk_progress_bar_set_pulse_step (GTK_PROGRESS_BAR(connection_view->priv->progressbar), 0.1);
-    connection_view->priv->dl_button = gtk_button_new_from_stock("gtk-cancel");
-
-#ifdef ENABLE_GST
-    connection_view->priv->downloading = FALSE;
-#endif
-
-    gtk_box_pack_start(GTK_BOX(dl_vbox), connection_view->priv->dl_label, FALSE, FALSE, 0);
+    self->priv->dl_label = gtk_label_new("Downloading...");
+    self->priv->progressbar = gtk_progress_bar_new();
+    gtk_progress_bar_set_pulse_step (GTK_PROGRESS_BAR(self->priv->progressbar), 0.1);
+    self->priv->dl_button = gtk_button_new_from_stock("gtk-cancel");
+
+    /* Pack the Download UI */
+    gtk_box_pack_start(GTK_BOX(dl_vbox), self->priv->dl_label, FALSE, FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(dl_hbox), self->priv->progressbar, TRUE, TRUE, 0);
+    gtk_box_pack_end(GTK_BOX(dl_hbox), self->priv->dl_button, FALSE, FALSE, 0);
+    gtk_box_pack_end(GTK_BOX(dl_vbox), dl_hbox, TRUE, TRUE, 0);
 
-    gtk_box_pack_start(GTK_BOX(dl_hbox), connection_view->priv->progressbar, TRUE, TRUE, 0);
+    /* Pack into Main UI */
+    gtk_box_pack_start(GTK_BOX(box), dl_vbox, FALSE, FALSE, 0);
 
-    gtk_box_pack_end(GTK_BOX(dl_hbox), connection_view->priv->dl_button, FALSE, FALSE, 0);
+    /* Set defaults and create download queue */
+    self->priv->downloading = FALSE;
+    self->priv->download_queue = g_queue_new();
+    self->priv->dl_conn = NULL;
+
+    /* Connect Download Cancel Signal */
+    g_signal_connect(self->priv->dl_button,
+                     "clicked",
+                     G_CALLBACK(mud_connection_view_cancel_dl_cb),
+                     self);
+#endif
 
-    gtk_box_pack_end(GTK_BOX(dl_vbox), dl_hbox, TRUE, TRUE, 0);
+    /* Pack the Terminal UI */
+    gtk_box_pack_start(GTK_BOX(term_box),
+                       GTK_WIDGET(self->terminal),
+                       TRUE,
+                       TRUE,
+                       0);
+
+    gtk_box_pack_end(GTK_BOX(term_box),
+                     self->priv->scrollbar, 
+                     FALSE,
+                     FALSE,
+                     0);
 
-    connection_view->priv->terminal = vte_terminal_new();
-    vte_terminal_set_encoding(VTE_TERMINAL(connection_view->priv->terminal), "ISO-8859-1");
-    vte_terminal_set_emulation(VTE_TERMINAL(connection_view->priv->terminal), "xterm");
+    /* Pack into Main UI */
+    gtk_box_pack_end(GTK_BOX(box), term_box, TRUE, TRUE, 0);
 
-    gtk_box_pack_start(GTK_BOX(term_box), connection_view->priv->terminal, TRUE, TRUE, 0);
-    g_signal_connect(G_OBJECT(connection_view->priv->terminal),
+    /* Connect signals and set data */
+    g_signal_connect(G_OBJECT(self->terminal),
                      "button_press_event",
                      G_CALLBACK(mud_connection_view_button_press_event),
-                     connection_view);
-    g_object_set_data(G_OBJECT(connection_view->priv->terminal),
-                      "connection-view", connection_view);
-
-#ifdef ENABLE_GST                                                       
-    g_signal_connect(connection_view->priv->dl_button, "clicked",
-    G_CALLBACK(mud_connection_view_cancel_dl_cb), connection_view);
-#endif
+                     self);
 
-    connection_view->priv->scrollbar = gtk_vscrollbar_new(NULL);
+    g_object_set_data(G_OBJECT(self->terminal),
+                      "connection-view",
+                      self);
+    g_object_set_data(G_OBJECT(box),
+                      "connection-view",
+                      self);
+
+    /* Setup scrollbar */
     gtk_range_set_adjustment(
-            GTK_RANGE(connection_view->priv->scrollbar),
-            VTE_TERMINAL(connection_view->priv->terminal)->adjustment);
-    gtk_box_pack_end(GTK_BOX(term_box), connection_view->priv->scrollbar, 
-            FALSE, FALSE, 0);
+            GTK_RANGE(self->priv->scrollbar),
+            self->terminal->adjustment);
 
-    gtk_box_pack_start(GTK_BOX(box), dl_vbox, FALSE, FALSE, 0);
-    gtk_box_pack_end(GTK_BOX(box), term_box, TRUE, TRUE, 0);
+    /* Setup VTE */
+    vte_terminal_set_encoding(self->terminal, "ISO-8859-1");
+    vte_terminal_set_emulation(self->terminal, "xterm");
+    vte_terminal_get_padding(self->terminal, &xpad, &ypad);
 
-    gtk_widget_show_all(box);
+    char_width = self->terminal->char_width;
+    char_height = self->terminal->char_height;
 
-    gtk_widget_hide(connection_view->priv->progressbar);
-    gtk_widget_hide(connection_view->priv->dl_label);
-    gtk_widget_hide(connection_view->priv->dl_button);
+    hints.base_width = xpad;
+    hints.base_height = ypad;
+    hints.width_inc = char_width;
+    hints.height_inc = char_height;
 
-    g_object_set_data(G_OBJECT(box), "connection-view", connection_view);
+    hints.min_width =  hints.base_width + hints.width_inc * 4;
+    hints.min_height = hints.base_height+ hints.height_inc * 2;
 
-    connection_view->priv->box = box;
-    connection_view->priv->connected = FALSE;
+    g_object_get(self->window,
+                 "window", &main_window,
+                 "tray", &tray,
+                 NULL);
 
-}
+    gtk_window_set_geometry_hints(GTK_WINDOW(main_window),
+            GTK_WIDGET(self->terminal),
+            &hints,
+            GDK_HINT_RESIZE_INC |
+            GDK_HINT_MIN_SIZE |
+            GDK_HINT_BASE_SIZE);
 
-static void
-mud_connection_view_reread_profile(MudConnectionView *view)
-{
-    mud_connection_view_set_terminal_colors(view);
-    mud_connection_view_set_terminal_scrollback(view);
-    mud_connection_view_set_terminal_scrolloutput(view);
-    mud_connection_view_set_terminal_font(view);
-}
+    self->connection = gnet_conn_new(self->hostname, self->port,
+            mud_connection_view_network_event_cb, self);
+    gnet_conn_ref(self->connection);
+    gnet_conn_set_watch_error(self->connection, TRUE);
+
+    self->telnet = g_object_new(MUD_TYPE_TELNET,
+                                "parent-view", self,
+                                NULL);
+
+    mud_connection_view_set_profile(self, mud_profile_new(self->profile_name));
+
+    self->tray = tray;
+
+    self->parse = g_object_new(MUD_TYPE_PARSE_BASE,
+                               "parent-view", self,
+                               NULL);
+
+    self->log = g_object_new(MUD_TYPE_LOG,
+                             "mud-name", self->mud_name,
+                              NULL);
 
-static void
-mud_connection_view_class_init (MudConnectionViewClass *klass)
-{
-    GObjectClass *object_class = G_OBJECT_CLASS(klass);
+    buf = g_strdup_printf(_("*** Making connection to %s, port %d.\n"),
+            self->hostname, self->port);
+    mud_connection_view_add_text(self, buf, System);
+    g_free(buf);
+    buf = NULL;
 
-    object_class->finalize = mud_connection_view_finalize;
+    if (strcmp(self->profile_name, "Default") != 0)
+    {
+        g_snprintf(extra_path, 512, "profiles/%s/", self->profile_name);
+    }
+
+    g_snprintf(key, 2048, "/apps/gnome-mud/%s%s", extra_path, "functionality/use_proxy");
+    client = gconf_client_get_default();
+    use_proxy = gconf_client_get_bool(client, key, NULL);
+
+    g_snprintf(key, 2048, "/apps/gnome-mud/%s%s", extra_path, "functionality/proxy_hostname");
+    proxy_host = gconf_client_get_string(client, key, NULL);
+
+    g_snprintf(key, 2048, "/apps/gnome-mud/%s%s", extra_path, "functionality/proxy_version");
+    version = gconf_client_get_string(client, key, NULL);
+
+    if(use_proxy)
+    {
+        if(proxy_host && version)
+        {
+            gnet_socks_set_enabled(TRUE);
+            gnet_socks_set_server(gnet_inetaddr_new(proxy_host,GNET_SOCKS_PORT));
+            gnet_socks_set_version((strcmp(version, "4") == 0) ? 4 : 5);
+        }
+    }
+    else
+        gnet_socks_set_enabled(FALSE);
+
+    if(proxy_host)
+        g_free(proxy_host);
+
+    if(version)
+        g_free(version);
+
+    g_object_unref(client);
+
+    /* Show everything */
+    gtk_widget_show_all(box);
+
+#ifdef ENABLE_GST
+    /* Hide UI until download starts */
+    gtk_widget_hide(self->priv->progressbar);
+    gtk_widget_hide(self->priv->dl_label);
+    gtk_widget_hide(self->priv->dl_button);
+#endif
+
+    gnet_conn_connect(self->connection);
+
+    return obj;
 }
 
 static void
@@ -488,326 +664,298 @@
     if(connection_view->connection)
         gnet_conn_unref(connection_view->connection);
 
-    if(connection_view->priv->hostname)
-        g_free(connection_view->priv->hostname);
+    if(connection_view->hostname)
+        g_free(connection_view->hostname);
 
-    if(connection_view->priv->connect_string)
-        g_free(connection_view->priv->connect_string);
+    if(connection_view->connect_string)
+        g_free(connection_view->connect_string);
     
-    if(connection_view->priv->mud_name)
-        g_free(connection_view->priv->mud_name);
+    if(connection_view->mud_name)
+        g_free(connection_view->mud_name);
     
     if(connection_view->priv->processed)
         g_string_free(connection_view->priv->processed, TRUE);
     
-    if(connection_view->priv->telnet)
-        g_object_unref(connection_view->priv->telnet);
+    if(connection_view->telnet)
+        g_object_unref(connection_view->telnet);
    
-    g_object_unref(connection_view->priv->log);
-    g_object_unref(connection_view->priv->parse);
-    g_object_unref(connection_view->priv->profile);
-
-    g_free(connection_view->priv);
+    g_object_unref(connection_view->log);
+    g_object_unref(connection_view->parse);
+    g_object_unref(connection_view->profile);
 
     parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
     parent_class->finalize(object);
 }
 
-void
-mud_connection_view_set_connect_string(MudConnectionView *view, gchar *connect_string)
-{
-    g_assert(view != NULL);
-    view->priv->connect_hook = TRUE;
-    view->priv->connect_string = g_strdup(connect_string);
-}
 
-void
-mud_connection_view_disconnect(MudConnectionView *view)
+static void
+mud_connection_view_set_property(GObject *object,
+                                 guint prop_id,
+                                 const GValue *value,
+                                 GParamSpec *pspec)
 {
-#ifdef ENABLE_GST
-    MudMSPDownloadItem *item;
-#endif
+    MudConnectionView *self;
+    gboolean new_boolean;
+    gint new_int;
+    gchar *new_string;
 
-    g_assert(view != NULL);
+    self = MUD_CONNECTION_VIEW(object);
 
-    if(view->connection && gnet_conn_is_connected(view->connection))
+    switch(prop_id)
     {
-#ifdef ENABLE_GST
-        if(view->priv->download_queue)
-            while((item = (MudMSPDownloadItem *)g_queue_pop_head(view->priv->download_queue)) != NULL)
-                mud_telnet_msp_download_item_free(item);
+        case PROP_REMOTE_ENCODE:
+            new_boolean = g_value_get_boolean(value);
 
-        if(view->priv->download_queue)
-            g_queue_free(view->priv->download_queue);
+            if(new_boolean != self->remote_encode)
+                self->remote_encode = new_boolean;
+            break;
 
-        view->priv->download_queue = NULL;
-#endif
+        case PROP_CONNECT_STRING:
+            new_string = g_value_dup_string(value);
 
-        view->priv->processed = NULL;
+            if(!self->connect_string)
+                self->connect_string = 
+                    (new_string) ? g_strdup(new_string) : NULL;
+            else if( strcmp(self->connect_string, new_string) != 0)
+            {
+                if(self->connect_string)
+                    g_free(self->connect_string);
+                self->connect_string = 
+                    (new_string) ? g_strdup(new_string) : NULL;
+            }
 
-        gnet_conn_disconnect(view->connection);
-        gnet_conn_unref(view->connection);
-        view->connection = NULL;
+            if(self->connect_string)
+                self->connect_hook = TRUE;
 
-        if(view->priv->telnet)
-        {
-            g_object_unref(view->priv->telnet);
-            view->priv->telnet = NULL;
-        }
+            g_free(new_string);
+            break;
 
-        mud_connection_view_add_text(view, _("\n*** Connection closed.\n"), System);
-    }
-}
+        case PROP_REMOTE_ENCODING:
+            new_string = g_value_dup_string(value);
 
-void
-mud_connection_view_reconnect(MudConnectionView *view)
-{
-    gchar *buf, *profile_name, *proxy_host, *version;
-    gchar key[2048];
-    gchar extra_path[512] = "";
-    gboolean use_proxy;
-    GConfClient *client;
+            if(!self->remote_encoding)
+                self->remote_encoding = 
+                    (new_string) ? g_strdup(new_string) : NULL;
+            else if( strcmp(self->remote_encoding, new_string) != 0)
+            {
+                if(self->remote_encoding)
+                    g_free(self->remote_encoding);
+                self->remote_encoding = 
+                    (new_string) ? g_strdup(new_string) : NULL;
+            }
 
-#ifdef ENABLE_GST
-    MudMSPDownloadItem *item;
-#endif
+            g_free(new_string);
+            break;
 
-    g_assert(view != NULL);
+        case PROP_PORT:
+            new_int = g_value_get_int(value);
 
-    if(view->connection && gnet_conn_is_connected(view->connection))
-    {
+            if(new_int != self->port)
+                self->port = new_int;
+            break;
 
-#ifdef ENABLE_GST
-        while((item = (MudMSPDownloadItem *)
-                    g_queue_pop_head(view->priv->download_queue)) != NULL)
-            mud_telnet_msp_download_item_free(item);
+        case PROP_NAWS_ENABLED:
+            new_boolean = g_value_get_boolean(value);
 
-        if(view->priv->download_queue)
-            g_queue_free(view->priv->download_queue);
+            if(new_boolean != self->naws_enabled)
+                self->naws_enabled = new_boolean;
+            break;
 
-        view->priv->download_queue = NULL;
-#endif
+        case PROP_LOCAL_ECHO:
+            new_boolean = g_value_get_boolean(value);
 
-        view->priv->processed = NULL;
+            if(new_boolean != self->local_echo)
+                self->local_echo = new_boolean;
+            break;
 
-        gnet_conn_disconnect(view->connection);
-        gnet_conn_unref(view->connection);
-        view->connection = NULL;
+        case PROP_MUD_NAME:
+            new_string = g_value_dup_string(value);
 
-        g_object_unref(view->priv->telnet);
-        view->priv->telnet = NULL;
+            if(!self->mud_name)
+                self->mud_name = 
+                    (new_string) ? g_strdup(new_string) : NULL;
+            else if( strcmp(self->mud_name, new_string) != 0)
+            {
+                if(self->mud_name)
+                    g_free(self->mud_name);
+                self->mud_name = 
+                    (new_string) ? g_strdup(new_string) : NULL;
+            }
 
-        mud_connection_view_add_text(view,
-                _("\n*** Connection closed.\n"), System);
-    }
+            g_free(new_string);
+            break;
 
-    view->connection = gnet_conn_new(view->priv->hostname, view->priv->port,
-            mud_connection_view_network_event_cb, view);
-    gnet_conn_ref(view->connection);
-    gnet_conn_set_watch_error(view->connection, TRUE);
+        case PROP_HOSTNAME:
+            new_string = g_value_dup_string(value);
 
-    profile_name = mud_profile_get_name(view->priv->profile);
+            if(!self->hostname)
+                self->hostname = 
+                    (new_string) ? g_strdup(new_string) : NULL;
+            else if( strcmp(self->hostname, new_string) != 0)
+            {
+                if(self->hostname)
+                    g_free(self->hostname);
+                self->hostname = 
+                    (new_string) ? g_strdup(new_string) : NULL;
+            }
 
-    if (strcmp(profile_name, "Default") != 0)
-    {
-        g_snprintf(extra_path, 512, "profiles/%s/", profile_name);
-    }
+            g_free(new_string);
+            break;
 
-    g_snprintf(key, 2048, "/apps/gnome-mud/%s%s", extra_path, "functionality/use_proxy");
-    client = gconf_client_get_default();
-    use_proxy = gconf_client_get_bool(client, key, NULL);
+        case PROP_WINDOW:
+            self->window = MUD_WINDOW(g_value_get_object(value));
+            break;
 
-    g_snprintf(key, 2048, "/apps/gnome-mud/%s%s", extra_path, "functionality/proxy_hostname");
-    proxy_host = gconf_client_get_string(client, key, NULL);
+        case PROP_TRAY:
+            self->tray = MUD_TRAY(g_value_get_object(value));
+            break;
 
-    g_snprintf(key, 2048, "/apps/gnome-mud/%s%s", extra_path, "functionality/proxy_version");
-    version = gconf_client_get_string(client, key, NULL);
+        case PROP_PROFILE_NAME:
+            new_string = g_value_dup_string(value);
 
-    if(use_proxy)
-    {
-        if(proxy_host && version)
-        {
-            gnet_socks_set_enabled(TRUE);
-            gnet_socks_set_server(gnet_inetaddr_new(proxy_host,GNET_SOCKS_PORT));
-            gnet_socks_set_version((strcmp(version, "4") == 0) ? 4 : 5);
-        }
-    }
-    else
-        gnet_socks_set_enabled(FALSE);
+            if(!self->profile_name)
+                self->profile_name = 
+                    (new_string) ? g_strdup(new_string) : NULL;
+            else if( strcmp(self->profile_name, new_string) != 0)
+            {
+                if(self->profile_name)
+                    g_free(self->profile_name);
+                self->profile_name = 
+                    (new_string) ? g_strdup(new_string) : NULL;
+            }
 
-    if(proxy_host)
-        g_free(proxy_host);
+            g_free(new_string);
+            break;
 
-    if(version)
-        g_free(version);
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
 
-#ifdef ENABLE_GST
-    view->priv->download_queue = g_queue_new();
-#endif
+static void
+mud_connection_view_get_property(GObject *object,
+                                 guint prop_id,
+                                 GValue *value,
+                                 GParamSpec *pspec)
+{
+    MudConnectionView *self;
 
-    view->naws_enabled = FALSE;
-    view->local_echo = TRUE;
+    self = MUD_CONNECTION_VIEW(object);
 
-    view->priv->telnet = mud_telnet_new(view,
-            view->connection, view->priv->mud_name);
+    switch(prop_id)
+    {
+        case PROP_CONNECTION:
+            g_value_set_pointer(value, self->connection);
+            break;
 
-    buf = g_strdup_printf(_("*** Making connection to %s, port %d.\n"),
-            view->priv->hostname, view->priv->port);
-    mud_connection_view_add_text(view, buf, System);
-    g_free(buf);
+        case PROP_NAWS_ENABLED:
+            g_value_set_boolean(value, self->naws_enabled);
+            break;
 
-    g_object_unref(client);
+        case PROP_LOCAL_ECHO:
+            g_value_set_boolean(value, self->local_echo);
+            break;
 
-    gnet_conn_connect(view->connection);
-}
+        case PROP_REMOTE_ENCODE:
+            g_value_set_boolean(value, self->remote_encode);
+            break;
 
-void
-mud_connection_view_send(MudConnectionView *view, const gchar *data)
-{
-    GList *commands, *command;
-    gchar *text, *encoding, *conv_text;
-    const gchar *local_codeset;
-    gchar *profile_name;
-    GConfClient *client;
-    gboolean remote;
-    gsize bytes_read, bytes_written;
-    GError *error = NULL;
+        case PROP_CONNECT_HOOK:
+            g_value_set_boolean(value, self->connect_hook);
+            break;
 
-    gchar key[2048];
-    gchar extra_path[512] = "";
+        case PROP_CONNECTED:
+            g_value_set_boolean(value, self->connected);
+            break;
 
-    if(view->connection && gnet_conn_is_connected(view->connection))
-    {
-        if(view->local_echo) // Prevent password from being cached.
-        {
-            gchar *head = g_queue_peek_head(view->priv->history);
+        case PROP_CONNECT_STRING:
+            g_value_set_string(value, self->connect_string);
+            break;
 
-            if( (head && strcmp(head, data) != 0 && head[0] != '\n') 
-                    || g_queue_is_empty(view->priv->history))
-                g_queue_push_head(view->priv->history,
-                        (gpointer)g_strdup(data));
-        }
-        else
-            g_queue_push_head(view->priv->history,
-                    (gpointer)g_strdup(_("<password removed>")));
+        case PROP_REMOTE_ENCODING:
+            g_value_set_string(value, self->remote_encoding);
+            break;
 
-        client = gconf_client_get_default();
+        case PROP_PORT:
+            g_value_set_int(value, self->port);
+            break;
 
-        g_snprintf(key, 2048, "/apps/gnome-mud/%s%s", extra_path, "functionality/remote_encoding");
-        remote = gconf_client_get_bool(client, key, NULL);
+        case PROP_MUD_NAME:
+            g_value_set_string(value, self->mud_name);
+            break;
 
-        if(view->remote_encode && remote)
-            encoding = view->remote_encoding;
-        else
-        {
-            profile_name = mud_profile_get_name(view->priv->profile);
+        case PROP_HOSTNAME:
+            g_value_set_string(value, self->hostname);
+            break;
 
-            if (strcmp(profile_name, "Default"))
-            {
-                g_snprintf(extra_path, 512, "profiles/%s/", profile_name);
-            }
+        case PROP_LOG:
+            g_value_take_object(value, self->log);
+            break;
 
-            g_snprintf(key, 2048, "/apps/gnome-mud/%s%s", extra_path, "functionality/encoding");
-            encoding = gconf_client_get_string(client, key, NULL);
-        }
+        case PROP_TRAY:
+            g_value_take_object(value, self->tray);
+            break;
 
-        g_get_charset(&local_codeset);
+        case PROP_PROFILE:
+            g_value_take_object(value, self->profile);
+            break;
 
-        view->priv->current_history_index = 0;
-        commands = mud_profile_process_commands(view->priv->profile, data);
+        case PROP_PARSE_BASE:
+            g_value_take_object(value, self->parse);
+            break;
 
-        for (command = g_list_first(commands); command != NULL; command = command->next)
-        {
-            text = g_strdup_printf("%s\r\n", (gchar *) command->data);
+        case PROP_WINDOW:
+            g_value_take_object(value, self->window);
+            break;
 
-            conv_text = g_convert(text, -1,
-                encoding,
-                local_codeset, 
-                &bytes_read, &bytes_written, &error);
+        case PROP_TELNET:
+            g_value_take_object(value, self->telnet);
+            break;
 
-            if(error)
-            {
-                conv_text = NULL;
-                error = NULL;
-            }
+        case PROP_LOGGING:
+            g_value_set_boolean(value, self->logging);
+            break;
 
-            if(conv_text == NULL)
-                gnet_conn_write(view->connection, text, strlen(text));
-            else
-                gnet_conn_write(view->connection, conv_text, strlen(conv_text));
+        case PROP_PROFILE_NAME:
+            g_value_set_string(value, self->profile_name);
+            break;
 
-            if (view->priv->profile->preferences->EchoText && view->local_echo)
-                mud_connection_view_add_text(view, text, Sent);
+        case PROP_TERMINAL:
+            g_value_take_object(value, self->terminal);
+            break;
 
-            if(conv_text != NULL)
-                g_free(conv_text);
-            g_free(text);
-        }
+        case PROP_VBOX:
+            g_value_take_object(value, self->ui_vbox);
+            break;
 
-        g_list_free(commands);
-        g_object_unref(client);
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
     }
 }
 
+/* Callbacks */
 static void
-mud_connection_view_set_terminal_colors(MudConnectionView *view)
-{
-    vte_terminal_set_colors(VTE_TERMINAL(view->priv->terminal),
-            &view->priv->profile->preferences->Foreground,
-            &view->priv->profile->preferences->Background,
-            view->priv->profile->preferences->Colors, C_MAX);
-}
-
-void
-mud_connection_view_start_logging(MudConnectionView *view)
+choose_profile_callback(GtkWidget *menu_item, MudConnectionView *view)
 {
-    mud_log_open(view->priv->log);
-}
+    MudProfile *profile;
 
-void
-mud_connection_view_stop_logging(MudConnectionView *view)
-{
-    mud_log_close(view->priv->log);
-}
+    if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_item)))
+        return;
 
-gboolean
-mud_connection_view_islogging(MudConnectionView *view)
-{
-    return (view && view->connection && 
-            gnet_conn_is_connected(view->connection) &&
-                mud_log_islogging(view->priv->log));
-}
+    profile = g_object_get_data(G_OBJECT(menu_item), "profile");
 
-static void
-mud_connection_view_set_terminal_scrollback(MudConnectionView *view)
-{
-    vte_terminal_set_scrollback_lines(VTE_TERMINAL(view->priv->terminal),
-            view->priv->profile->preferences->Scrollback);
-}
+    g_assert(profile);
 
-static void
-mud_connection_view_set_terminal_scrolloutput(MudConnectionView *view)
-{
-    if(view->priv->terminal)
-        vte_terminal_set_scroll_on_output(VTE_TERMINAL(view->priv->terminal),
-                view->priv->profile->preferences->ScrollOnOutput);
+    mud_connection_view_set_profile(view, profile);
+    mud_connection_view_reread_profile(view);
 }
 
 static void
-mud_connection_view_set_terminal_font(MudConnectionView *view)
+mud_connection_view_close_current_cb(GtkWidget *menu_item, MudConnectionView *view)
 {
-    PangoFontDescription *desc = NULL;
-    char *name;
-
-    name = view->priv->profile->preferences->FontName;
-
-    if(name)
-        desc = pango_font_description_from_string(name);
-
-    if(!desc)
-        desc = pango_font_description_from_string("Monospace 10");
-
-    vte_terminal_set_font(VTE_TERMINAL(view->priv->terminal), desc);
+    mud_window_close_current_window(view->window);
 }
 
 static void
@@ -853,7 +1001,7 @@
 
     view->priv->popup_menu = gtk_menu_new();
     gtk_menu_attach_to_widget(GTK_MENU(view->priv->popup_menu),
-            view->priv->terminal,
+            GTK_WIDGET(view->terminal),
             popup_menu_detach);
 
     append_menuitem(view->priv->popup_menu,
@@ -898,7 +1046,7 @@
         group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menu_item));
         gtk_menu_shell_append(GTK_MENU_SHELL(profile_menu), menu_item);
 
-        if (prof == view->priv->profile)
+        if (prof == view->profile)
             gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item), TRUE);
 
         g_signal_connect(G_OBJECT(menu_item),
@@ -918,7 +1066,7 @@
     im_menu = gtk_menu_new();
     menu_item = gtk_menu_item_new_with_mnemonic(_("_Input Methods"));
     gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), im_menu);
-    vte_terminal_im_append_menuitems(VTE_TERMINAL(view->priv->terminal),
+    vte_terminal_im_append_menuitems(view->terminal,
             GTK_MENU_SHELL(im_menu));
     gtk_menu_shell_append(GTK_MENU_SHELL(view->priv->popup_menu), menu_item);
 
@@ -930,93 +1078,464 @@
             event ? event->time : gtk_get_current_event_time());
 }
 
-void
-mud_connection_view_set_id(MudConnectionView *view, gint id)
+static void
+mud_connection_view_network_event_cb(GConn *conn, GConnEvent *event, gpointer pview)
 {
-    view->priv->id = id;
+    gint gag;
+    gint pluggag;
+    gchar *buf;
+    gboolean temp;
+    MudConnectionView *view = MUD_CONNECTION_VIEW(pview);
+    gint length;
+
+#ifdef ENABLE_GST
+    MudMSPDownloadItem *item;
+    MudTelnetMsp *msp_handler;
+    gboolean msp_parser_enabled;
+#endif
+
+    g_assert(view != NULL);
+
+    switch(event->type)
+    {
+        case GNET_CONN_ERROR:
+            mud_connection_view_add_text(view, _("*** Could not connect.\n"), Error);
+            mud_window_disconnected(view->window);
+            break;
+
+        case GNET_CONN_CONNECT:
+            mud_connection_view_add_text(view, _("*** Connected.\n"), System);
+            gnet_conn_read(view->connection);
+            break;
+
+        case GNET_CONN_CLOSE:
+#ifdef ENABLE_GST
+            if(view->priv->download_queue)
+                while((item = (MudMSPDownloadItem *)g_queue_pop_head(view->priv->download_queue)) != NULL)
+                    mud_telnet_msp_download_item_free(item);
+
+            if(view->priv->download_queue)
+                g_queue_free(view->priv->download_queue);
+
+            view->priv->download_queue = NULL;
+#endif
+
+            view->priv->processed = NULL;
+
+            gnet_conn_disconnect(view->connection);
+            gnet_conn_unref(view->connection);
+            view->connection = NULL;
+
+            if(view->telnet)
+            {
+                g_object_unref(view->telnet);
+                view->telnet = NULL;
+            }
+
+            mud_connection_view_add_text(view, _("*** Connection closed.\n"), Error);
+
+            mud_window_disconnected(view->window);
+            break;
+
+        case GNET_CONN_TIMEOUT:
+            break;
+
+        case GNET_CONN_READ:
+            if(!view->connected)
+            {
+                view->connected = TRUE;
+                mud_tray_update_icon(view->tray, online);
+            }
+
+            view->priv->processed =
+                mud_telnet_process(view->telnet, (guchar *)event->buffer,
+                        event->length, &length);
+
+            if(view->priv->processed != NULL)
+            {
+#ifdef ENABLE_GST
+                msp_handler =
+                    MUD_TELNET_MSP(mud_telnet_get_handler(view->telnet,
+                                                          TELOPT_MSP));
+
+                g_object_get(msp_handler,
+                             "enabled", &msp_parser_enabled,
+                             NULL);
+
+                if(msp_parser_enabled)
+                {
+                    view->priv->processed =
+                        mud_telnet_msp_parse(msp_handler,
+                                             view->priv->processed,
+                                             &length);
+                }
+#endif
+                if(view->priv->processed != NULL)
+                {
+#ifdef ENABLE_GST
+                    if(msp_parser_enabled)
+                        mud_telnet_msp_parser_clear(msp_handler);
+#endif 
+                    buf = view->priv->processed->str;
+
+                    temp = view->local_echo;
+                    view->local_echo = FALSE;
+                    gag = mud_parse_base_do_triggers(view->parse,
+                            buf);
+                    view->local_echo = temp;
+
+                    if(!gag)
+                    {
+                        vte_terminal_feed(view->terminal,
+                                buf, length);
+                        mud_log_write_hook(view->log, buf, length);
+                    }
+
+                    if (view->connect_hook) {
+                        mud_connection_view_send (view, view->connect_string);
+                        view->connect_hook = FALSE;
+                    }
+
+                    if(view->priv->processed != NULL)
+                    {
+                        g_string_free(view->priv->processed, TRUE);
+                        view->priv->processed = NULL;
+                    }
+
+                    buf = NULL;
+                }
+            }
+
+            gnet_conn_read(view->connection);
+            break;
+
+        case GNET_CONN_WRITE:
+            break;
+
+        case GNET_CONN_READABLE:
+            break;
+
+        case GNET_CONN_WRITABLE:
+            break;
+    }
 }
 
-void
-mud_connection_view_set_parent(MudConnectionView *view, MudWindow *window)
+
+static void
+popup_menu_detach(GtkWidget *widget, GtkMenu *menu)
+{
+    MudConnectionView *view;
+
+    view = g_object_get_data(G_OBJECT(widget), "connection-view");
+    view->priv->popup_menu = NULL;
+}
+
+/* Private Methods */
+
+static GtkWidget*
+append_stock_menuitem(GtkWidget *menu, const gchar *text, GCallback callback, gpointer data)
+{
+    GtkWidget *menu_item;
+    GtkWidget *image;
+    GConfClient *client;
+    GError *error;
+    gboolean use_image;
+
+    menu_item = gtk_image_menu_item_new_from_stock(text, NULL);
+    image = gtk_image_menu_item_get_image(GTK_IMAGE_MENU_ITEM(menu_item));
+
+    client = gconf_client_get_default();
+    error = NULL;
+
+    use_image = gconf_client_get_bool(client,
+                                      "/desktop/gnome/interface/menus_have_icons",
+                                      &error);
+    if (error)
+    {
+        g_printerr(_("There was an error loading config value for whether to use image in menus. (%s)\n"),
+                   error->message);
+        g_error_free(error);
+    }
+    else
+    {
+        if (use_image)
+            gtk_widget_show(image);
+        else
+            gtk_widget_hide(image);
+    }
+
+    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+
+    if (callback)
+        g_signal_connect(G_OBJECT(menu_item),
+                         "activate",
+                         callback, data);
+
+    g_object_unref(client);
+
+    return menu_item;
+}
+
+static GtkWidget*
+append_menuitem(GtkWidget *menu, const gchar *text, GCallback callback, gpointer data)
 {
-    view->priv->window = window;
+    GtkWidget *menu_item;
+
+    menu_item = gtk_menu_item_new_with_mnemonic(text);
+    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+
+    if (callback)
+        g_signal_connect(G_OBJECT(menu_item), "activate", callback, data);
+
+    return menu_item;
 }
 
 
-MudConnectionView*
-mud_connection_view_new (const gchar *profile, const gchar *hostname,
-        const gint port, GtkWidget *window, GtkWidget *tray, gchar *name)
+static void
+mud_connection_view_feed_text(MudConnectionView *view, gchar *message)
 {
+    gint rlen = strlen(message);
+    gchar buf[rlen*2];
+
+    g_return_if_fail(IS_MUD_CONNECTION_VIEW(view));
+
+    g_stpcpy(buf, message);
+    utils_str_replace(buf, "\r", "");
+    utils_str_replace(buf, "\n", "\n\r");
+
+    vte_terminal_feed(view->terminal, buf, strlen(buf));
+}
+
+static void
+mud_connection_view_reread_profile(MudConnectionView *view)
+{
+    g_return_if_fail(IS_MUD_CONNECTION_VIEW(view));
+
+    mud_connection_view_set_terminal_colors(view);
+    mud_connection_view_set_terminal_scrollback(view);
+    mud_connection_view_set_terminal_scrolloutput(view);
+    mud_connection_view_set_terminal_font(view);
+}
+
+static void
+mud_connection_view_set_terminal_colors(MudConnectionView *view)
+{
+    g_return_if_fail(IS_MUD_CONNECTION_VIEW(view));
+
+    vte_terminal_set_colors(view->terminal,
+            &view->profile->preferences->Foreground,
+            &view->profile->preferences->Background,
+            view->profile->preferences->Colors, C_MAX);
+}
+
+static void
+mud_connection_view_set_terminal_scrollback(MudConnectionView *view)
+{
+    g_return_if_fail(IS_MUD_CONNECTION_VIEW(view));
+
+    vte_terminal_set_scrollback_lines(view->terminal,
+            view->profile->preferences->Scrollback);
+}
+
+static void
+mud_connection_view_set_terminal_scrolloutput(MudConnectionView *view)
+{
+    g_return_if_fail(IS_MUD_CONNECTION_VIEW(view));
+
+    if(view->terminal)
+        vte_terminal_set_scroll_on_output(view->terminal,
+                view->profile->preferences->ScrollOnOutput);
+}
+
+static void
+mud_connection_view_set_terminal_font(MudConnectionView *view)
+{
+    PangoFontDescription *desc = NULL;
+    char *name;
+
+    g_return_if_fail(IS_MUD_CONNECTION_VIEW(view));
+
+    name = view->profile->preferences->FontName;
+
+    if(name)
+        desc = pango_font_description_from_string(name);
+
+    if(!desc)
+        desc = pango_font_description_from_string("Monospace 10");
+
+    vte_terminal_set_font(view->terminal, desc);
+}
+
+/* Public Methods */
+void
+mud_connection_view_add_text(MudConnectionView *view, gchar *message, enum MudConnectionColorType type)
+{
+    gchar *encoding, *text;
+    const gchar *local_codeset;
     gchar *profile_name;
     GConfClient *client;
+    gboolean remote;
+    gsize bytes_read, bytes_written;
+    GError *error = NULL;
 
     gchar key[2048];
     gchar extra_path[512] = "";
-    gboolean use_proxy;
-    gchar *proxy_host;
-    gchar *version;
 
-    MudConnectionView *view;
-    GdkGeometry hints;
-    gint xpad, ypad;
-    gint char_width, char_height;
-    gchar *buf;
+    g_return_if_fail(IS_MUD_CONNECTION_VIEW(view));
 
-    g_assert(hostname != NULL);
-    g_assert(port > 0);
+    client = gconf_client_get_default();
 
-    view = g_object_new(TYPE_MUD_CONNECTION_VIEW, NULL);
+    text = g_strdup(message);
 
-    view->priv->hostname = g_strdup(hostname);
-    view->priv->port = port;
-    view->priv->mud_name = g_strdup(name);
+    g_snprintf(key, 2048, "/apps/gnome-mud/%s%s", extra_path, "functionality/remote_encoding");
+    remote = gconf_client_get_bool(client, key, NULL);
 
-    view->connection = gnet_conn_new(hostname, port,
-            mud_connection_view_network_event_cb, view);
-    gnet_conn_ref(view->connection);
-    gnet_conn_set_watch_error(view->connection, TRUE);
+    if(view->remote_encode && remote)
+        encoding = view->remote_encoding;
+    else
+    {
+        profile_name = mud_profile_get_name(view->profile);
 
-    view->naws_enabled = FALSE;
+        if (strcmp(profile_name, "Default"))
+        {
+            g_snprintf(extra_path, 512, "profiles/%s/", profile_name);
+        }
 
-    view->priv->telnet = mud_telnet_new(view, view->connection, name);
+        g_snprintf(key, 2048, "/apps/gnome-mud/%s%s", extra_path, "functionality/encoding");
+        encoding = gconf_client_get_string(client, key, NULL);
+    }
 
-    view->local_echo = TRUE;
+    g_get_charset(&local_codeset);
 
-    mud_connection_view_set_profile(view, mud_profile_new(profile));
+    text = g_convert(message, -1,
+            encoding,
+            local_codeset, 
+            &bytes_read, &bytes_written, &error);
 
-    /* Let us resize the gnome-mud window */
-    vte_terminal_get_padding(VTE_TERMINAL(view->priv->terminal), &xpad, &ypad);
-    char_width = VTE_TERMINAL(view->priv->terminal)->char_width;
-    char_height = VTE_TERMINAL(view->priv->terminal)->char_height;
+    if(error)
+    {
+        text = NULL;
+    }
 
-    hints.base_width = xpad;
-    hints.base_height = ypad;
-    hints.width_inc = char_width;
-    hints.height_inc = char_height;
+    vte_terminal_set_encoding(view->terminal, encoding);
 
-    hints.min_width =  hints.base_width + hints.width_inc * 4;
-    hints.min_height = hints.base_height+ hints.height_inc * 2;
+    g_free(encoding);
+
+    switch (type)
+    {
+        case Sent:
+            mud_connection_view_feed_text(view, "\e[1;33m");
+            break;
+
+        case Error:
+            mud_connection_view_feed_text(view, "\e[1;31m");
+            break;
+
+        case System:
+            mud_connection_view_feed_text(view, "\e[1;32m");
+            break;
+
+        case Normal:
+        default:
+            break;
+    }
+
+    if(view->local_echo)
+        mud_connection_view_feed_text(view, (!error) ? text : message);
+
+    mud_connection_view_feed_text(view, "\e[0m");
+
+    if(text != NULL)
+        g_free(text);
+
+    g_object_unref(client);
+}
+
+void
+mud_connection_view_disconnect(MudConnectionView *view)
+{
+#ifdef ENABLE_GST
+    MudMSPDownloadItem *item;
+#endif
+
+    g_return_if_fail(IS_MUD_CONNECTION_VIEW(view));
+
+    if(view->connection && gnet_conn_is_connected(view->connection))
+    {
+#ifdef ENABLE_GST
+        if(view->priv->download_queue)
+            while((item = (MudMSPDownloadItem *)g_queue_pop_head(view->priv->download_queue)) != NULL)
+                mud_telnet_msp_download_item_free(item);
+
+        if(view->priv->download_queue)
+            g_queue_free(view->priv->download_queue);
+
+        view->priv->download_queue = NULL;
+#endif
+
+        view->priv->processed = NULL;
+
+        gnet_conn_disconnect(view->connection);
+        gnet_conn_unref(view->connection);
+        view->connection = NULL;
+
+        if(view->telnet)
+        {
+            g_object_unref(view->telnet);
+            view->telnet = NULL;
+        }
+
+        mud_connection_view_add_text(view, _("\n*** Connection closed.\n"), System);
+    }
+}
+
+void
+mud_connection_view_reconnect(MudConnectionView *view)
+{
+    gchar *buf, *profile_name, *proxy_host, *version;
+    gchar key[2048];
+    gchar extra_path[512] = "";
+    gboolean use_proxy;
+    GConfClient *client;
+
+#ifdef ENABLE_GST
+    MudMSPDownloadItem *item;
+#endif
+    g_return_if_fail(IS_MUD_CONNECTION_VIEW(view));
+
+    if(view->connection && gnet_conn_is_connected(view->connection))
+    {
+
+#ifdef ENABLE_GST
+        while((item = (MudMSPDownloadItem *)
+                    g_queue_pop_head(view->priv->download_queue)) != NULL)
+            mud_telnet_msp_download_item_free(item);
+
+        if(view->priv->download_queue)
+            g_queue_free(view->priv->download_queue);
+
+        view->priv->download_queue = NULL;
+#endif
+
+        view->priv->processed = NULL;
 
-    gtk_window_set_geometry_hints(GTK_WINDOW(window),
-            GTK_WIDGET(view->priv->terminal),
-            &hints,
-            GDK_HINT_RESIZE_INC |
-            GDK_HINT_MIN_SIZE |
-            GDK_HINT_BASE_SIZE);
+        gnet_conn_disconnect(view->connection);
+        gnet_conn_unref(view->connection);
+        view->connection = NULL;
 
-    view->priv->tray = MUD_TRAY(tray);
+        g_object_unref(view->telnet);
+        view->telnet = NULL;
 
-    view->priv->log = g_object_new(MUD_TYPE_LOG,
-                                   "mud-name", name,
-                                   NULL);
+        mud_connection_view_add_text(view,
+                _("\n*** Connection closed.\n"), System);
+    }
 
-    buf = g_strdup_printf(_("*** Making connection to %s, port %d.\n"),
-            view->priv->hostname, view->priv->port);
-    mud_connection_view_add_text(view, buf, System);
-    g_free(buf);
-    buf = NULL;
+    view->connection = gnet_conn_new(view->hostname, view->port,
+            mud_connection_view_network_event_cb, view);
+    gnet_conn_ref(view->connection);
+    gnet_conn_set_watch_error(view->connection, TRUE);
 
-    profile_name = mud_profile_get_name(view->priv->profile);
+    profile_name = mud_profile_get_name(view->profile);
 
     if (strcmp(profile_name, "Default") != 0)
     {
@@ -1051,251 +1570,211 @@
     if(version)
         g_free(version);
 
-    g_object_unref(client);
-
-    gnet_conn_connect(view->connection);
-
-    return view;
-}
-
-void
-mud_connection_view_set_profile(MudConnectionView *view, MudProfile *profile)
-{
-    if (profile == view->priv->profile)
-        return;
-
-    if (view->priv->profile)
-    {
-        g_signal_handler_disconnect(view->priv->profile, view->priv->signal_profile_changed);
-        g_object_unref(G_OBJECT(view->priv->profile));
-    }
+#ifdef ENABLE_GST
+    view->priv->download_queue = g_queue_new();
+#endif
 
-    view->priv->profile = profile;
-    g_object_ref(G_OBJECT(profile));
-    view->priv->signal_profile_changed =
-        g_signal_connect(G_OBJECT(view->priv->profile), "changed",
-                         G_CALLBACK(mud_connection_view_profile_changed_cb),
-                         view);
-    mud_connection_view_reread_profile(view);
-}
+    view->naws_enabled = FALSE;
+    view->local_echo = TRUE;
 
-MudProfile *
-mud_connection_view_get_current_profile(MudConnectionView *view)
-{
-    return view->priv->profile;
-}
+    view->telnet = g_object_new(MUD_TYPE_TELNET,
+                                "parent-view", view,
+                                NULL);
 
-GtkWidget *
-mud_connection_view_get_viewport (MudConnectionView *view)
-{
-    return view->priv->box;
-}
+    buf = g_strdup_printf(_("*** Making connection to %s, port %d.\n"),
+            view->hostname, view->port);
+    mud_connection_view_add_text(view, buf, System);
+    g_free(buf);
 
-GtkWidget *
-mud_connection_view_get_terminal(MudConnectionView *view)
-{
-    return view->priv->terminal;
-}
+    g_object_unref(client);
 
-MudParseBase *
-mud_connection_view_get_parsebase(MudConnectionView *view)
-{
-    return view->priv->parse;
+    gnet_conn_connect(view->connection);
 }
 
-gchar *
-mud_connection_view_get_history_item(MudConnectionView *view, enum
-                                     MudConnectionHistoryDirection direction)
+void
+mud_connection_view_send(MudConnectionView *view, const gchar *data)
 {
-    gchar *history_item;
+    GList *commands, *command;
+    gchar *text, *encoding, *conv_text;
+    const gchar *local_codeset;
+    gchar *profile_name;
+    GConfClient *client;
+    gboolean remote;
+    gsize bytes_read, bytes_written;
+    GError *error = NULL;
 
-    if(direction == HISTORY_DOWN)
-        if(view->priv->current_history_index != 0)
-            view->priv->current_history_index--;
+    gchar key[2048];
+    gchar extra_path[512] = "";
 
-    history_item = (gchar *)g_queue_peek_nth(view->priv->history,
-            view->priv->current_history_index);
+    g_return_if_fail(IS_MUD_CONNECTION_VIEW(view));
 
-    if(direction == HISTORY_UP)
-        if(view->priv->current_history_index <
-                g_queue_get_length(view->priv->history) - 1)
-            view->priv->current_history_index++;
+    if(view->connection && gnet_conn_is_connected(view->connection))
+    {
+        if(view->local_echo) // Prevent password from being cached.
+        {
+            gchar *head = g_queue_peek_head(view->priv->history);
 
-    return history_item;
-}
+            if( (head && strcmp(head, data) != 0 && head[0] != '\n') 
+                    || g_queue_is_empty(view->priv->history))
+                g_queue_push_head(view->priv->history,
+                        (gpointer)g_strdup(data));
+        }
+        else
+            g_queue_push_head(view->priv->history,
+                    (gpointer)g_strdup(_("<password removed>")));
 
-static void
-mud_connection_view_network_event_cb(GConn *conn, GConnEvent *event, gpointer pview)
-{
-    gint gag;
-    gint pluggag;
-    gchar *buf;
-    gboolean temp;
-    MudConnectionView *view = MUD_CONNECTION_VIEW(pview);
-    gint length;
+        view->priv->current_history_index = -1;
 
-#ifdef ENABLE_GST
-    MudMSPDownloadItem *item;
-#endif
+        client = gconf_client_get_default();
 
-    g_assert(view != NULL);
+        g_snprintf(key, 2048, "/apps/gnome-mud/%s%s", extra_path, "functionality/remote_encoding");
+        remote = gconf_client_get_bool(client, key, NULL);
 
-    switch(event->type)
-    {
-        case GNET_CONN_ERROR:
-            mud_connection_view_add_text(view, _("*** Could not connect.\n"), Error);
-            mud_window_disconnected(view->priv->window);
-            break;
+        if(view->remote_encode && remote)
+            encoding = view->remote_encoding;
+        else
+        {
+            profile_name = mud_profile_get_name(view->profile);
 
-        case GNET_CONN_CONNECT:
-            mud_connection_view_add_text(view, _("*** Connected.\n"), System);
-            gnet_conn_read(view->connection);
-            break;
+            if (strcmp(profile_name, "Default"))
+            {
+                g_snprintf(extra_path, 512, "profiles/%s/", profile_name);
+            }
 
-        case GNET_CONN_CLOSE:
-#ifdef ENABLE_GST
-            if(view->priv->download_queue)
-                while((item = (MudMSPDownloadItem *)g_queue_pop_head(view->priv->download_queue)) != NULL)
-                    mud_telnet_msp_download_item_free(item);
+            g_snprintf(key, 2048, "/apps/gnome-mud/%s%s", extra_path, "functionality/encoding");
+            encoding = gconf_client_get_string(client, key, NULL);
+        }
 
-            if(view->priv->download_queue)
-                g_queue_free(view->priv->download_queue);
+        g_get_charset(&local_codeset);
 
-            view->priv->download_queue = NULL;
-#endif
+        commands = mud_profile_process_commands(view->profile, data);
 
-            view->priv->processed = NULL;
+        for (command = g_list_first(commands); command != NULL; command = command->next)
+        {
+            text = g_strdup_printf("%s\r\n", (gchar *) command->data);
 
-            gnet_conn_disconnect(view->connection);
-            gnet_conn_unref(view->connection);
-            view->connection = NULL;
+            conv_text = g_convert(text, -1,
+                encoding,
+                local_codeset, 
+                &bytes_read, &bytes_written, &error);
 
-            if(view->priv->telnet)
+            if(error)
             {
-                g_object_unref(view->priv->telnet);
-                view->priv->telnet = NULL;
+                conv_text = NULL;
+                error = NULL;
             }
 
-            mud_connection_view_add_text(view, _("*** Connection closed.\n"), Error);
+            if(conv_text == NULL)
+                gnet_conn_write(view->connection, text, strlen(text));
+            else
+                gnet_conn_write(view->connection, conv_text, strlen(conv_text));
 
-            mud_window_disconnected(view->priv->window);
-            break;
+            if (view->profile->preferences->EchoText && view->local_echo)
+                mud_connection_view_add_text(view, text, Sent);
 
-        case GNET_CONN_TIMEOUT:
-            break;
+            if(conv_text != NULL)
+                g_free(conv_text);
+            g_free(text);
+        }
 
-        case GNET_CONN_READ:
-            if(!view->priv->connected)
-            {
-                view->priv->connected = TRUE;
-                mud_tray_update_icon(view->priv->tray, online);
-            }
+        g_list_free(commands);
+        g_object_unref(client);
+    }
+}
 
-            view->priv->processed =
-                mud_telnet_process(view->priv->telnet, (guchar *)event->buffer,
-                        event->length, &length);
+void
+mud_connection_view_start_logging(MudConnectionView *view)
+{
+    g_return_if_fail(IS_MUD_CONNECTION_VIEW(view));
 
-            if(view->priv->processed != NULL)
-            {
-#ifdef ENABLE_GST
-                if(view->priv->telnet->msp_parser.enabled)
-                {
-                    view->priv->processed = mud_telnet_msp_parse(
-                            view->priv->telnet, view->priv->processed, &length);
-                }
-#endif
-                if(view->priv->processed != NULL)
-                {
-#ifdef ENABLE_GST
-                    mud_telnet_msp_parser_clear(view->priv->telnet);
-#endif 
-                    buf = view->priv->processed->str;
+    view->logging = TRUE;
+    mud_log_open(view->log);
+}
 
-                    temp = view->local_echo;
-                    view->local_echo = FALSE;
-                    gag = mud_parse_base_do_triggers(view->priv->parse,
-                            buf);
-                    view->local_echo = temp;
+void
+mud_connection_view_stop_logging(MudConnectionView *view)
+{
+    g_return_if_fail(IS_MUD_CONNECTION_VIEW(view));
 
-                    if(!gag)
-                    {
-                        vte_terminal_feed(VTE_TERMINAL(view->priv->terminal),
-                                buf, length);
-                        mud_log_write_hook(view->priv->log, buf, length);
-                    }
+    view->logging = FALSE;
+    mud_log_close(view->log);
+}
 
-                    if (view->priv->connect_hook) {
-                        mud_connection_view_send (view, view->priv->connect_string);
-                        view->priv->connect_hook = FALSE;
-                    }
+void
+mud_connection_view_set_profile(MudConnectionView *view, MudProfile *profile)
+{
+    g_return_if_fail(IS_MUD_CONNECTION_VIEW(view));
 
-                    if(view->priv->processed != NULL)
-                    {
-                        g_string_free(view->priv->processed, TRUE);
-                        view->priv->processed = NULL;
-                    }
+    if(profile == view->profile)
+        return;
 
-                    buf = NULL;
-                }
-            }
+    if (view->profile)
+    {
+        g_signal_handler_disconnect(view->profile, view->priv->signal_profile_changed);
+        g_object_unref(G_OBJECT(view->profile));
+    }
 
-            gnet_conn_read(view->connection);
-            break;
+    view->profile = profile;
+    g_object_ref(G_OBJECT(profile));
+    view->priv->signal_profile_changed =
+        g_signal_connect(G_OBJECT(view->profile), "changed",
+                         G_CALLBACK(mud_connection_view_profile_changed_cb),
+                         view);
+    mud_connection_view_reread_profile(view);
+}
 
-        case GNET_CONN_WRITE:
-            break;
+const gchar *
+mud_connection_view_get_history_item(MudConnectionView *view, enum
+                                     MudConnectionHistoryDirection direction)
+{
+    gchar *history_item;
 
-        case GNET_CONN_READABLE:
-            break;
+    if(direction == HISTORY_DOWN)
+        if( !(view->priv->current_history_index <= 0) )
+            view->priv->current_history_index--;
 
-        case GNET_CONN_WRITABLE:
-            break;
-    }
+    if(direction == HISTORY_UP)
+        if(view->priv->current_history_index < 
+                (gint)g_queue_get_length(view->priv->history) - 1)
+            view->priv->current_history_index++;
+
+    history_item = (gchar *)g_queue_peek_nth(view->priv->history,
+            view->priv->current_history_index);
+
+    return history_item;
 }
 
 void
 mud_connection_view_get_term_size(MudConnectionView *view, gint *w, gint *h)
 {
-    VteTerminal *term = VTE_TERMINAL(view->priv->terminal);
+    g_return_if_fail(IS_MUD_CONNECTION_VIEW(view));
+
+    VteTerminal *term = view->terminal;
     *w = term->column_count;
     *h = term->row_count;
 }
 
 void
-mud_connection_view_set_naws(MudConnectionView *view, gint enabled)
-{
-    view->naws_enabled = enabled;
-}
-
-void
 mud_connection_view_send_naws(MudConnectionView *view)
 {
-    guint curr_width = VTE_TERMINAL(view->priv->terminal)->column_count;
-    guint curr_height = VTE_TERMINAL(view->priv->terminal)->row_count;
-
-    mud_telnet_send_naws(view->priv->telnet, curr_width, curr_height);
-}
-
-static void
-mud_connection_view_resized_cb(MudWindow *window, MudConnectionView *view)
-{
-    g_message("resized cb called");
+    g_return_if_fail(IS_MUD_CONNECTION_VIEW(view));
 
-    g_printf("foo");
-}
+    guint curr_width = view->terminal->column_count;
+    guint curr_height = view->terminal->row_count;
 
-gboolean
-mud_connection_view_is_connected(MudConnectionView *view)
-{
-    return (view && view->connection && gnet_conn_is_connected(view->connection));
+    if(view->naws_enabled)
+        mud_telnet_send_naws(view->telnet, curr_width, curr_height);
 }
 
+/* MSP Download Code */
 #ifdef ENABLE_GST
 static void
 mud_connection_view_start_download(MudConnectionView *view)
 {
     MudMSPDownloadItem *item;
 
+    g_return_if_fail(IS_MUD_CONNECTION_VIEW(view));
+
     gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(view->priv->progressbar), 0.0);
     gtk_label_set_text(GTK_LABEL(view->priv->dl_label), _("Connecting..."));
     gtk_widget_show(view->priv->progressbar);
@@ -1329,6 +1808,8 @@
     gchar key[2048];
     gchar extra_path[512] = "";
 
+    g_return_if_fail(IS_MUD_CONNECTION_VIEW(view));
+
     client = gconf_client_get_default();
 
     g_snprintf(key, 2048, "/apps/gnome-mud/%s%s", extra_path, "functionality/remote_download");

Modified: trunk/src/mud-connection-view.h
==============================================================================
--- trunk/src/mud-connection-view.h	(original)
+++ trunk/src/mud-connection-view.h	Fri Mar 13 23:41:46 2009
@@ -3,48 +3,81 @@
 
 G_BEGIN_DECLS
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <gtk/gtk.h>
 #include <gnet.h>
+#include <vte/vte.h>
 
-
-#define TYPE_MUD_CONNECTION_VIEW               (mud_connection_view_get_type ())
-#define MUD_CONNECTION_VIEW(object)            (G_TYPE_CHECK_INSTANCE_CAST ((object), TYPE_MUD_CONNECTION_VIEW, MudConnectionView))
-#define MUD_CONNECTION_VIEW_TYPE_CLASS(klass)  (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_MUD_CONNECTION_VIEW, MudConnectionViewClass))
-#define IS_MUD_CONNECTION_VIEW(object)         (G_TYPE_CHECK_INSTANCE_TYPE ((object), TYPE_MUD_CONNECTION_VIEW))
-#define IS_MUD_CONNECTION_VIEW_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_MUD_CONNECTION_VIEW))
+#define MUD_TYPE_CONNECTION_VIEW               (mud_connection_view_get_type ())
+#define MUD_CONNECTION_VIEW(object)            (G_TYPE_CHECK_INSTANCE_CAST ((object), MUD_TYPE_CONNECTION_VIEW, MudConnectionView))
+#define MUD_CONNECTION_VIEW_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), MUD_TYPE_CONNECTION_VIEW, MudConnectionViewClass))
+#define IS_MUD_CONNECTION_VIEW(object)         (G_TYPE_CHECK_INSTANCE_TYPE ((object), MUD_TYPE_CONNECTION_VIEW))
+#define IS_MUD_CONNECTION_VIEW_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), MUD_TYPE_CONNECTION_VIEW))
 #define MUD_CONNECTION_VIEW_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), MUD_TYPE_CONNECTION, MudConnectionViewClass))
+#define MUD_CONNECTION_VIEW_GET_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUD_TYPE_CONNECTION_VIEW, MudConnectionViewPrivate))
 
 typedef struct _MudConnectionView           MudConnectionView;
 typedef struct _MudConnectionViewClass      MudConnectionViewClass;
 typedef struct _MudConnectionViewPrivate    MudConnectionViewPrivate;
 
-struct _MudConnectionView
-{
-	GObject parent_instance;
+#include "mud-telnet.h"
+#include "mud-parse-base.h"
+#include "mud-profile.h"
+#include "mud-window.h"
+#include "mud-log.h"
+#include "mud-tray.h"
 
-	MudConnectionViewPrivate *priv;
+struct _MudConnectionViewClass
+{
+    GObjectClass parent_class;
+};
 
-	GConn *connection;
+struct _MudConnectionView
+{
+    GObject parent_instance;
 
-	gint naws_enabled;
+    /*< Private >*/
+    MudConnectionViewPrivate *priv;
 
-	gint local_echo;
+    /*< Public >*/
+    GConn *connection;
 
-	gint remote_encode;
-	gchar *remote_encoding;
-};
+    // Flags
+    gboolean naws_enabled;
+    gboolean local_echo;
+    gboolean remote_encode;   
+    gboolean connect_hook;
+    gboolean connected;
+    gboolean logging;
+
+    gchar *connect_string;
+    gchar *remote_encoding;
+    gchar *profile_name;
+
+    gint port;
+    gchar *mud_name;
+    gchar *hostname;
+
+    MudLog *log;
+    MudTray *tray;
+    MudTelnet *telnet;
+    MudWindow *window;
+    MudProfile *profile;
+    MudParseBase *parse;
 
-struct _MudConnectionViewClass
-{
-	GObjectClass parent_class;
+    VteTerminal *terminal;
+    GtkVBox *ui_vbox;
 };
 
 enum MudConnectionColorType
 {
-	Error,
-	Normal,
-	Sent,
-	System
+    Error,
+    Normal,
+    Sent,
+    System
 };
 
 enum MudConnectionHistoryDirection
@@ -55,40 +88,27 @@
 
 GType mud_connection_view_get_type (void) G_GNUC_CONST;
 
-MudConnectionView* mud_connection_view_new (const gchar *profile, const gchar *hostname, const gint port, GtkWidget *window, GtkWidget *tray, gchar *name);
-GtkWidget* mud_connection_view_get_viewport (MudConnectionView *view);
-GtkWidget* mud_connection_view_get_terminal(MudConnectionView *view);
-void mud_connection_view_disconnect (MudConnectionView *view);
-void mud_connection_view_reconnect (MudConnectionView *view);
 void mud_connection_view_send (MudConnectionView *view, const gchar *data);
-void mud_connection_view_set_connect_string(MudConnectionView *view, gchar *connect_string);
-void mud_connection_view_set_id(MudConnectionView *view, gint id);
 void mud_connection_view_add_text(MudConnectionView *view, gchar *message, enum MudConnectionColorType type);
-gchar *mud_connection_view_get_history_item(MudConnectionView *view, enum
-MudConnectionHistoryDirection direction);
+
+void mud_connection_view_reconnect (MudConnectionView *view);
+void mud_connection_view_disconnect (MudConnectionView *view);
+
+const gchar *mud_connection_view_get_history_item(MudConnectionView *view, enum
+                                   MudConnectionHistoryDirection direction);
 void mud_connection_view_get_term_size(MudConnectionView *view, gint *w, gint *h);
-void mud_connection_view_set_naws(MudConnectionView *view, gint enabled);
 void mud_connection_view_send_naws(MudConnectionView *view);
 
 #ifdef ENABLE_GST
 void mud_connection_view_queue_download(MudConnectionView *view, gchar *url, gchar *file);
 #endif
 
-#include "mud-profile.h"
 void mud_connection_view_set_profile(MudConnectionView *view, MudProfile *profile);
-MudProfile *mud_connection_view_get_current_profile(MudConnectionView *view);
-
-#include "mud-window.h"
-void mud_connection_view_set_parent(MudConnectionView *view, MudWindow *window);
 
 void mud_connection_view_start_logging(MudConnectionView *view);
 void mud_connection_view_stop_logging(MudConnectionView *view);
-gboolean mud_connection_view_islogging(MudConnectionView *view);
-gboolean mud_connection_view_is_connected(MudConnectionView *view);
-
-#include "mud-parse-base.h"
-MudParseBase *mud_connection_view_get_parsebase(MudConnectionView *view);
 
 G_END_DECLS
 
 #endif /* MUD_CONNECTION_VIEW_H */
+

Modified: trunk/src/mud-connections.c
==============================================================================
--- trunk/src/mud-connections.c	(original)
+++ trunk/src/mud-connections.c	Fri Mar 13 23:41:46 2009
@@ -203,7 +203,7 @@
             g_param_spec_object("parent-window",
                 "parent mud window",
                 "the mud window the connections is attached to",
-                TYPE_MUD_WINDOW,
+                MUD_TYPE_WINDOW,
                 G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
 }
 
@@ -456,16 +456,19 @@
 
     mud_tray_update_icon(conn->priv->tray, offline);
 
-    view = mud_connection_view_new("Default", host, port,
-				   conn->priv->winwidget,
-				   (GtkWidget *)conn->priv->tray, mud_name);
+    view = g_object_new(MUD_TYPE_CONNECTION_VIEW,
+                        "hostname", host,
+                        "port", port,
+                        "profile-name", profile,
+                        "mud-name", mud_name,
+                        "connect-string", (logon && strlen(logon) != 0) ? logon : NULL,
+                        "window", conn->parent_window,
+                        NULL);
+
     mud_window_add_connection_view(conn->parent_window, G_OBJECT(view), mud_name);
     mud_connection_view_set_profile(view, get_profile(profile));
     mud_window_profile_menu_set_active(conn->parent_window, profile);
 
-    if(logon && strlen(logon) != 0)
-	mud_connection_view_set_connect_string(view, logon);
-
     g_free(mud_name);
     g_free(strip_name);
     g_object_unref(client);
@@ -489,10 +492,16 @@
 
     if(strlen(host) != 0)
     {
+
         mud_tray_update_icon(conn->priv->tray, offline);
-        view = mud_connection_view_new("Default", host, port,
-                                       conn->priv->winwidget,
-                                       (GtkWidget *)conn->priv->tray, (gchar *)host);
+        view = g_object_new(MUD_TYPE_CONNECTION_VIEW,
+                "hostname", host,
+                "port", port,
+                "profile-name", "Default",
+                "mud-name", (gchar *)host, 
+                "connect-string", NULL,
+                "window", conn->parent_window,
+                NULL);
         mud_window_add_connection_view(conn->parent_window, G_OBJECT(view), (gchar *)host);
 
         gtk_widget_destroy(conn->priv->window);

Modified: trunk/src/mud-parse-alias.c
==============================================================================
--- trunk/src/mud-parse-alias.c	(original)
+++ trunk/src/mud-parse-alias.c	Fri Mar 13 23:41:46 2009
@@ -30,54 +30,101 @@
 #include "mud-parse-alias.h"
 #include "utils.h"
 
-GType mud_parse_alias_get_type (void);
+struct _MudParseAliasPrivate
+{
+    MudParseBase *parent;
+};
+
+
+/* Property Identifiers */
+enum
+{
+    PROP_MUD_PARSE_ALIAS_0,
+    PROP_PARENT
+};
+
+/* Create the Type */
+G_DEFINE_TYPE(MudParseAlias, mud_parse_alias, G_TYPE_OBJECT);
+
+/* Class Functions */
 static void mud_parse_alias_init (MudParseAlias *parse_alias);
 static void mud_parse_alias_class_init (MudParseAliasClass *klass);
 static void mud_parse_alias_finalize (GObject *object);
+static GObject *mud_parse_alias_constructor (GType gtype,
+                                             guint n_properties,
+                                             GObjectConstructParam *properties);
+static void mud_parse_alias_set_property(GObject *object,
+                                         guint prop_id,
+                                         const GValue *value,
+                                         GParamSpec *pspec);
+static void mud_parse_alias_get_property(GObject *object,
+                                         guint prop_id,
+                                         GValue *value,
+                                         GParamSpec *pspec);
 
-void mud_parse_alias_parse(const gchar *data, gchar *stripped_data, gint ovector[1020], MudConnectionView *view, MudRegex *regex);
-
-// MudParseAlias class functions
-GType
-mud_parse_alias_get_type (void)
+/* Class Functions */
+static void
+mud_parse_alias_class_init (MudParseAliasClass *klass)
 {
-    static GType object_type = 0;
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
 
-    g_type_init();
+    /* Override base object constructor */
+    object_class->constructor = mud_parse_alias_constructor;
 
-    if (!object_type)
-    {
-        static const GTypeInfo object_info =
-        {
-            sizeof (MudParseAliasClass),
-            NULL,
-            NULL,
-            (GClassInitFunc) mud_parse_alias_class_init,
-            NULL,
-            NULL,
-            sizeof (MudParseAlias),
-            0,
-            (GInstanceInitFunc) mud_parse_alias_init,
-        };
-
-        object_type = g_type_register_static(G_TYPE_OBJECT, "MudParseAlias", &object_info, 0);
-    }
+    /* Override base object's finalize */
+    object_class->finalize = mud_parse_alias_finalize;
 
-    return object_type;
+    /* Override base object property methods */
+    object_class->set_property = mud_parse_alias_set_property;
+    object_class->get_property = mud_parse_alias_get_property;
+
+    /* Add private data to class */
+    g_type_class_add_private(klass, sizeof(MudParseAliasPrivate));
+
+    /* Install Properties */
+    g_object_class_install_property(object_class,
+            PROP_PARENT,
+            g_param_spec_object("parent-base",
+                "parent base",
+                "the parent MudParseBase",
+                MUD_TYPE_PARSE_BASE,
+                G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
 }
 
 static void
-mud_parse_alias_init (MudParseAlias *pa)
+mud_parse_alias_init (MudParseAlias *self)
 {
+    /* Get our private data */
+    self->priv = MUD_PARSE_ALIAS_GET_PRIVATE(self);
 
+    /* set private members to defaults */
+    self->priv->parent = NULL;
 }
 
-static void
-mud_parse_alias_class_init (MudParseAliasClass *klass)
+static GObject *
+mud_parse_alias_constructor (GType gtype,
+                             guint n_properties,
+                             GObjectConstructParam *properties)
 {
-    GObjectClass *object_class = G_OBJECT_CLASS(klass);
+    MudParseAlias *self;
+    GObject *obj;
+    MudParseAliasClass *klass;
+    GObjectClass *parent_class;
 
-    object_class->finalize = mud_parse_alias_finalize;
+    /* Chain up to parent constructor */
+    klass = MUD_PARSE_ALIAS_CLASS( g_type_class_peek(MUD_TYPE_PARSE_ALIAS) );
+    parent_class = G_OBJECT_CLASS( g_type_class_peek_parent(klass) );
+    obj = parent_class->constructor(gtype, n_properties, properties);
+
+    self = MUD_PARSE_ALIAS(obj);
+
+    if(!self->priv->parent && !MUD_IS_PARSE_BASE(self->priv->parent))
+    {
+        g_printf("ERROR: Tried to instantiate MudParseAlias without passing parent parse base\n");
+        g_error("Tried to instantiate MudParseAlias without passing parent parse base");
+    }
+
+    return obj;
 }
 
 static void
@@ -92,9 +139,54 @@
     parent_class->finalize(object);
 }
 
+static void
+mud_parse_alias_set_property(GObject *object,
+                             guint prop_id,
+                             const GValue *value,
+                             GParamSpec *pspec)
+{
+    MudParseAlias *self;
+
+    self = MUD_PARSE_ALIAS(object);
+
+    switch(prop_id)
+    {
+        /* Parent is Construct Only */
+        case PROP_PARENT:
+            self->priv->parent = MUD_PARSE_BASE(g_value_get_object(value));
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
+
+static void
+mud_parse_alias_get_property(GObject *object,
+                             guint prop_id,
+                             GValue *value,
+                             GParamSpec *pspec)
+{
+    MudParseAlias *self;
+
+    self = MUD_PARSE_ALIAS(object);
+
+    switch(prop_id)
+    {
+        case PROP_PARENT:
+            g_value_take_object(value, self->priv->parent);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
+
 // MudParseAlias Methods
 gboolean
-mud_parse_alias_do(gchar *data, MudConnectionView *view, MudRegex *regex, MudParseAlias *alias)
+mud_parse_alias_do(MudParseAlias *self, gchar *data)
 {
     gchar *profile_name;
     gchar *actions;
@@ -106,10 +198,21 @@
     gint enabled;
     gint ovector[1020];
     gboolean send_line = TRUE;
+    MudRegex *regex;
+    MudConnectionView *view;
+
+    g_return_if_fail(MUD_IS_PARSE_ALIAS(self));
 
     client = gconf_client_get_default();
 
-    profile_name = mud_profile_get_name(mud_connection_view_get_current_profile(view));
+    g_object_get(self->priv->parent,
+                 "parent-view", &view,
+                 "regex", &regex,
+                 NULL);
+
+    g_object_get(view,
+                 "profile-name", &profile_name,
+                 NULL);
 
     g_snprintf(keyname, 2048, "/apps/gnome-mud/profiles/%s/aliases/list", profile_name);
     aliases = gconf_client_get_list(client, keyname, GCONF_VALUE_STRING, &error);
@@ -124,13 +227,16 @@
             g_snprintf(keyname, 2048, "/apps/gnome-mud/profiles/%s/aliases/%s/regex", profile_name, (gchar *)entry->data);
             regexstr = gconf_client_get_string(client, keyname, &error);
 
-            if(mud_regex_check((const gchar *)data, strlen(data), regexstr, ovector, regex))
+            if(mud_regex_check(regex, (const gchar *)data, strlen(data), regexstr, ovector))
             {
                 g_snprintf(keyname, 2048, "/apps/gnome-mud/profiles/%s/aliases/%s/actions", profile_name, (gchar *)entry->data);
                 actions = gconf_client_get_string(client, keyname, &error);
 
                 send_line = FALSE;
-                mud_parse_base_parse((const gchar *)actions, data, ovector, view, regex);
+                mud_parse_base_parse(self->priv->parent,
+                                     (const gchar *)actions, 
+                                     data, 
+                                     ovector);
 
                 if(actions)
                     g_free(actions);
@@ -148,14 +254,10 @@
     if(aliases)
         g_slist_free(aliases);
 
+    g_free(profile_name);
+
     g_object_unref(client);
 
     return send_line;
 }
 
-// Instantiate MudParseAlias
-MudParseAlias*
-mud_parse_alias_new(void)
-{
-    return g_object_new(MUD_TYPE_PARSE_ALIAS, NULL);
-}

Modified: trunk/src/mud-parse-alias.h
==============================================================================
--- trunk/src/mud-parse-alias.h	(original)
+++ trunk/src/mud-parse-alias.h	Fri Mar 13 23:41:46 2009
@@ -28,31 +28,30 @@
 #define MUD_IS_PARSE_ALIAS(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), MUD_TYPE_PARSE_ALIAS))
 #define MUD_IS_PARSE_ALIAS_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MUD_TYPE_PARSE_ALIAS))
 #define MUD_PARSE_ALIAS_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), MUD_TYPE_PARSE_ALIAS, MudParseAliasClass))
+#define MUD_PARSE_ALIAS_GET_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUD_TYPE_PARSE_ALIAS, MudParseAliasPrivate))
 
 typedef struct _MudParseAlias            MudParseAlias;
 typedef struct _MudParseAliasClass       MudParseAliasClass;
 typedef struct _MudParseAliasPrivate     MudParseAliasPrivate;
 
+struct _MudParseAliasClass
+{
+	GObjectClass parent_class;
+};
+
 struct _MudParseAlias
 {
 	GObject parent_instance;
 
+        /*< Private >*/
 	MudParseAliasPrivate *priv;
 };
 
-struct _MudParseAliasClass
-{
-	GObjectClass parent_class;
-};
-
-GType mud_parse_alias_get_type (void) G_GNUC_CONST;
-
-MudParseAlias *mud_parse_alias_new(void);
+GType mud_parse_alias_get_type (void);
 
-#include "mud-connection-view.h"
-#include "mud-regex.h"
-gboolean mud_parse_alias_do(gchar *data, MudConnectionView *view, MudRegex *regex, MudParseAlias *alias);
+gboolean mud_parse_alias_do(MudParseAlias *self, gchar *data);
 
 G_END_DECLS
 
 #endif // MUD_PARSE_ALIAS_H
+

Modified: trunk/src/mud-parse-base.c
==============================================================================
--- trunk/src/mud-parse-base.c	(original)
+++ trunk/src/mud-parse-base.c	Fri Mar 13 23:41:46 2009
@@ -41,70 +41,128 @@
 #define PARSE_STATE_REGISTER 	2
 #define PARSE_STATE_INREGISTER  3
 
-typedef struct ParseObject {
-	gchar *data;
-	gint type;
+typedef struct ParseObject
+{
+    gchar *data;
+    gint type;
 } ParseObject;
 
 struct _MudParseBasePrivate
 {
-	MudRegex *regex;
 	MudParseAlias *alias;
 	MudParseTrigger *trigger;
+};
 
-	MudConnectionView *parentview;
+/* Property Identifiers */
+enum
+{
+    PROP_MUD_PARSE_BASE_0,
+    PROP_PARENT_VIEW,
+    PROP_REGEX
 };
 
-GType mud_parse_base_get_type (void);
+/* Create the Type */
+G_DEFINE_TYPE(MudParseBase, mud_parse_base, G_TYPE_OBJECT);
+
+/* Class Functions */
 static void mud_parse_base_init (MudParseBase *parse_base);
 static void mud_parse_base_class_init (MudParseBaseClass *klass);
 static void mud_parse_base_finalize (GObject *object);
+static GObject *mud_parse_base_constructor (GType gtype,
+                                            guint n_properties,
+                                            GObjectConstructParam *properties);
+static void mud_parse_base_set_property(GObject *object,
+                                        guint prop_id,
+                                        const GValue *value,
+                                        GParamSpec *pspec);
+static void mud_parse_base_get_property(GObject *object,
+                                        guint prop_id,
+                                        GValue *value,
+                                        GParamSpec *pspec);
 
 // MudParseBase class functions
-GType
-mud_parse_base_get_type (void)
-{
-    static GType object_type = 0;
 
-    g_type_init();
+static void
+mud_parse_base_class_init (MudParseBaseClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
 
-    if (!object_type)
-    {
-        static const GTypeInfo object_info =
-        {
-            sizeof (MudParseBaseClass),
-            NULL,
-            NULL,
-            (GClassInitFunc) mud_parse_base_class_init,
-            NULL,
-            NULL,
-            sizeof (MudParseBase),
-            0,
-            (GInstanceInitFunc) mud_parse_base_init,
-        };
+    /* Override base object constructor */
+    object_class->constructor = mud_parse_base_constructor;
 
-        object_type = g_type_register_static(G_TYPE_OBJECT, "MudParseBase", &object_info, 0);
-    }
+    /* Override base object's finalize */
+    object_class->finalize = mud_parse_base_finalize;
 
-    return object_type;
+    /* Override base object property methods */
+    object_class->set_property = mud_parse_base_set_property;
+    object_class->get_property = mud_parse_base_get_property;
+
+    /* Add private data to class */
+    g_type_class_add_private(klass, sizeof(MudParseBasePrivate));
+
+    /* Install Properties */
+    g_object_class_install_property(object_class,
+            PROP_PARENT_VIEW,
+            g_param_spec_object("parent-view",
+                "parent view",
+                "parent mud connection view",
+                MUD_TYPE_CONNECTION_VIEW,
+                G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
+
+    g_object_class_install_property(object_class,
+            PROP_REGEX,
+            g_param_spec_object("regex",
+                "regex",
+                "mud regex object",
+                MUD_TYPE_REGEX,
+                G_PARAM_READABLE));
 }
 
 static void
-mud_parse_base_init (MudParseBase *pb)
+mud_parse_base_init (MudParseBase *self)
 {
-    pb->priv = g_new0(MudParseBasePrivate, 1);
+    /* Get our private data */
+    self->priv = MUD_PARSE_BASE_GET_PRIVATE(self);
 
-    pb->priv->regex = mud_regex_new();
-    pb->priv->alias = mud_parse_alias_new();
-    pb->priv->trigger = mud_parse_trigger_new();
+    /* set public members to defaults */
+    self->parent_view = NULL;
+    self->regex = NULL;
 }
 
-static void
-mud_parse_base_class_init (MudParseBaseClass *klass)
+static GObject *
+mud_parse_base_constructor (GType gtype,
+                            guint n_properties,
+                            GObjectConstructParam *properties)
 {
-    GObjectClass *object_class = G_OBJECT_CLASS(klass);
+    MudParseBase *self;
+    GObject *obj;
+    MudParseBaseClass *klass;
+    GObjectClass *parent_class;
 
-    object_class->finalize = mud_parse_base_finalize;
+    /* Chain up to parent constructor */
+    klass = MUD_PARSE_BASE_CLASS( g_type_class_peek(MUD_TYPE_PARSE_BASE) );
+    parent_class = G_OBJECT_CLASS( g_type_class_peek_parent(klass) );
+    obj = parent_class->constructor(gtype, n_properties, properties);
+
+    self = MUD_PARSE_BASE(obj);
+
+    if(!self->parent_view)
+    {
+        g_printf("ERROR: Tried to instantiate MudParseBase without passing parent mudconnectionview\n");
+        g_error("Tried to instantiate MudParseBase without passing parent mudconnectionview");
+    }
+
+    self->regex = g_object_new(MUD_TYPE_REGEX, NULL);
+
+    self->priv->alias = g_object_new(MUD_TYPE_PARSE_ALIAS,
+                                     "parent-base", self,
+                                     NULL);
+
+    self->priv->trigger = g_object_new(MUD_TYPE_PARSE_TRIGGER,
+                                       "parent-base", self,
+                                       NULL);
+
+    return obj;
 }
 
 static void
@@ -115,31 +173,83 @@
 
     parse_base = MUD_PARSE_BASE(object);
 
-    g_object_unref(parse_base->priv->regex);
+    g_object_unref(parse_base->regex);
     g_object_unref(parse_base->priv->alias);
     g_object_unref(parse_base->priv->trigger);
 
-    g_free(parse_base->priv);
-
     parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
     parent_class->finalize(object);
 }
 
+static void
+mud_parse_base_set_property(GObject *object,
+                            guint prop_id,
+                            const GValue *value,
+                            GParamSpec *pspec)
+{
+    MudParseBase *self;
+
+    self = MUD_PARSE_BASE(object);
+
+    switch(prop_id)
+    {
+        case PROP_PARENT_VIEW:
+            self->parent_view = MUD_CONNECTION_VIEW(g_value_get_object(value));
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
+
+static void
+mud_parse_base_get_property(GObject *object,
+                            guint prop_id,
+                            GValue *value,
+                            GParamSpec *pspec)
+{
+    MudParseBase *self;
+
+    self = MUD_PARSE_BASE(object);
+
+    switch(prop_id)
+    {
+        case PROP_PARENT_VIEW:
+            g_value_take_object(value, self->parent_view);
+            break;
+
+        case PROP_REGEX:
+            g_value_take_object(value, self->regex);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
+
 // MudParseBase Methods
 gboolean
-mud_parse_base_do_triggers(MudParseBase *base, gchar *data)
+mud_parse_base_do_triggers(MudParseBase *self, gchar *data)
 {
-    return mud_parse_trigger_do(data, base->priv->parentview, base->priv->regex, base->priv->trigger);
+    if(!MUD_IS_PARSE_BASE(self))
+        return FALSE;
+
+    return mud_parse_trigger_do(self->priv->trigger, data);
 }
 
 gboolean
-mud_parse_base_do_aliases(MudParseBase *base, gchar *data)
+mud_parse_base_do_aliases(MudParseBase *self, gchar *data)
 {
-    return mud_parse_alias_do(data, base->priv->parentview, base->priv->regex, base->priv->alias);
+    if(!MUD_IS_PARSE_BASE(self))
+        return FALSE;
+
+    return mud_parse_alias_do(self->priv->alias, data);
 }
 
 void
-mud_parse_base_parse(const gchar *data, gchar *stripped_data, gint ovector[1020], MudConnectionView *view, MudRegex *regex)
+mud_parse_base_parse(MudParseBase *self, const gchar *data, gchar *stripped_data, gint ovector[1020])
 {
     gint i, state, len, reg_num, reg_len, startword, endword, replace_len, curr_char;
     gchar *replace_text;
@@ -149,6 +259,8 @@
     ParseObject *po = NULL;
     GSList *parse_list, *entry;
 
+    g_return_if_fail(MUD_IS_PARSE_BASE(self));
+
     parse_list = NULL;
     len = strlen(data);
 
@@ -299,19 +411,7 @@
     g_slist_free(parse_list);
 
     // We're done, send our parsed trigger actions!
-    mud_connection_view_send(view, (const gchar *)send_line);
+    mud_connection_view_send(self->parent_view, (const gchar *)send_line);
     g_free(send_line);
 }
 
-// Instantiate MudParseBase
-MudParseBase*
-mud_parse_base_new(MudConnectionView *parentview)
-{
-    MudParseBase *pb;
-
-    pb = g_object_new(MUD_TYPE_PARSE_BASE, NULL);
-
-    pb->priv->parentview = parentview;
-
-    return pb;
-}

Modified: trunk/src/mud-parse-base.h
==============================================================================
--- trunk/src/mud-parse-base.h	(original)
+++ trunk/src/mud-parse-base.h	Fri Mar 13 23:41:46 2009
@@ -28,32 +28,40 @@
 #define MUD_IS_PARSE_BASE(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), MUD_TYPE_PARSE_BASE))
 #define MUD_IS_PARSE_BASE_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MUD_TYPE_PARSE_BASE))
 #define MUD_PARSE_BASE_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), MUD_TYPE_PARSE_BASE, MudParseBaseClass))
+#define MUD_PARSE_BASE_GET_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUD_TYPE_PARSE_BASE, MudParseBasePrivate))
 
 typedef struct _MudParseBase            MudParseBase;
 typedef struct _MudParseBaseClass       MudParseBaseClass;
 typedef struct _MudParseBasePrivate     MudParseBasePrivate;
 
-struct _MudParseBase
-{
-	GObject parent_instance;
-
-	MudParseBasePrivate *priv;
-};
+#include "mud-connection-view.h"
+#include "mud-regex.h"
 
 struct _MudParseBaseClass
 {
-	GObjectClass parent_class;
+    GObjectClass parent_class;
 };
 
-GType mud_parse_base_get_type (void) G_GNUC_CONST;
+struct _MudParseBase
+{
+    GObject parent_instance;
 
-#include "mud-connection-view.h"
-#include "mud-regex.h"
-MudParseBase *mud_parse_base_new(MudConnectionView *parentview);
+    /*< Private >*/
+    MudParseBasePrivate *priv;
+
+    /*< Public >*/
+    MudConnectionView *parent_view;
+    MudRegex *regex;
+};
+
+GType mud_parse_base_get_type (void);
 
-gboolean mud_parse_base_do_triggers(MudParseBase *base, gchar *data);
-gboolean mud_parse_base_do_aliases(MudParseBase *base, gchar *data);
-void mud_parse_base_parse(const gchar *data, gchar *stripped_data, gint ovector[1020], MudConnectionView *view, MudRegex *regex);
+gboolean mud_parse_base_do_triggers(MudParseBase *self, gchar *data);
+gboolean mud_parse_base_do_aliases(MudParseBase *self, gchar *data);
+void mud_parse_base_parse(MudParseBase *self,
+                          const gchar *data,
+                          gchar *stripped_data,
+                          gint ovector[1020]);
 
 G_END_DECLS
 

Modified: trunk/src/mud-parse-trigger.c
==============================================================================
--- trunk/src/mud-parse-trigger.c	(original)
+++ trunk/src/mud-parse-trigger.c	Fri Mar 13 23:41:46 2009
@@ -35,55 +35,98 @@
 
 struct _MudParseTriggerPrivate
 {
+    MudParseBase *parent;
+};
+
 
+/* Property Identifiers */
+enum
+{
+    PROP_MUD_PARSE_TRIGGER_0,
+    PROP_PARENT
 };
 
-GType mud_parse_trigger_get_type (void);
+/* Create the Type */
+G_DEFINE_TYPE(MudParseTrigger, mud_parse_trigger, G_TYPE_OBJECT);
+
+/* Class Functions */
 static void mud_parse_trigger_init (MudParseTrigger *pt);
 static void mud_parse_trigger_class_init (MudParseTriggerClass *klass);
 static void mud_parse_trigger_finalize (GObject *object);
-
+static GObject *mud_parse_trigger_constructor (GType gtype,
+                                               guint n_properties,
+                                               GObjectConstructParam *properties);
+static void mud_parse_trigger_set_property(GObject *object,
+                                           guint prop_id,
+                                           const GValue *value,
+                                           GParamSpec *pspec);
+static void mud_parse_trigger_get_property(GObject *object,
+                                           guint prop_id,
+                                           GValue *value,
+                                           GParamSpec *pspec);
 // MudParseTrigger class functions
-GType
-mud_parse_trigger_get_type (void)
+static void
+mud_parse_trigger_class_init (MudParseTriggerClass *klass)
 {
-    static GType object_type = 0;
-
-    g_type_init();
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
 
-    if (!object_type)
-    {
-        static const GTypeInfo object_info =
-        {
-            sizeof (MudParseTriggerClass),
-            NULL,
-            NULL,
-            (GClassInitFunc) mud_parse_trigger_class_init,
-            NULL,
-            NULL,
-            sizeof (MudParseTrigger),
-            0,
-            (GInstanceInitFunc) mud_parse_trigger_init,
-        };
+    /* Override base object constructor */
+    object_class->constructor = mud_parse_trigger_constructor;
 
-        object_type = g_type_register_static(G_TYPE_OBJECT, "MudParseTrigger", &object_info, 0);
-    }
+    /* Override base object's finalize */
+    object_class->finalize = mud_parse_trigger_finalize;
 
-    return object_type;
+    /* Override base object property methods */
+    object_class->set_property = mud_parse_trigger_set_property;
+    object_class->get_property = mud_parse_trigger_get_property;
+
+    /* Add private data to class */
+    g_type_class_add_private(klass, sizeof(MudParseTriggerPrivate));
+
+    /* Install Properties */
+    g_object_class_install_property(object_class,
+            PROP_PARENT,
+            g_param_spec_object("parent-base",
+                "parent base",
+                "the parent MudParseBase",
+                MUD_TYPE_PARSE_BASE,
+                G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
 }
 
 static void
-mud_parse_trigger_init (MudParseTrigger *pt)
+mud_parse_trigger_init (MudParseTrigger *self)
 {
-    pt->priv = g_new0(MudParseTriggerPrivate, 1);
+    /* Get our private data */
+    self->priv = MUD_PARSE_TRIGGER_GET_PRIVATE(self);
+
+    /* set private members to defaults */
+    self->priv->parent = NULL;
 }
 
-static void
-mud_parse_trigger_class_init (MudParseTriggerClass *klass)
+static GObject *
+mud_parse_trigger_constructor (GType gtype,
+                               guint n_properties,
+                               GObjectConstructParam *properties)
 {
-    GObjectClass *object_class = G_OBJECT_CLASS(klass);
+    MudParseTrigger *self;
+    GObject *obj;
+    MudParseTriggerClass *klass;
+    GObjectClass *parent_class;
 
-    object_class->finalize = mud_parse_trigger_finalize;
+    /* Chain up to parent constructor */
+    klass = MUD_PARSE_TRIGGER_CLASS( g_type_class_peek(MUD_TYPE_PARSE_TRIGGER) );
+    parent_class = G_OBJECT_CLASS( g_type_class_peek_parent(klass) );
+    obj = parent_class->constructor(gtype, n_properties, properties);
+
+    self = MUD_PARSE_TRIGGER(obj);
+
+    if(!self->priv->parent)
+    {
+        g_printf("ERROR: Tried to instantiate MudParseTrigger without passing parent parse base\n");
+        g_error("Tried to instantiate MudParseTrigger without passing parent parse base");
+    }
+
+    return obj;
 }
 
 static void
@@ -94,15 +137,58 @@
 
     parse_trigger = MUD_PARSE_TRIGGER(object);
 
-    g_free(parse_trigger->priv);
-
     parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
     parent_class->finalize(object);
 }
 
-// MudParseTrigger Methods
+static void
+mud_parse_trigger_set_property(GObject *object,
+                               guint prop_id,
+                               const GValue *value,
+                               GParamSpec *pspec)
+{
+    MudParseTrigger *self;
+
+    self = MUD_PARSE_TRIGGER(object);
+
+    switch(prop_id)
+    {
+        /* Parent is Construct Only */
+        case PROP_PARENT:
+            self->priv->parent = MUD_PARSE_BASE(g_value_get_object(value));
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
+
+static void
+mud_parse_trigger_get_property(GObject *object,
+                               guint prop_id,
+                               GValue *value,
+                               GParamSpec *pspec)
+{
+    MudParseTrigger *self;
+
+    self = MUD_PARSE_TRIGGER(object);
+
+    switch(prop_id)
+    {
+        case PROP_PARENT:
+            g_value_take_object(value, self->priv->parent);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
+
+/* Public Methods */
 gboolean
-mud_parse_trigger_do(gchar *data, MudConnectionView *view, MudRegex *regex, MudParseTrigger *trig)
+mud_parse_trigger_do(MudParseTrigger *self, gchar *data)
 {
     gchar *profile_name;
     gchar *actions;
@@ -116,10 +202,21 @@
     gint gag;
     gint ovector[1020];
     gboolean doGag = FALSE;
+    MudRegex *regex;
+    MudConnectionView *view;
+
+    g_return_if_fail(MUD_IS_PARSE_TRIGGER(self));
 
     client = gconf_client_get_default();
 
-    profile_name = mud_profile_get_name(mud_connection_view_get_current_profile(view));
+    g_object_get(self->priv->parent,
+                 "parent-view", &view,
+                 "regex", &regex,
+                 NULL);
+
+    g_object_get(view,
+                 "profile-name", &profile_name,
+                 NULL);
 
     g_snprintf(keyname, 2048, "/apps/gnome-mud/profiles/%s/triggers/list", profile_name);
     triggers = gconf_client_get_list(client, keyname, GCONF_VALUE_STRING, &error);
@@ -136,7 +233,7 @@
 
             stripped_data = utils_strip_ansi((const gchar *) data);
 
-            if(mud_regex_check((const gchar *)stripped_data, strlen(stripped_data), (const gchar *)regexstr, ovector, regex))
+            if(mud_regex_check(regex, (const gchar *)stripped_data, strlen(stripped_data), (const gchar *)regexstr, ovector))
             {
                 g_snprintf(keyname, 2048, "/apps/gnome-mud/profiles/%s/triggers/%s/gag", profile_name, (gchar *)entry->data);
                 gag = gconf_client_get_int(client, keyname, &error);
@@ -149,7 +246,10 @@
                 g_snprintf(keyname, 2048, "/apps/gnome-mud/profiles/%s/triggers/%s/actions", profile_name, (gchar *)entry->data);
                 actions = gconf_client_get_string(client, keyname, &error);
 
-                mud_parse_base_parse((const gchar *)actions, stripped_data, ovector, view, regex);
+                mud_parse_base_parse(self->priv->parent,
+                                     (const gchar *)actions, 
+                                     stripped_data, 
+                                     ovector);
 
                 if(actions)
                     g_free(actions);
@@ -169,12 +269,8 @@
 
     g_object_unref(client);
 
+    g_free(profile_name);
+
     return doGag;
 }
 
-// Instantiate MudParseTrigger
-MudParseTrigger*
-mud_parse_trigger_new(void)
-{
-    return g_object_new(MUD_TYPE_PARSE_TRIGGER, NULL);
-}

Modified: trunk/src/mud-parse-trigger.h
==============================================================================
--- trunk/src/mud-parse-trigger.h	(original)
+++ trunk/src/mud-parse-trigger.h	Fri Mar 13 23:41:46 2009
@@ -28,31 +28,30 @@
 #define MUD_IS_PARSE_TRIGGER(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), MUD_TYPE_PARSE_TRIGGER))
 #define MUD_IS_PARSE_TRIGGER_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MUD_TYPE_PARSE_TRIGGER))
 #define MUD_PARSE_TRIGGER_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), MUD_TYPE_PARSE_TRIGGER, MudParseTriggerClass))
+#define MUD_PARSE_TRIGGER_GET_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUD_TYPE_PARSE_TRIGGER, MudParseTriggerPrivate))
 
 typedef struct _MudParseTrigger            MudParseTrigger;
 typedef struct _MudParseTriggerClass       MudParseTriggerClass;
 typedef struct _MudParseTriggerPrivate     MudParseTriggerPrivate;
 
+struct _MudParseTriggerClass
+{
+	GObjectClass parent_class;
+};
+
 struct _MudParseTrigger
 {
 	GObject parent_instance;
 
+        /*< Private >*/
 	MudParseTriggerPrivate *priv;
 };
 
-struct _MudParseTriggerClass
-{
-	GObjectClass parent_class;
-};
-
-GType mud_parse_trigger_get_type (void) G_GNUC_CONST;
-
-MudParseTrigger *mud_parse_trigger_new(void);
+GType mud_parse_trigger_get_type (void);
 
-#include "mud-regex.h"
-#include "mud-connection-view.h"
-gboolean mud_parse_trigger_do(gchar *data, MudConnectionView *view, MudRegex *regex, MudParseTrigger *trigger);
+gboolean mud_parse_trigger_do(MudParseTrigger *self, gchar *data);
 
 G_END_DECLS
 
 #endif // MUD_PARSE_TRIGGER_H
+

Modified: trunk/src/mud-profile.c
==============================================================================
--- trunk/src/mud-profile.c	(original)
+++ trunk/src/mud-profile.c	Fri Mar 13 23:41:46 2009
@@ -177,7 +177,7 @@
     profile = get_profile(name);
     if (profile == NULL)
     {
-        profile = g_object_new(TYPE_MUD_PROFILE, NULL);
+        profile = g_object_new(MUD_TYPE_PROFILE, NULL);
         profile->name = g_strdup(name);
         profile->preferences = &profile->priv->preferences;
 

Modified: trunk/src/mud-profile.h
==============================================================================
--- trunk/src/mud-profile.h	(original)
+++ trunk/src/mud-profile.h	Fri Mar 13 23:41:46 2009
@@ -26,13 +26,13 @@
 #include <gtk/gtk.h>
 #include <gdk/gdk.h>
 
-#define TYPE_MUD_PROFILE              (mud_profile_get_type ())
-#define MUD_PROFILE(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), TYPE_MUD_PROFILE, MudProfile))
-#define MUD_PROFILE_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_MUD_PROFILE, MudProfile))
-#define IS_MUD_PROFILE(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), TYPE_MUD_PROFILE))
-#define IS_MUD_PROFILE_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_MUD_PROFILE))
-#define MUD_PROFILE_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_MUD_PROFILE, MudProfileClass))
-#define MUD_PROFILE_GET_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_MUD_PROFILE, MudProfilePrivate))
+#define MUD_TYPE_PROFILE              (mud_profile_get_type ())
+#define MUD_PROFILE(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), MUD_TYPE_PROFILE, MudProfile))
+#define MUD_PROFILE_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), MUD_TYPE_PROFILE, MudProfile))
+#define IS_MUD_PROFILE(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), MUD_TYPE_PROFILE))
+#define IS_MUD_PROFILE_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MUD_TYPE_PROFILE))
+#define MUD_PROFILE_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), MUD_TYPE_PROFILE, MudProfileClass))
+#define MUD_PROFILE_GET_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUD_TYPE_PROFILE, MudProfilePrivate))
 
 #define C_MAX 16
 

Modified: trunk/src/mud-regex.c
==============================================================================
--- trunk/src/mud-regex.c	(original)
+++ trunk/src/mud-regex.c	Fri Mar 13 23:41:46 2009
@@ -36,60 +36,36 @@
     gint substring_count;
 };
 
-GType mud_regex_get_type (void);
+/* Create the Type */
+G_DEFINE_TYPE(MudRegex, mud_regex, G_TYPE_OBJECT);
+
 static void mud_regex_init (MudRegex *regex);
 static void mud_regex_class_init (MudRegexClass *klass);
 static void mud_regex_finalize (GObject *object);
 
-// MudRegex class functions
-GType
-mud_regex_get_type (void)
+/* Class Functions */
+static void
+mud_regex_class_init (MudRegexClass *klass)
 {
-    static GType object_type = 0;
-
-    g_type_init();
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
 
-    if (!object_type)
-    {
-	static const GTypeInfo object_info =
-	    {
-		sizeof (MudRegexClass),
-		NULL,
-		NULL,
-		(GClassInitFunc) mud_regex_class_init,
-		NULL,
-		NULL,
-		sizeof (MudRegex),
-		0,
-		(GInstanceInitFunc) mud_regex_init,
-	    };
-
-	object_type =
-	    g_type_register_static(
-		G_TYPE_OBJECT, "MudRegex", &object_info, 0);
-    }
+    /* Override base object's finalize */
+    object_class->finalize = mud_regex_finalize;
 
-    return object_type;
+    /* Add our private data */
+    g_type_class_add_private(klass, sizeof(MudRegexPrivate));
 }
 
 static void
 mud_regex_init (MudRegex *regex)
 {
-    regex->priv = g_new0(MudRegexPrivate, 1);
+    regex->priv = MUD_REGEX_GET_PRIVATE(regex);
 
     regex->priv->substring_list = NULL;
     regex->priv->substring_count = 0;
 }
 
 static void
-mud_regex_class_init (MudRegexClass *klass)
-{
-    GObjectClass *object_class = G_OBJECT_CLASS(klass);
-
-    object_class->finalize = mud_regex_finalize;
-}
-
-static void
 mud_regex_finalize (GObject *object)
 {
     MudRegex *regex;
@@ -100,20 +76,17 @@
     if(regex->priv->substring_list)
          pcre_free_substring_list(regex->priv->substring_list);
 
-    g_free(regex->priv);
-
     parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
     parent_class->finalize(object);
 }
 
-// MudRegex Methods
-
+/* Public Methods */
 gboolean
-mud_regex_check(const gchar *data,
+mud_regex_check(MudRegex *regex,
+                const gchar *data,
 		guint length,
 		const gchar *rx,
-		gint ovector[1020],
-		MudRegex *regex)
+		gint ovector[1020])
 {
     pcre *re = NULL;
     const gchar *error = NULL;
@@ -121,6 +94,8 @@
     gint erroroffset;
     gint rc;
 
+    g_return_if_fail(MUD_IS_REGEX(regex));
+
     re = pcre_compile2(rx, 0, &errorcode, &error, &erroroffset, NULL);
 
     if(!re)
@@ -195,20 +170,11 @@
 }
 
 const gchar **
-mud_regex_get_substring_list(gint *count, MudRegex *regex)
+mud_regex_get_substring_list(MudRegex *regex, gint *count)
 {
+    g_return_if_fail(MUD_IS_REGEX(regex));
+
     *count = regex->priv->substring_count;
     return regex->priv->substring_list;
 }
 
-
-// Instantiate MudRegex
-MudRegex*
-mud_regex_new(void)
-{
-    MudRegex *regex;
-
-    regex = g_object_new(MUD_TYPE_REGEX, NULL);
-
-    return regex;
-}

Modified: trunk/src/mud-regex.h
==============================================================================
--- trunk/src/mud-regex.h	(original)
+++ trunk/src/mud-regex.h	Fri Mar 13 23:41:46 2009
@@ -28,32 +28,33 @@
 #define MUD_IS_REGEX(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), MUD_TYPE_REGEX))
 #define MUD_IS_REGEX_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MUD_TYPE_REGEX))
 #define MUD_REGEX_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), MUD_TYPE_REGEX, MudRegexClass))
+#define MUD_REGEX_GET_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUD_TYPE_REGEX, MudRegexPrivate))
 
 typedef struct _MudRegex            MudRegex;
 typedef struct _MudRegexClass       MudRegexClass;
 typedef struct _MudRegexPrivate     MudRegexPrivate;
 
+struct _MudRegexClass
+{
+    GObjectClass parent_class;
+};
+
 struct _MudRegex
 {
     GObject parent_instance;
 
+    /*< Private >*/
     MudRegexPrivate *priv;
 };
 
-struct _MudRegexClass
-{
-    GObjectClass parent_class;
-};
-
-GType mud_regex_get_type (void) G_GNUC_CONST;
-
-MudRegex *mud_regex_new(void);
+GType mud_regex_get_type (void);
 
-gboolean mud_regex_check(const gchar *data, guint length, const gchar *rx, gint ovector[1020], MudRegex *regex);
+gboolean mud_regex_check(MudRegex *regex, const gchar *data, guint length, const gchar *rx, gint ovector[1020]);
 const gchar **mud_regex_test(const gchar *data, guint length, const gchar *rx, gint *rc, const gchar **error, gint *errorcode, gint *erroroffset);
 void mud_regex_substring_clear(const gchar **substring_list);
-const gchar **mud_regex_get_substring_list(gint *count, MudRegex *regex);
+const gchar **mud_regex_get_substring_list(MudRegex *regex, gint *count);
 
 G_END_DECLS
 
 #endif // MUD_REGEX_H
+

Added: trunk/src/mud-telnet-charset.c
==============================================================================
--- (empty file)
+++ trunk/src/mud-telnet-charset.c	Fri Mar 13 23:41:46 2009
@@ -0,0 +1,377 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-charset.c
+ * Copyright (C) 2005-2009 Les Harris <lharris gnome org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+#include <glib/gi18n.h>
+#include <gnet.h>
+
+#include "gnome-mud.h"
+#include "mud-telnet.h"
+#include "mud-telnet-handler-interface.h"
+#include "mud-telnet-charset.h"
+
+struct _MudTelnetCharsetPrivate
+{
+    /* Interface Properties */
+    MudTelnet *telnet;
+    gboolean enabled;
+    gint option;
+
+    /* Private Instance Members */
+};
+
+/* Property Identifiers */
+enum
+{
+    PROP_MUD_TELNET_CHARSET_0,
+    PROP_ENABLED,
+    PROP_HANDLES_OPTION,
+    PROP_TELNET
+};
+
+/* Class Functions */
+static void mud_telnet_charset_init (MudTelnetCharset *self);
+static void mud_telnet_charset_class_init (MudTelnetCharsetClass *klass);
+static void mud_telnet_charset_interface_init(MudTelnetHandlerInterface *iface);
+static void mud_telnet_charset_finalize (GObject *object);
+static GObject *mud_telnet_charset_constructor (GType gtype,
+                                             guint n_properties,
+                                             GObjectConstructParam *properties);
+static void mud_telnet_charset_set_property(GObject *object,
+                                         guint prop_id,
+                                         const GValue *value,
+                                         GParamSpec *pspec);
+static void mud_telnet_charset_get_property(GObject *object,
+                                         guint prop_id,
+                                         GValue *value,
+                                         GParamSpec *pspec);
+
+/* Interface Implementation */
+void mud_telnet_charset_enable(MudTelnetHandler *self);
+void mud_telnet_charset_disable(MudTelnetHandler *self);
+void mud_telnet_charset_handle_sub_neg(MudTelnetHandler *self,
+                                    guchar *buf,
+                                    guint len);
+
+/* Private Methods */
+static void mud_telnet_charset_send(MudTelnetCharset *self, gchar *encoding);
+
+/* Create the Type. We implement MudTelnetHandlerInterface */
+G_DEFINE_TYPE_WITH_CODE(MudTelnetCharset, mud_telnet_charset, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE (MUD_TELNET_HANDLER_TYPE,
+                                               mud_telnet_charset_interface_init));
+/* MudTelnetCharset class functions */
+static void
+mud_telnet_charset_class_init (MudTelnetCharsetClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+    /* Override base object constructor */
+    object_class->constructor = mud_telnet_charset_constructor;
+
+    /* Override base object's finalize */
+    object_class->finalize = mud_telnet_charset_finalize;
+
+    /* Override base object property methods */
+    object_class->set_property = mud_telnet_charset_set_property;
+    object_class->get_property = mud_telnet_charset_get_property;
+
+    /* Add private data to class */
+    g_type_class_add_private(klass, sizeof(MudTelnetCharsetPrivate));
+
+    /* Override Implementation Properties */
+    g_object_class_override_property(object_class,
+                                     PROP_ENABLED,
+                                     "enabled");
+
+    g_object_class_override_property(object_class,
+                                     PROP_HANDLES_OPTION,
+                                     "handles-option");
+
+    g_object_class_override_property(object_class,
+                                     PROP_TELNET,
+                                     "telnet");
+}
+
+static void
+mud_telnet_charset_interface_init(MudTelnetHandlerInterface *iface)
+{
+    iface->Enable = mud_telnet_charset_enable;
+    iface->Disable = mud_telnet_charset_disable;
+    iface->HandleSubNeg = mud_telnet_charset_handle_sub_neg;
+}
+
+static void
+mud_telnet_charset_init (MudTelnetCharset *self)
+{
+    /* Get our private data */
+    self->priv = MUD_TELNET_CHARSET_GET_PRIVATE(self);
+
+    /* Set the defaults */
+    self->priv->telnet = NULL;
+    self->priv->option = TELOPT_CHARSET;
+    self->priv->enabled = FALSE;
+}
+
+static GObject *
+mud_telnet_charset_constructor (GType gtype,
+                              guint n_properties,
+                              GObjectConstructParam *properties)
+{
+    MudTelnetCharset *self;
+    GObject *obj;
+    MudTelnetCharsetClass *klass;
+    GObjectClass *parent_class;
+
+    /* Chain up to parent constructor */
+    klass = MUD_TELNET_CHARSET_CLASS( g_type_class_peek(MUD_TYPE_TELNET_CHARSET) );
+    parent_class = G_OBJECT_CLASS( g_type_class_peek_parent(klass) );
+    obj = parent_class->constructor(gtype, n_properties, properties);
+
+    self = MUD_TELNET_CHARSET(obj);
+
+    if(!self->priv->telnet)
+    {
+        g_printf("ERROR: Tried to instantiate MudTelnetCharset without passing parent MudTelnet\n");
+        g_error("Tried to instantiate MudTelnetCharset without passing parent MudTelnet");
+    }
+
+    return obj;
+}
+
+static void
+mud_telnet_charset_finalize (GObject *object)
+{
+    MudTelnetCharset *self;
+    GObjectClass *parent_class;
+
+    self = MUD_TELNET_CHARSET(object);
+
+    parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
+    parent_class->finalize(object);
+}
+
+static void
+mud_telnet_charset_set_property(GObject *object,
+                              guint prop_id,
+                              const GValue *value,
+                              GParamSpec *pspec)
+{
+    MudTelnetCharset *self;
+
+    self = MUD_TELNET_CHARSET(object);
+
+    switch(prop_id)
+    {
+        case PROP_TELNET:
+            self->priv->telnet = MUD_TELNET(g_value_get_object(value));
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
+
+static void
+mud_telnet_charset_get_property(GObject *object,
+                              guint prop_id,
+                              GValue *value,
+                              GParamSpec *pspec)
+{
+    MudTelnetCharset *self;
+
+    self = MUD_TELNET_CHARSET(object);
+
+    switch(prop_id)
+    {
+        case PROP_ENABLED:
+            g_value_set_boolean(value, self->priv->enabled);
+            break;
+
+        case PROP_HANDLES_OPTION:
+            g_value_set_int(value, self->priv->option);
+            break;
+
+        case PROP_TELNET:
+            g_value_take_object(value, self->priv->telnet);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
+
+/* Interface Implementation */
+void 
+mud_telnet_charset_enable(MudTelnetHandler *handler)
+{
+    MudTelnetCharset *self;
+
+    self = MUD_TELNET_CHARSET(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_CHARSET(self));
+
+    self->priv->enabled = TRUE;
+
+    g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "CHARSET Enabled");
+}
+
+void
+mud_telnet_charset_disable(MudTelnetHandler *handler)
+{
+    MudTelnetCharset *self;
+    MudConnectionView *view;
+
+    self = MUD_TELNET_CHARSET(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_CHARSET(self));
+
+    self->priv->enabled = FALSE;
+
+    g_object_get(self->priv->telnet, "parent-view", &view, NULL);
+
+    g_object_set(view,
+                 "remote-encode", FALSE,
+                 "remote-encoding", NULL,
+                 NULL);
+
+    g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "CHARSET Disabled");
+}
+
+void
+mud_telnet_charset_handle_sub_neg(MudTelnetHandler *handler,
+                               guchar *buf,
+                               guint len)
+{
+    gint index = 0;
+    guchar sep;
+    guchar tbuf[9];
+    gchar sep_buf[2];
+    GString *encoding;
+    gchar **encodings;
+    MudTelnetCharset *self;
+
+    self = MUD_TELNET_CHARSET(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_CHARSET(self));
+
+    switch(buf[index])
+    {
+        case TEL_CHARSET_REQUEST:
+            // Check for [TTABLE] and
+            // reject if found.
+            memcpy(&buf[1], tbuf, 8);
+            tbuf[8] = '\0';
+
+            if(strcmp((gchar *)tbuf, "[TTABLE]") == 0)
+            {
+                mud_telnet_send_sub_req(self->priv->telnet, 2,
+                        (guchar)TELOPT_CHARSET,
+                        (guchar)TEL_CHARSET_TTABLE_REJECTED);
+                return;
+            }
+
+            sep = buf[++index];
+            index++;
+
+            encoding = g_string_new(NULL);
+
+            while(buf[index] != (guchar)TEL_SE)
+                encoding = g_string_append_c(encoding, buf[index++]);
+
+            sep_buf[0] = (gchar)sep;
+            sep_buf[1] = '\0';
+            encodings = g_strsplit(encoding->str, sep_buf, -1);
+
+            /* We are using VTE's locale fallback function
+               to handle a charset we do not support so we
+               just take the first returned and use it.
+
+               This is potentially stupid. Fix me? */
+
+            if(g_strv_length(encodings) != 0)
+            {
+                MudConnectionView *view;
+                g_object_get(self->priv->telnet, "parent-view", &view, NULL);
+
+                g_object_set(view,
+                        "remote-encode", TRUE,
+                        "remote-encoding", encodings[0],
+                        NULL);
+            }
+
+            mud_telnet_charset_send(self, encodings[0]);
+
+            g_string_free(encoding, TRUE);
+            g_strfreev(encodings);
+
+            break;
+    }
+}
+
+/* Private Methods */
+static void
+mud_telnet_charset_send(MudTelnetCharset *self, gchar *encoding)
+{
+    guchar byte;
+    guint32 i;
+    GConn *conn;
+
+    g_return_if_fail(MUD_IS_TELNET_CHARSET(self));
+
+    if(!encoding)
+	return;
+
+    g_log("Telnet", G_LOG_LEVEL_DEBUG, "Sending Charset Accepted SubReq");
+
+    g_object_get(self->priv->telnet, "connection", &conn, NULL);
+
+    /* Writes IAC SB CHARSET ACCEPTED <charset> IAC SE to server */
+    byte = (guchar)TEL_IAC;
+
+    gnet_conn_write(conn, (gchar *)&byte, 1);
+    byte = (guchar)TEL_SB;
+    gnet_conn_write(conn, (gchar *)&byte, 1);
+    byte = (guchar)TELOPT_CHARSET;
+    gnet_conn_write(conn, (gchar *)&byte, 1);
+    byte = (guchar)TEL_CHARSET_ACCEPT;
+    gnet_conn_write(conn, (gchar *)&byte, 1);
+
+    for (i = 0; i < strlen(encoding); ++i)
+    {
+	byte = (guchar)encoding[i];
+	gnet_conn_write(conn, (gchar *)&byte, 1);
+
+	if (byte == (guchar)TEL_IAC)
+	    gnet_conn_write(conn, (gchar *)&byte, 1);
+    }
+
+    byte = (guchar)TEL_IAC;
+    gnet_conn_write(conn, (gchar *)&byte, 1);
+    byte = (guchar)TEL_SE;
+    gnet_conn_write(conn, (gchar *)&byte, 1);
+}
+

Added: trunk/src/mud-telnet-charset.h
==============================================================================
--- (empty file)
+++ trunk/src/mud-telnet-charset.h	Fri Mar 13 23:41:46 2009
@@ -0,0 +1,57 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-charset.h
+ * Copyright (C) 2005-2009 Les Harris <lharris gnome org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef MUD_TELNET_CHARSET_H
+#define MUD_TELNET_CHARSET_H
+
+G_BEGIN_DECLS
+
+#include <glib.h>
+
+#define MUD_TYPE_TELNET_CHARSET              (mud_telnet_charset_get_type ())
+#define MUD_TELNET_CHARSET(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), MUD_TYPE_TELNET_CHARSET, MudTelnetCharset))
+#define MUD_TELNET_CHARSET_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), MUD_TYPE_TELNET_CHARSET, MudTelnetCharsetClass))
+#define MUD_IS_TELNET_CHARSET(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), MUD_TYPE_TELNET_CHARSET))
+#define MUD_IS_TELNET_CHARSET_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MUD_TYPE_TELNET_CHARSET))
+#define MUD_TELNET_CHARSET_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), MUD_TYPE_TELNET_CHARSET, MudTelnetCharsetClass))
+#define MUD_TELNET_CHARSET_GET_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUD_TYPE_TELNET_CHARSET, MudTelnetCharsetPrivate))
+
+typedef struct _MudTelnetCharset            MudTelnetCharset;
+typedef struct _MudTelnetCharsetClass       MudTelnetCharsetClass;
+typedef struct _MudTelnetCharsetPrivate     MudTelnetCharsetPrivate;
+
+struct _MudTelnetCharsetClass
+{
+    GObjectClass parent_class;
+};
+
+struct _MudTelnetCharset
+{
+    GObject parent_instance;
+
+    /*< private >*/
+    MudTelnetCharsetPrivate *priv;
+};
+
+GType mud_telnet_charset_get_type (void);
+
+G_END_DECLS
+
+#endif // MUD_TELNET_CHARSET_H
+

Added: trunk/src/mud-telnet-echo.c
==============================================================================
--- (empty file)
+++ trunk/src/mud-telnet-echo.c	Fri Mar 13 23:41:46 2009
@@ -0,0 +1,278 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-echo.c
+ * Copyright (C) 2005-2009 Les Harris <lharris gnome org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+#include <glib/gi18n.h>
+
+#include "gnome-mud.h"
+#include "mud-telnet.h"
+#include "mud-telnet-handler-interface.h"
+#include "mud-telnet-echo.h"
+
+struct _MudTelnetEchoPrivate
+{
+    /* Interface Properties */
+    MudTelnet *telnet;
+    gboolean enabled;
+    gint option;
+
+    /* Private Instance Members */
+};
+
+/* Property Identifiers */
+enum
+{
+    PROP_MUD_TELNET_ECHO_0,
+    PROP_ENABLED,
+    PROP_HANDLES_OPTION,
+    PROP_TELNET
+};
+
+/* Class Functions */
+static void mud_telnet_echo_init (MudTelnetEcho *self);
+static void mud_telnet_echo_class_init (MudTelnetEchoClass *klass);
+static void mud_telnet_echo_interface_init(MudTelnetHandlerInterface *iface);
+static void mud_telnet_echo_finalize (GObject *object);
+static GObject *mud_telnet_echo_constructor (GType gtype,
+                                             guint n_properties,
+                                             GObjectConstructParam *properties);
+static void mud_telnet_echo_set_property(GObject *object,
+                                         guint prop_id,
+                                         const GValue *value,
+                                         GParamSpec *pspec);
+static void mud_telnet_echo_get_property(GObject *object,
+                                         guint prop_id,
+                                         GValue *value,
+                                         GParamSpec *pspec);
+
+/*Interface Implementation */
+void mud_telnet_echo_enable(MudTelnetHandler *self);
+void mud_telnet_echo_disable(MudTelnetHandler *self);
+void mud_telnet_echo_handle_sub_neg(MudTelnetHandler *self,
+                                    guchar *buf,
+                                    guint len);
+
+/* Create the Type. We implement MudTelnetHandlerInterface */
+G_DEFINE_TYPE_WITH_CODE(MudTelnetEcho, mud_telnet_echo, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE (MUD_TELNET_HANDLER_TYPE,
+                                               mud_telnet_echo_interface_init));
+/* MudTelnetEcho class functions */
+static void
+mud_telnet_echo_class_init (MudTelnetEchoClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+    /* Override base object constructor */
+    object_class->constructor = mud_telnet_echo_constructor;
+
+    /* Override base object's finalize */
+    object_class->finalize = mud_telnet_echo_finalize;
+
+    /* Override base object property methods */
+    object_class->set_property = mud_telnet_echo_set_property;
+    object_class->get_property = mud_telnet_echo_get_property;
+
+    /* Add private data to class */
+    g_type_class_add_private(klass, sizeof(MudTelnetEchoPrivate));
+
+    /* Override Implementation Properties */
+    g_object_class_override_property(object_class,
+                                     PROP_ENABLED,
+                                     "enabled");
+
+    g_object_class_override_property(object_class,
+                                     PROP_HANDLES_OPTION,
+                                     "handles-option");
+
+    g_object_class_override_property(object_class,
+                                     PROP_TELNET,
+                                     "telnet");
+}
+
+static void
+mud_telnet_echo_interface_init(MudTelnetHandlerInterface *iface)
+{
+    iface->Enable = mud_telnet_echo_enable;
+    iface->Disable = mud_telnet_echo_disable;
+    iface->HandleSubNeg = mud_telnet_echo_handle_sub_neg;
+}
+
+static void
+mud_telnet_echo_init (MudTelnetEcho *self)
+{
+    /* Get our private data */
+    self->priv = MUD_TELNET_ECHO_GET_PRIVATE(self);
+
+    /* Set the defaults */
+    self->priv->telnet = NULL;
+    self->priv->option = TELOPT_ECHO;
+    self->priv->enabled = FALSE;
+}
+
+static GObject *
+mud_telnet_echo_constructor (GType gtype,
+                              guint n_properties,
+                              GObjectConstructParam *properties)
+{
+    MudTelnetEcho *self;
+    GObject *obj;
+    MudTelnetEchoClass *klass;
+    GObjectClass *parent_class;
+
+    /* Chain up to parent constructor */
+    klass = MUD_TELNET_ECHO_CLASS( g_type_class_peek(MUD_TYPE_TELNET_ECHO) );
+    parent_class = G_OBJECT_CLASS( g_type_class_peek_parent(klass) );
+    obj = parent_class->constructor(gtype, n_properties, properties);
+
+    self = MUD_TELNET_ECHO(obj);
+
+    if(!self->priv->telnet)
+    {
+        g_printf("ERROR: Tried to instantiate MudTelnetEcho without passing parent MudTelnet\n");
+        g_error("Tried to instantiate MudTelnetEcho without passing parent MudTelnet");
+    }
+
+    return obj;
+}
+
+static void
+mud_telnet_echo_finalize (GObject *object)
+{
+    MudTelnetEcho *self;
+    GObjectClass *parent_class;
+
+    self = MUD_TELNET_ECHO(object);
+
+    parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
+    parent_class->finalize(object);
+}
+
+static void
+mud_telnet_echo_set_property(GObject *object,
+                              guint prop_id,
+                              const GValue *value,
+                              GParamSpec *pspec)
+{
+    MudTelnetEcho *self;
+
+    self = MUD_TELNET_ECHO(object);
+
+    switch(prop_id)
+    {
+        case PROP_TELNET:
+            self->priv->telnet = MUD_TELNET(g_value_get_object(value));
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
+
+static void
+mud_telnet_echo_get_property(GObject *object,
+                              guint prop_id,
+                              GValue *value,
+                              GParamSpec *pspec)
+{
+    MudTelnetEcho *self;
+
+    self = MUD_TELNET_ECHO(object);
+
+    switch(prop_id)
+    {
+        case PROP_ENABLED:
+            g_value_set_boolean(value, self->priv->enabled);
+            break;
+
+        case PROP_HANDLES_OPTION:
+            g_value_set_int(value, self->priv->option);
+            break;
+
+        case PROP_TELNET:
+            g_value_take_object(value, self->priv->telnet);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
+
+/* Interface Implementation */
+void 
+mud_telnet_echo_enable(MudTelnetHandler *handler)
+{
+    MudTelnetEcho *self;
+    MudConnectionView *view;
+
+    self = MUD_TELNET_ECHO(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_ECHO(self));
+
+    self->priv->enabled = TRUE;
+
+    g_object_get(self->priv->telnet, "parent-view", &view, NULL);
+    g_object_set(view,
+                 "local-echo", FALSE,
+                 NULL);
+
+    g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "ECHO Enabled");
+}
+
+void
+mud_telnet_echo_disable(MudTelnetHandler *handler)
+{
+    MudTelnetEcho *self;
+    MudConnectionView *view;
+
+    self = MUD_TELNET_ECHO(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_ECHO(self));
+
+    self->priv->enabled = FALSE;
+
+    g_object_get(self->priv->telnet, "parent-view", &view, NULL);
+    g_object_set(view,
+                 "local-echo", TRUE,
+                 NULL);
+
+    g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "ECHO Disabled");
+}
+
+void
+mud_telnet_echo_handle_sub_neg(MudTelnetHandler *handler,
+                               guchar *buf,
+                               guint len)
+{
+    MudTelnetEcho *self;
+
+    self = MUD_TELNET_ECHO(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_ECHO(self));
+
+    /* There is no ECHO subreq.*/
+    return;
+}
+

Added: trunk/src/mud-telnet-echo.h
==============================================================================
--- (empty file)
+++ trunk/src/mud-telnet-echo.h	Fri Mar 13 23:41:46 2009
@@ -0,0 +1,57 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-echo.h
+ * Copyright (C) 2005-2009 Les Harris <lharris gnome org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef MUD_TELNET_ECHO_H
+#define MUD_TELNET_ECHO_H
+
+G_BEGIN_DECLS
+
+#include <glib.h>
+
+#define MUD_TYPE_TELNET_ECHO              (mud_telnet_echo_get_type ())
+#define MUD_TELNET_ECHO(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), MUD_TYPE_TELNET_ECHO, MudTelnetEcho))
+#define MUD_TELNET_ECHO_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), MUD_TYPE_TELNET_ECHO, MudTelnetEchoClass))
+#define MUD_IS_TELNET_ECHO(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), MUD_TYPE_TELNET_ECHO))
+#define MUD_IS_TELNET_ECHO_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MUD_TYPE_TELNET_ECHO))
+#define MUD_TELNET_ECHO_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), MUD_TYPE_TELNET_ECHO, MudTelnetEchoClass))
+#define MUD_TELNET_ECHO_GET_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUD_TYPE_TELNET_ECHO, MudTelnetEchoPrivate))
+
+typedef struct _MudTelnetEcho            MudTelnetEcho;
+typedef struct _MudTelnetEchoClass       MudTelnetEchoClass;
+typedef struct _MudTelnetEchoPrivate     MudTelnetEchoPrivate;
+
+struct _MudTelnetEchoClass
+{
+    GObjectClass parent_class;
+};
+
+struct _MudTelnetEcho
+{
+    GObject parent_instance;
+
+    /*< private >*/
+    MudTelnetEchoPrivate *priv;
+};
+
+GType mud_telnet_echo_get_type (void);
+
+G_END_DECLS
+
+#endif // MUD_TELNET_ECHO_H
+

Added: trunk/src/mud-telnet-eor.c
==============================================================================
--- (empty file)
+++ trunk/src/mud-telnet-eor.c	Fri Mar 13 23:41:46 2009
@@ -0,0 +1,266 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-eor.c
+ * Copyright (C) 2005-2009 Les Harris <lharris gnome org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+#include <glib/gi18n.h>
+
+#include "gnome-mud.h"
+#include "mud-telnet.h"
+#include "mud-telnet-handler-interface.h"
+#include "mud-telnet-eor.h"
+
+struct _MudTelnetEorPrivate
+{
+    /* Interface Properties */
+    MudTelnet *telnet;
+    gboolean enabled;
+    gint option;
+
+    /* Private Instance Members */
+};
+
+/* Property Identifiers */
+enum
+{
+    PROP_MUD_TELNET_EOR_0,
+    PROP_ENABLED,
+    PROP_HANDLES_OPTION,
+    PROP_TELNET
+};
+
+/* Class Functions */
+static void mud_telnet_eor_init (MudTelnetEor *self);
+static void mud_telnet_eor_class_init (MudTelnetEorClass *klass);
+static void mud_telnet_eor_interface_init(MudTelnetHandlerInterface *iface);
+static void mud_telnet_eor_finalize (GObject *object);
+static GObject *mud_telnet_eor_constructor (GType gtype,
+                                             guint n_properties,
+                                             GObjectConstructParam *properties);
+static void mud_telnet_eor_set_property(GObject *object,
+                                         guint prop_id,
+                                         const GValue *value,
+                                         GParamSpec *pspec);
+static void mud_telnet_eor_get_property(GObject *object,
+                                         guint prop_id,
+                                         GValue *value,
+                                         GParamSpec *pspec);
+
+/*Interface Implementation */
+void mud_telnet_eor_enable(MudTelnetHandler *self);
+void mud_telnet_eor_disable(MudTelnetHandler *self);
+void mud_telnet_eor_handle_sub_neg(MudTelnetHandler *self,
+                                    guchar *buf,
+                                    guint len);
+
+/* Create the Type. We implement MudTelnetHandlerInterface */
+G_DEFINE_TYPE_WITH_CODE(MudTelnetEor, mud_telnet_eor, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE (MUD_TELNET_HANDLER_TYPE,
+                                               mud_telnet_eor_interface_init));
+/* MudTelnetEor class functions */
+static void
+mud_telnet_eor_class_init (MudTelnetEorClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+    /* Override base object constructor */
+    object_class->constructor = mud_telnet_eor_constructor;
+
+    /* Override base object's finalize */
+    object_class->finalize = mud_telnet_eor_finalize;
+
+    /* Override base object property methods */
+    object_class->set_property = mud_telnet_eor_set_property;
+    object_class->get_property = mud_telnet_eor_get_property;
+
+    /* Add private data to class */
+    g_type_class_add_private(klass, sizeof(MudTelnetEorPrivate));
+
+    /* Override Implementation Properties */
+    g_object_class_override_property(object_class,
+                                     PROP_ENABLED,
+                                     "enabled");
+
+    g_object_class_override_property(object_class,
+                                     PROP_HANDLES_OPTION,
+                                     "handles-option");
+
+    g_object_class_override_property(object_class,
+                                     PROP_TELNET,
+                                     "telnet");
+}
+
+static void
+mud_telnet_eor_interface_init(MudTelnetHandlerInterface *iface)
+{
+    iface->Enable = mud_telnet_eor_enable;
+    iface->Disable = mud_telnet_eor_disable;
+    iface->HandleSubNeg = mud_telnet_eor_handle_sub_neg;
+}
+
+static void
+mud_telnet_eor_init (MudTelnetEor *self)
+{
+    /* Get our private data */
+    self->priv = MUD_TELNET_EOR_GET_PRIVATE(self);
+
+    /* Set the defaults */
+    self->priv->telnet = NULL;
+    self->priv->option = TELOPT_EOR;
+    self->priv->enabled = FALSE;
+}
+
+static GObject *
+mud_telnet_eor_constructor (GType gtype,
+                              guint n_properties,
+                              GObjectConstructParam *properties)
+{
+    MudTelnetEor *self;
+    GObject *obj;
+    MudTelnetEorClass *klass;
+    GObjectClass *parent_class;
+
+    /* Chain up to parent constructor */
+    klass = MUD_TELNET_EOR_CLASS( g_type_class_peek(MUD_TYPE_TELNET_EOR) );
+    parent_class = G_OBJECT_CLASS( g_type_class_peek_parent(klass) );
+    obj = parent_class->constructor(gtype, n_properties, properties);
+
+    self = MUD_TELNET_EOR(obj);
+
+    if(!self->priv->telnet)
+    {
+        g_printf("ERROR: Tried to instantiate MudTelnetEor without passing parent MudTelnet\n");
+        g_error("Tried to instantiate MudTelnetEor without passing parent MudTelnet");
+    }
+
+    return obj;
+}
+
+static void
+mud_telnet_eor_finalize (GObject *object)
+{
+    MudTelnetEor *self;
+    GObjectClass *parent_class;
+
+    self = MUD_TELNET_EOR(object);
+
+    parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
+    parent_class->finalize(object);
+}
+
+static void
+mud_telnet_eor_set_property(GObject *object,
+                              guint prop_id,
+                              const GValue *value,
+                              GParamSpec *pspec)
+{
+    MudTelnetEor *self;
+
+    self = MUD_TELNET_EOR(object);
+
+    switch(prop_id)
+    {
+        case PROP_TELNET:
+            self->priv->telnet = MUD_TELNET(g_value_get_object(value));
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
+
+static void
+mud_telnet_eor_get_property(GObject *object,
+                              guint prop_id,
+                              GValue *value,
+                              GParamSpec *pspec)
+{
+    MudTelnetEor *self;
+
+    self = MUD_TELNET_EOR(object);
+
+    switch(prop_id)
+    {
+        case PROP_ENABLED:
+            g_value_set_boolean(value, self->priv->enabled);
+            break;
+
+        case PROP_HANDLES_OPTION:
+            g_value_set_int(value, self->priv->option);
+            break;
+
+        case PROP_TELNET:
+            g_value_take_object(value, self->priv->telnet);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
+
+/* Interface Implementation */
+void 
+mud_telnet_eor_enable(MudTelnetHandler *handler)
+{
+    MudTelnetEor *self;
+
+    self = MUD_TELNET_EOR(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_EOR(self));
+
+    self->priv->enabled = TRUE;
+
+    g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "EOR Enabled");
+}
+
+void
+mud_telnet_eor_disable(MudTelnetHandler *handler)
+{
+    MudTelnetEor *self;
+
+    self = MUD_TELNET_EOR(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_EOR(self));
+
+    self->priv->enabled = FALSE;
+
+    g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "EOR Disabled");
+}
+
+void
+mud_telnet_eor_handle_sub_neg(MudTelnetHandler *handler,
+                               guchar *buf,
+                               guint len)
+{
+    MudTelnetEor *self;
+
+    self = MUD_TELNET_EOR(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_EOR(self));
+
+    /* There is no EOR subreq.*/
+    return;
+}
+

Added: trunk/src/mud-telnet-eor.h
==============================================================================
--- (empty file)
+++ trunk/src/mud-telnet-eor.h	Fri Mar 13 23:41:46 2009
@@ -0,0 +1,57 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-eor.h
+ * Copyright (C) 2005-2009 Les Harris <lharris gnome org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef MUD_TELNET_EOR_H
+#define MUD_TELNET_EOR_H
+
+G_BEGIN_DECLS
+
+#include <glib.h>
+
+#define MUD_TYPE_TELNET_EOR              (mud_telnet_eor_get_type ())
+#define MUD_TELNET_EOR(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), MUD_TYPE_TELNET_EOR, MudTelnetEor))
+#define MUD_TELNET_EOR_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), MUD_TYPE_TELNET_EOR, MudTelnetEorClass))
+#define MUD_IS_TELNET_EOR(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), MUD_TYPE_TELNET_EOR))
+#define MUD_IS_TELNET_EOR_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MUD_TYPE_TELNET_EOR))
+#define MUD_TELNET_EOR_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), MUD_TYPE_TELNET_EOR, MudTelnetEorClass))
+#define MUD_TELNET_EOR_GET_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUD_TYPE_TELNET_EOR, MudTelnetEorPrivate))
+
+typedef struct _MudTelnetEor            MudTelnetEor;
+typedef struct _MudTelnetEorClass       MudTelnetEorClass;
+typedef struct _MudTelnetEorPrivate     MudTelnetEorPrivate;
+
+struct _MudTelnetEorClass
+{
+    GObjectClass parent_class;
+};
+
+struct _MudTelnetEor
+{
+    GObject parent_instance;
+
+    /*< private >*/
+    MudTelnetEorPrivate *priv;
+};
+
+GType mud_telnet_eor_get_type (void);
+
+G_END_DECLS
+
+#endif // MUD_TELNET_EOR_H
+

Added: trunk/src/mud-telnet-handler-interface.c
==============================================================================
--- (empty file)
+++ trunk/src/mud-telnet-handler-interface.c	Fri Mar 13 23:41:46 2009
@@ -0,0 +1,119 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-handler-interface.c
+ * Copyright (C) 2005-2009 Les Harris <lharris gnome org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "mud-telnet-handler-interface.h"
+#include "mud-telnet.h"
+
+/* Interface Prototypes */
+static void mud_telnet_handler_base_init (gpointer klass);
+
+/* Define the Dummy Type */
+GType
+mud_telnet_handler_get_type (void)
+{
+    static GType mud_telnet_handler_iface_type = 0;
+
+    if(mud_telnet_handler_iface_type == 0)
+    {
+        static const GTypeInfo info =
+        {
+            sizeof (MudTelnetHandlerInterface),
+            mud_telnet_handler_base_init, /* base_init */
+            NULL                          /* base_finalize */
+        };
+
+        mud_telnet_handler_iface_type =
+            g_type_register_static(G_TYPE_INTERFACE,
+                                   "MudTelnetHandler",
+                                   &info,
+                                   0);
+    }
+
+    return mud_telnet_handler_iface_type;
+}
+
+/* Interface Functions */
+static void
+mud_telnet_handler_base_init(gpointer klass)
+{
+    static gboolean initialized = FALSE;
+
+    if(!initialized)
+    {
+        g_object_interface_install_property(klass,
+                                            g_param_spec_boolean(
+                                                "enabled",
+                                                "Enabled",
+                                                "Is handler enabled",
+                                                FALSE,
+                                                G_PARAM_READABLE));
+
+        g_object_interface_install_property(klass,
+                                            g_param_spec_int(
+                                                "handles-option",
+                                                "Handles Option",
+                                                "The TelOpt Number it handles",
+                                                -1, 50000,-1,
+                                                G_PARAM_READABLE));
+
+        g_object_interface_install_property(klass,
+                                            g_param_spec_object(
+                                                "telnet",
+                                                "Telnet",
+                                                "The parent telnet object",
+                                                MUD_TYPE_TELNET,
+                                                G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+        initialized = TRUE;
+    }
+}
+
+/* Interface Methods */
+void
+mud_telnet_handler_enable(MudTelnetHandler *self)
+{
+    g_return_if_fail(MUD_IS_TELNET_HANDLER(self));
+
+    MUD_TELNET_HANDLER_GET_INTERFACE (self)->Enable(self);
+}
+
+void
+mud_telnet_handler_disable(MudTelnetHandler *self)
+{
+    g_return_if_fail(MUD_IS_TELNET_HANDLER(self));
+
+    MUD_TELNET_HANDLER_GET_INTERFACE(self)->Disable(self);
+}
+
+void
+mud_telnet_handler_handle_sub_neg(MudTelnetHandler *self,
+                                  guchar *buf,
+                                  guint len)
+{
+    g_return_if_fail(MUD_IS_TELNET_HANDLER(self));
+
+    MUD_TELNET_HANDLER_GET_INTERFACE (self)->HandleSubNeg (self, buf, len);
+}
+

Added: trunk/src/mud-telnet-handler-interface.h
==============================================================================
--- (empty file)
+++ trunk/src/mud-telnet-handler-interface.h	Fri Mar 13 23:41:46 2009
@@ -0,0 +1,69 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-handler-interface.h
+ * Copyright (C) 2005-2009 Les Harris <lharris gnome org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef MUD_TELNET_HANDLER_INTERFACE_H
+#define MUD_TELNET_HANDLER_INTERFACE_H
+
+G_BEGIN_DECLS
+
+#define MUD_TELNET_HANDLER_TYPE                (mud_telnet_handler_get_type ())
+#define MUD_TELNET_HANDLER(obj)                (G_TYPE_CHECK_INSTANCE_CAST ((obj), MUD_TELNET_HANDLER_TYPE, MudTelnetHandler))
+#define MUD_IS_TELNET_HANDLER(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MUD_TELNET_HANDLER_TYPE))
+#define MUD_TELNET_HANDLER_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), MUD_TELNET_HANDLER_TYPE, MudTelnetHandlerInterface))
+
+typedef struct _MudTelnetHandler MudTelnetHandler; // Dummy object
+typedef struct _MudTelnetHandlerInterface MudTelnetHandlerInterface;
+
+#include <glib.h>
+#include "mud-telnet.h"
+
+struct _MudTelnetHandlerInterface
+{
+    GTypeInterface parent;
+
+    /* Interface Methods */
+    void (*Enable)      (MudTelnetHandler *self);
+    void (*Disable)     (MudTelnetHandler *self);
+    void (*HandleSubNeg)(MudTelnetHandler *self,
+                         guchar *buf,
+                         guint len);
+
+};
+
+GType mud_telnet_handler_get_type (void);
+
+/* Typedefs for Casting */
+typedef void (*MudTelnetHandlerEnableFunc)(MudTelnetHandler *self);
+typedef void (*MudTelnetHandlerDisableFunc)(MudTelnetHandler *self);
+typedef void (*MudTelnetHandlerHandleSubNeg)(MudTelnetHandler *self,
+                                            guchar *buf,
+                                            guint len);
+
+/* Interface Method Prototypes */
+
+void mud_telnet_handler_enable(MudTelnetHandler *self);
+void mud_telnet_handler_disable(MudTelnetHandler *self);
+void mud_telnet_handler_handle_sub_neg(MudTelnetHandler *self,
+                                       guchar *buf,
+                                       guint len);
+
+G_END_DECLS
+
+#endif // MUD_TELNET_HANDLER_INTERFACE_H
+

Modified: trunk/src/mud-telnet-mccp.c
==============================================================================
--- trunk/src/mud-telnet-mccp.c	(original)
+++ trunk/src/mud-telnet-mccp.c	Fri Mar 13 23:41:46 2009
@@ -21,68 +21,398 @@
 #  include "config.h"
 #endif
 
+#ifdef ENABLE_MCCP
+
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <zlib.h>
+#include <stdlib.h>
+#include <stdio.h>
 
 #include "gnome-mud.h"
 #include "mud-connection-view.h"
 #include "mud-telnet.h"
+#include "mud-telnet-handler-interface.h"
+#include "mud-telnet-mccp.h"
+
+struct _MudTelnetMccpPrivate
+{
+    /* Interface Properties */
+    MudTelnet *telnet;
+    gboolean enabled;
+    gint option;
+
+    /* Private Instance Members */
+    z_stream *compress_out;
+    guchar *compress_out_buf;
+    gboolean mccp_new;
+    gboolean mccp;
+};
+
+/* Property Identifiers */
+enum
+{
+    PROP_MUD_TELNET_MCCP_0,
+    PROP_ENABLED,
+    PROP_HANDLES_OPTION,
+    PROP_TELNET,
+    PROP_MCCP_NEW,
+    PROP_MCCP
+};
+
+/* Class Functions */
+static void mud_telnet_mccp_init (MudTelnetMccp *self);
+static void mud_telnet_mccp_class_init (MudTelnetMccpClass *klass);
+static void mud_telnet_mccp_interface_init(MudTelnetHandlerInterface *iface);
+static void mud_telnet_mccp_finalize (GObject *object);
+static GObject *mud_telnet_mccp_constructor (GType gtype,
+                                             guint n_properties,
+                                             GObjectConstructParam *properties);
+static void mud_telnet_mccp_set_property(GObject *object,
+                                         guint prop_id,
+                                         const GValue *value,
+                                         GParamSpec *pspec);
+static void mud_telnet_mccp_get_property(GObject *object,
+                                         guint prop_id,
+                                         GValue *value,
+                                         GParamSpec *pspec);
+
+/*Interface Implementation */
+void mud_telnet_mccp_enable(MudTelnetHandler *self);
+void mud_telnet_mccp_disable(MudTelnetHandler *self);
+void mud_telnet_mccp_handle_sub_neg(MudTelnetHandler *self,
+                                    guchar *buf,
+                                    guint len);
+
+/* Create the Type. We implement MudTelnetHandlerInterface */
+G_DEFINE_TYPE_WITH_CODE(MudTelnetMccp, mud_telnet_mccp, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE (MUD_TELNET_HANDLER_TYPE,
+                                               mud_telnet_mccp_interface_init));
+/* MudTelnetMccp class functions */
+static void
+mud_telnet_mccp_class_init (MudTelnetMccpClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+    /* Override base object constructor */
+    object_class->constructor = mud_telnet_mccp_constructor;
+
+    /* Override base object's finalize */
+    object_class->finalize = mud_telnet_mccp_finalize;
+
+    /* Override base object property methods */
+    object_class->set_property = mud_telnet_mccp_set_property;
+    object_class->get_property = mud_telnet_mccp_get_property;
+
+    /* Add private data to class */
+    g_type_class_add_private(klass, sizeof(MudTelnetMccpPrivate));
+
+    /* Override Implementation Properties */
+    g_object_class_override_property(object_class,
+                                     PROP_ENABLED,
+                                     "enabled");
+
+    g_object_class_override_property(object_class,
+                                     PROP_HANDLES_OPTION,
+                                     "handles-option");
+
+    g_object_class_override_property(object_class,
+                                     PROP_TELNET,
+                                     "telnet");
+
+    g_object_class_install_property(object_class,
+                            PROP_MCCP_NEW,
+                            g_param_spec_boolean("mccp-new",
+                                "MCCP New",
+                                "Is MCCP newly enabled.",
+                                FALSE,
+                                G_PARAM_READWRITE));
+
+    g_object_class_install_property(object_class,
+                            PROP_MCCP,
+                            g_param_spec_boolean("mccp-active",
+                                "MCCP Active",
+                                "Is MCCP Active.",
+                                FALSE,
+                                G_PARAM_READABLE));
+}
+
+static void
+mud_telnet_mccp_interface_init(MudTelnetHandlerInterface *iface)
+{
+    iface->Enable = mud_telnet_mccp_enable;
+    iface->Disable = mud_telnet_mccp_disable;
+    iface->HandleSubNeg = mud_telnet_mccp_handle_sub_neg;
+}
+
+static void
+mud_telnet_mccp_init (MudTelnetMccp *self)
+{
+    /* Get our private data */
+    self->priv = MUD_TELNET_MCCP_GET_PRIVATE(self);
+
+    /* Set the defaults */
+    self->priv->telnet = NULL;
+    self->priv->option = TELOPT_MCCP2;
+    self->priv->enabled = FALSE;
+
+    self->priv->mccp_new = TRUE;
+    self->priv->mccp = FALSE;
+}
+
+static GObject *
+mud_telnet_mccp_constructor (GType gtype,
+                              guint n_properties,
+                              GObjectConstructParam *properties)
+{
+    MudTelnetMccp *self;
+    GObject *obj;
+    MudTelnetMccpClass *klass;
+    GObjectClass *parent_class;
+
+    /* Chain up to parent constructor */
+    klass = MUD_TELNET_MCCP_CLASS( g_type_class_peek(MUD_TYPE_TELNET_MCCP) );
+    parent_class = G_OBJECT_CLASS( g_type_class_peek_parent(klass) );
+    obj = parent_class->constructor(gtype, n_properties, properties);
+
+    self = MUD_TELNET_MCCP(obj);
+
+    if(!self->priv->telnet)
+    {
+        g_printf("ERROR: Tried to instantiate MudTelnetMccp without passing parent MudTelnet\n");
+        g_error("Tried to instantiate MudTelnetMccp without passing parent MudTelnet");
+    }
+
+    return obj;
+}
+
+static void
+mud_telnet_mccp_finalize (GObject *object)
+{
+    MudTelnetMccp *self;
+    GObjectClass *parent_class;
+
+    self = MUD_TELNET_MCCP(object);
+
+    if(self->priv->compress_out != NULL)
+    {
+        inflateEnd(self->priv->compress_out);
+
+        g_free(self->priv->compress_out);
+        g_free(self->priv->compress_out_buf);
+    }
+
+    parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
+    parent_class->finalize(object);
+}
+
+static void
+mud_telnet_mccp_set_property(GObject *object,
+                              guint prop_id,
+                              const GValue *value,
+                              GParamSpec *pspec)
+{
+    MudTelnetMccp *self;
+
+    self = MUD_TELNET_MCCP(object);
+
+    switch(prop_id)
+    {
+        case PROP_TELNET:
+            self->priv->telnet = MUD_TELNET(g_value_get_object(value));
+            break;
+
+        case PROP_MCCP_NEW:
+            self->priv->mccp_new = g_value_get_boolean(value);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
+
+static void
+mud_telnet_mccp_get_property(GObject *object,
+                              guint prop_id,
+                              GValue *value,
+                              GParamSpec *pspec)
+{
+    MudTelnetMccp *self;
+
+    self = MUD_TELNET_MCCP(object);
+
+    switch(prop_id)
+    {
+        case PROP_ENABLED:
+            g_value_set_boolean(value, self->priv->enabled);
+            break;
 
+        case PROP_HANDLES_OPTION:
+            g_value_set_int(value, self->priv->option);
+            break;
+
+        case PROP_TELNET:
+            g_value_take_object(value, self->priv->telnet);
+            break;
+
+        case PROP_MCCP_NEW:
+            g_value_set_boolean(value, self->priv->mccp_new);
+            break;
+
+        case PROP_MCCP:
+            g_value_set_boolean(value, self->priv->mccp);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
+
+/* Interface Implementation */
+void 
+mud_telnet_mccp_enable(MudTelnetHandler *handler)
+{
+    MudTelnetMccp *self;
+
+    self = MUD_TELNET_MCCP(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_MCCP(self));
+
+    self->priv->enabled = TRUE;
+    self->priv->mccp = FALSE;
+
+    g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "MCCP Requested");
+}
+
+void
+mud_telnet_mccp_disable(MudTelnetHandler *handler)
+{
+    MudTelnetMccp *self;
+
+    self = MUD_TELNET_MCCP(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_MCCP(self));
+
+    self->priv->enabled = FALSE;
+    self->priv->mccp = FALSE;
+
+    if (self->priv->compress_out != NULL)
+    {
+        inflateEnd(self->priv->compress_out);
+
+        g_free(self->priv->compress_out);
+        g_free(self->priv->compress_out_buf);
+        
+        self->priv->compress_out = NULL;
+    }
+
+    g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "MCCP Disabled");
+}
+
+void
+mud_telnet_mccp_handle_sub_neg(MudTelnetHandler *handler,
+                               guchar *buf,
+                               guint len)
+{
+    MudTelnetMccp *self;
+
+    self = MUD_TELNET_MCCP(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_MCCP(self));
+
+    self->priv->mccp_new = TRUE;
+    self->priv->mccp = TRUE;
+
+    self->priv->compress_out = g_new0(z_stream, 1);
+    self->priv->compress_out_buf = g_new0(guchar, 4096);
+
+    self->priv->compress_out->next_out = self->priv->compress_out_buf;
+    self->priv->compress_out->avail_out = 4096;
+
+    if(inflateInit(self->priv->compress_out) != Z_OK)
+    {
+        MudConnectionView *view;
+        g_object_get(self->priv->telnet, "parent-view", &view, NULL);
+
+        g_printf("failed to init compression\n");
+        g_critical("Failed to initialize compression.");
+
+        g_free(self->priv->compress_out);
+        g_free(self->priv->compress_out_buf);
+
+        self->priv->compress_out = NULL;
+        self->priv->compress_out_buf = NULL;
+
+        mud_connection_view_disconnect(view);
+    }
+
+    g_log("Telnet", G_LOG_LEVEL_INFO, "MCCP Enabled.");
+}
+
+/* Public Methods */
 GString *
-mud_mccp_decompress(MudTelnet *telnet, guchar *buffer, guint32 length)
+mud_mccp_decompress(MudTelnetMccp *self, guchar *buffer, guint32 length)
 {
     GString *ret = NULL;
     gint zstatus;
     gint i;
+    MudConnectionView *view;
 
-    if(!telnet->compress_out)
+    g_return_if_fail(MUD_IS_TELNET_MCCP(self));
+
+    if(!self->priv->compress_out)
         return NULL;
 
-    telnet->compress_out->next_in = buffer;
-    telnet->compress_out->avail_in = length;
+    g_object_get(self->priv->telnet, "parent-view", &view, NULL);
+
+    self->priv->compress_out->next_in = buffer;
+    self->priv->compress_out->avail_in = length;
 
     ret = g_string_new(NULL);
 
     while(1)
     {
-        if(telnet->compress_out->avail_in < 1)
+        if(self->priv->compress_out->avail_in < 1)
             break;
 
-        telnet->compress_out->avail_out = 4096;
-        telnet->compress_out->next_out = telnet->compress_out_buf;
+        self->priv->compress_out->avail_out = 4096;
+        self->priv->compress_out->next_out = self->priv->compress_out_buf;
 
-        zstatus = inflate(telnet->compress_out, Z_SYNC_FLUSH);
+        /* Inflating */
+        zstatus = inflate(self->priv->compress_out, Z_SYNC_FLUSH);
 
         if(zstatus == Z_OK)
         {
             ret = g_string_append_len(ret, 
-                    telnet->compress_out_buf, 
-                    (4096 - telnet->compress_out->avail_out));
+                    self->priv->compress_out_buf, 
+                    (4096 - self->priv->compress_out->avail_out));
+
             continue;
         }
 
         if(zstatus == Z_STREAM_END)
         {
             ret = g_string_append_len(ret, 
-                    telnet->compress_out_buf, 
-                    (4096 - telnet->compress_out->avail_out));
+                    self->priv->compress_out_buf, 
+                    (4096 - self->priv->compress_out->avail_out));
 
-            if(telnet->compress_out->avail_in > 0)
+            if(self->priv->compress_out->avail_in > 0)
                 ret = g_string_append_len(ret, 
-                        telnet->compress_out->next_in, 
-                        telnet->compress_out->avail_in);
+                        self->priv->compress_out->next_in, 
+                        self->priv->compress_out->avail_in);
 
-            inflateEnd(telnet->compress_out);
+            inflateEnd(self->priv->compress_out);
 
-            g_free(telnet->compress_out);
-            g_free(telnet->compress_out_buf);
+            g_free(self->priv->compress_out);
+            g_free(self->priv->compress_out_buf);
 
-            telnet->compress_out = NULL;
-            telnet->compress_out_buf = NULL;
+            self->priv->compress_out = NULL;
+            self->priv->compress_out_buf = NULL;
 
-            telnet->mccp = FALSE;
-            telnet->mccp_new = TRUE;
+            self->priv->mccp = FALSE;
+            self->priv->mccp_new = TRUE;
 
             break;
         }
@@ -94,10 +424,13 @@
 
         if(zstatus == Z_DATA_ERROR)
         {
-            mud_connection_view_add_text(telnet->parent,
+            mud_connection_view_add_text(view,
                     _("\nMCCP data corrupted. Aborting connection.\n"),
                     Error);
-            mud_connection_view_disconnect (telnet->parent);
+            mud_connection_view_disconnect (view);
+
+            g_printf("Z DATA ERROR!\n");
+
             return NULL; 
         }
     }
@@ -105,3 +438,5 @@
     return ret;
 }
 
+#endif // ENABLE_MCCP
+

Modified: trunk/src/mud-telnet-mccp.h
==============================================================================
--- trunk/src/mud-telnet-mccp.h	(original)
+++ trunk/src/mud-telnet-mccp.h	Fri Mar 13 23:41:46 2009
@@ -20,10 +20,47 @@
 #ifndef MUD_TELNET_MCCP_H
 #define MUD_TELNET_MCCP_H
 
+#ifdef ENABLE_MCCP
+
+G_BEGIN_DECLS
+
 #include <glib.h>
-#include "mud-telnet.h"
+#include <zlib.h>
+
+#define MUD_TYPE_TELNET_MCCP              (mud_telnet_mccp_get_type ())
+#define MUD_TELNET_MCCP(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), MUD_TYPE_TELNET_MCCP, MudTelnetMccp))
+#define MUD_TELNET_MCCP_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), MUD_TYPE_TELNET_MCCP, MudTelnetMccpClass))
+#define MUD_IS_TELNET_MCCP(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), MUD_TYPE_TELNET_MCCP))
+#define MUD_IS_TELNET_MCCP_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MUD_TYPE_TELNET_MCCP))
+#define MUD_TELNET_MCCP_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), MUD_TYPE_TELNET_MCCP, MudTelnetMccpClass))
+#define MUD_TELNET_MCCP_GET_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUD_TYPE_TELNET_MCCP, MudTelnetMccpPrivate))
+
+typedef struct _MudTelnetMccp            MudTelnetMccp;
+typedef struct _MudTelnetMccpClass       MudTelnetMccpClass;
+typedef struct _MudTelnetMccpPrivate     MudTelnetMccpPrivate;
+
+typedef struct z_stream_s z_stream;
+
+struct _MudTelnetMccpClass
+{
+    GObjectClass parent_class;
+};
+
+struct _MudTelnetMccp
+{
+    GObject parent_instance;
+
+    /*< private >*/
+    MudTelnetMccpPrivate *priv;
+};
+
+GType mud_telnet_mccp_get_type (void);
+
+GString *mud_mccp_decompress(MudTelnetMccp *self, guchar *buffer, guint32 length);
+
+G_END_DECLS
 
-GString *mud_mccp_decompress(MudTelnet *telnet, guchar *buffer, guint32 length);
+#endif // ENABLE_MCCP
 
 #endif // MUD_TELNET_MCCP_H
 

Modified: trunk/src/mud-telnet-msp.c
==============================================================================
--- trunk/src/mud-telnet-msp.c	(original)
+++ trunk/src/mud-telnet-msp.c	Fri Mar 13 23:41:46 2009
@@ -31,158 +31,474 @@
 
 #include "gnome-mud.h"
 #include "mud-telnet.h"
+#include "mud-telnet-handler-interface.h"
 #include "mud-telnet-msp.h"
 
-static void mud_telnet_msp_parser_reset(MudTelnet *telnet);
-static void mud_telnet_msp_parser_args(MudTelnet *telnet);
+struct _MudTelnetMspPrivate
+{
+    /* Interface Properties */
+    MudTelnet *telnet;
+    gboolean enabled;
+    gint option;
+
+    /* Private Instance Members */
+    MudMSPParser msp_parser;
+    MudMSPTypes msp_type;
+    MudMSPSound sound[2];
+    gchar *base_url;
+    GString *prev_buffer;
+};
+
+/* Property Identifiers */
+enum
+{
+    PROP_MUD_TELNET_MSP_0,
+    PROP_ENABLED,
+    PROP_HANDLES_OPTION,
+    PROP_TELNET
+};
+
+/* Class Functions */
+static void mud_telnet_msp_init (MudTelnetMsp *self);
+static void mud_telnet_msp_class_init (MudTelnetMspClass *klass);
+static void mud_telnet_msp_interface_init(MudTelnetHandlerInterface *iface);
+static void mud_telnet_msp_finalize (GObject *object);
+static GObject *mud_telnet_msp_constructor (GType gtype,
+                                             guint n_properties,
+                                             GObjectConstructParam *properties);
+static void mud_telnet_msp_set_property(GObject *object,
+                                         guint prop_id,
+                                         const GValue *value,
+                                         GParamSpec *pspec);
+static void mud_telnet_msp_get_property(GObject *object,
+                                         guint prop_id,
+                                         GValue *value,
+                                         GParamSpec *pspec);
+
+/*Interface Implementation */
+void mud_telnet_msp_enable(MudTelnetHandler *self);
+void mud_telnet_msp_disable(MudTelnetHandler *self);
+void mud_telnet_msp_handle_sub_neg(MudTelnetHandler *self,
+                                    guchar *buf,
+                                    guint len);
+
+
+/* Create the Type. We implement MudTelnetHandlerInterface */
+G_DEFINE_TYPE_WITH_CODE(MudTelnetMsp, mud_telnet_msp, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE (MUD_TELNET_HANDLER_TYPE,
+                                               mud_telnet_msp_interface_init));
+
+/* Private Methods */
+static void mud_telnet_msp_parser_reset(MudTelnetMsp *self);
+static void mud_telnet_msp_parser_args(MudTelnetMsp *self);
 static void mud_telnet_msp_command_free(MudMSPCommand *command);
 static gboolean mud_telnet_msp_parser_is_param_char(gchar c);
 static gboolean mud_telnet_msp_parser_switch_on_param_char(gint *state,
         gchar *buf,
         gint index,
         gint len);
-static void mud_telnet_msp_process_command(MudTelnet *telnet,
-        MudMSPCommand *command);
-static void mud_telnet_msp_start_playing(MudTelnet *telnet, MudMSPTypes type);
-static gboolean mud_telnet_msp_get_files(MudTelnet *telnet, MudMSPTypes type);
+static void mud_telnet_msp_process_command(MudTelnetMsp *self,
+                                           MudMSPCommand *command);
+static void mud_telnet_msp_start_playing(MudTelnetMsp *self, MudMSPTypes type);
+static gboolean mud_telnet_msp_get_files(MudTelnetMsp *self, MudMSPTypes type);
 static gboolean mud_telnet_msp_sound_bus_call (GstBus *bus,
-        GstMessage *msg, gpointer data);
+                                               GstMessage *msg,
+                                               gpointer data);
 static gboolean mud_telnet_msp_music_bus_call (GstBus *bus,
-        GstMessage *msg, gpointer data);
+                                               GstMessage *msg,
+                                               gpointer data);
+
+/* MudTelnetMsp class functions */
+static void
+mud_telnet_msp_class_init (MudTelnetMspClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+    /* Override base object constructor */
+    object_class->constructor = mud_telnet_msp_constructor;
+
+    /* Override base object's finalize */
+    object_class->finalize = mud_telnet_msp_finalize;
+
+    /* Override base object property methods */
+    object_class->set_property = mud_telnet_msp_set_property;
+    object_class->get_property = mud_telnet_msp_get_property;
+
+    /* Add private data to class */
+    g_type_class_add_private(klass, sizeof(MudTelnetMspPrivate));
+
+    /* Override Implementation Properties */
+    g_object_class_override_property(object_class,
+                                     PROP_ENABLED,
+                                     "enabled");
+
+    g_object_class_override_property(object_class,
+                                     PROP_HANDLES_OPTION,
+                                     "handles-option");
+
+    g_object_class_override_property(object_class,
+                                     PROP_TELNET,
+                                     "telnet");
+}
+
+static void
+mud_telnet_msp_interface_init(MudTelnetHandlerInterface *iface)
+{
+    iface->Enable = mud_telnet_msp_enable;
+    iface->Disable = mud_telnet_msp_disable;
+    iface->HandleSubNeg = mud_telnet_msp_handle_sub_neg;
+}
+
+static void
+mud_telnet_msp_init (MudTelnetMsp *self)
+{
+    /* Get our private data */
+    self->priv = MUD_TELNET_MSP_GET_PRIVATE(self);
+
+    /* Set the defaults */
+    self->priv->telnet = NULL;
+    self->priv->option = TELOPT_MSP;
+    self->priv->enabled = FALSE;
+
+    self->priv->sound[0].files = NULL;
+    self->priv->sound[0].current_command = NULL;
+    self->priv->sound[0].playing = FALSE;
+    self->priv->sound[0].files_len = 0;
+
+    self->priv->sound[1].files = NULL;
+    self->priv->sound[1].current_command = NULL;
+    self->priv->sound[1].playing = FALSE;
+    self->priv->sound[1].files_len = 0;
+
+    self->priv->prev_buffer = NULL;
+    self->priv->base_url = NULL;
+}
+
+static GObject *
+mud_telnet_msp_constructor (GType gtype,
+                              guint n_properties,
+                              GObjectConstructParam *properties)
+{
+    MudTelnetMsp *self;
+    GObject *obj;
+    MudTelnetMspClass *klass;
+    GObjectClass *parent_class;
+
+    /* Chain up to parent constructor */
+    klass = MUD_TELNET_MSP_CLASS( g_type_class_peek(MUD_TYPE_TELNET_MSP) );
+    parent_class = G_OBJECT_CLASS( g_type_class_peek_parent(klass) );
+    obj = parent_class->constructor(gtype, n_properties, properties);
+
+    self = MUD_TELNET_MSP(obj);
+
+    if(!self->priv->telnet)
+    {
+        g_printf("ERROR: Tried to instantiate MudTelnetMsp without passing parent MudTelnet\n");
+        g_error("Tried to instantiate MudTelnetMsp without passing parent MudTelnet");
+    }
+
+    self->priv->msp_parser.enabled = FALSE;
+    self->priv->msp_parser.state = MSP_STATE_TEXT;
+    self->priv->msp_parser.lex_pos_start = 0;
+    self->priv->msp_parser.lex_pos_end = 0;
+    self->priv->msp_parser.output = NULL;
+    self->priv->msp_parser.arg_buffer = NULL;
+
+    return obj;
+}
+
+static void
+mud_telnet_msp_finalize (GObject *object)
+{
+    MudTelnetMsp *self;
+    GObjectClass *parent_class;
+
+    self = MUD_TELNET_MSP(object);
+
+    mud_telnet_msp_stop_playing(self, MSP_TYPE_SOUND);
+    mud_telnet_msp_stop_playing(self, MSP_TYPE_MUSIC);
+    
+    if(self->priv->prev_buffer)
+        g_string_free(self->priv->prev_buffer, TRUE);
+    if(self->priv->base_url)
+        g_free(self->priv->base_url);
+
+    parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
+    parent_class->finalize(object);
+}
+
+static void
+mud_telnet_msp_set_property(GObject *object,
+                              guint prop_id,
+                              const GValue *value,
+                              GParamSpec *pspec)
+{
+    MudTelnetMsp *self;
+
+    self = MUD_TELNET_MSP(object);
+
+    switch(prop_id)
+    {
+        case PROP_TELNET:
+            self->priv->telnet = MUD_TELNET(g_value_get_object(value));
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
+
+static void
+mud_telnet_msp_get_property(GObject *object,
+                              guint prop_id,
+                              GValue *value,
+                              GParamSpec *pspec)
+{
+    MudTelnetMsp *self;
+
+    self = MUD_TELNET_MSP(object);
+
+    switch(prop_id)
+    {
+        case PROP_ENABLED:
+            g_value_set_boolean(value, self->priv->enabled);
+            break;
+
+        case PROP_HANDLES_OPTION:
+            g_value_set_int(value, self->priv->option);
+            break;
+
+        case PROP_TELNET:
+            g_value_take_object(value, self->priv->telnet);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
+
+/* Interface Implementation */
+void 
+mud_telnet_msp_enable(MudTelnetHandler *handler)
+{
+    MudTelnetMsp *self;
+
+    self = MUD_TELNET_MSP(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_MSP(self));
+
+    self->priv->enabled = TRUE;
+
+    if(self->priv->msp_parser.output)
+        g_string_free(self->priv->msp_parser.output, TRUE);
+
+    if(self->priv->msp_parser.arg_buffer)
+        g_string_free(self->priv->msp_parser.arg_buffer, TRUE);
+
+    self->priv->msp_parser.enabled = TRUE;
+    self->priv->msp_parser.state = MSP_STATE_TEXT;
+    self->priv->msp_parser.lex_pos_start = 0;
+    self->priv->msp_parser.lex_pos_end = 0;
+    self->priv->msp_parser.output = g_string_new(NULL);
+    self->priv->msp_parser.arg_buffer = NULL;
+
+    g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "MSP Enabled");
+}
+
+void
+mud_telnet_msp_disable(MudTelnetHandler *handler)
+{
+    MudTelnetMsp *self;
+
+    self = MUD_TELNET_MSP(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_MSP(self));
+
+    self->priv->enabled = FALSE;
+
+    mud_telnet_msp_stop_playing(self, MSP_TYPE_SOUND);
+    mud_telnet_msp_stop_playing(self, MSP_TYPE_MUSIC);
+    
+    if(self->priv->prev_buffer)
+        g_string_free(self->priv->prev_buffer, TRUE);
+    if(self->priv->base_url)
+        g_free(self->priv->base_url);
+    if(self->priv->msp_parser.output)
+        g_string_free(self->priv->msp_parser.output, TRUE);
+    if(self->priv->msp_parser.arg_buffer)
+        g_string_free(self->priv->msp_parser.arg_buffer, TRUE);
+
+    self->priv->msp_parser.enabled = FALSE;
+
+    g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "MSP Disabled");
+}
+
+void
+mud_telnet_msp_handle_sub_neg(MudTelnetHandler *handler,
+                              guchar *buf,
+                              guint len)
+{
+    MudTelnetMsp *self;
+
+    self = MUD_TELNET_MSP(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_MSP(self));
+
+    /* There is no MSP subreq.*/
+    return;
+}
+
+/* Public Methods */
+void
+mud_telnet_msp_parser_clear(MudTelnetMsp *self)
+{
+    g_return_if_fail(MUD_IS_TELNET_MSP(self));
+
+    if(self->priv->msp_parser.output)
+	g_string_free(self->priv->msp_parser.output, TRUE);
+
+    self->priv->msp_parser.lex_pos_start = 0;
+    self->priv->msp_parser.lex_pos_end = 0;
+    self->priv->msp_parser.output = g_string_new(NULL);
+}
 
 GString *
-mud_telnet_msp_parse(MudTelnet *telnet, GString *buf, gint *len)
+mud_telnet_msp_parse(MudTelnetMsp *self, GString *buf, gint *len)
 {
     gint count;
     GString *ret = NULL;
     gchar *temp;
 
-    mud_telnet_msp_parser_reset(telnet);
+    g_return_if_fail(MUD_IS_TELNET_MSP(self));
 
-    if(telnet->prev_buffer)
+    mud_telnet_msp_parser_reset(self);
+
+    if(self->priv->prev_buffer)
     {
-        buf = g_string_prepend(buf, telnet->prev_buffer->str);
-        g_string_free(telnet->prev_buffer, TRUE);
-        telnet->prev_buffer = NULL;
+        buf = g_string_prepend(buf, self->priv->prev_buffer->str);
+        g_string_free(self->priv->prev_buffer, TRUE);
+        self->priv->prev_buffer = NULL;
     }
 
-    while(telnet->msp_parser.lex_pos_start < *len)
+    while(self->priv->msp_parser.lex_pos_start < *len)
     {
-        switch(telnet->msp_parser.state)
+        switch(self->priv->msp_parser.state)
         {
             case MSP_STATE_TEXT:
-                if(buf->str[telnet->msp_parser.lex_pos_start] == '!')
-                    telnet->msp_parser.state = MSP_STATE_POSSIBLE_COMMAND;
+                if(buf->str[self->priv->msp_parser.lex_pos_start] == '!')
+                    self->priv->msp_parser.state = MSP_STATE_POSSIBLE_COMMAND;
                 else
                 {
-                    telnet->msp_parser.output = 
-                        g_string_append_c(telnet->msp_parser.output,
-                                buf->str[telnet->msp_parser.lex_pos_start++]);
+                    self->priv->msp_parser.output = 
+                        g_string_append_c(self->priv->msp_parser.output,
+                                buf->str[self->priv->msp_parser.lex_pos_start++]);
                 }
                 break;
 
             case MSP_STATE_POSSIBLE_COMMAND:
-                if(telnet->msp_parser.lex_pos_start + 1 == *len)
+                if(self->priv->msp_parser.lex_pos_start + 1 == *len)
                     continue;
-                else if(buf->str[telnet->msp_parser.lex_pos_start + 1] != '!')
+                else if(buf->str[self->priv->msp_parser.lex_pos_start + 1] != '!')
                 {
-                    telnet->msp_parser.output = 
-                        g_string_append_c(telnet->msp_parser.output,
-                                buf->str[telnet->msp_parser.lex_pos_start++]);
-                    telnet->msp_parser.state = MSP_STATE_TEXT;
+                    self->priv->msp_parser.output = 
+                        g_string_append_c(self->priv->msp_parser.output,
+                                buf->str[self->priv->msp_parser.lex_pos_start++]);
+                    self->priv->msp_parser.state = MSP_STATE_TEXT;
                     continue;
                 }
 
-                telnet->msp_parser.state = MSP_STATE_COMMAND;
+                self->priv->msp_parser.state = MSP_STATE_COMMAND;
                 break;
 
             case MSP_STATE_COMMAND:
-                if(telnet->msp_parser.lex_pos_start + 8 >= *len)
+                if(self->priv->msp_parser.lex_pos_start + 8 >= *len)
                 {
-                    telnet->prev_buffer = g_string_new(NULL);
+                    self->priv->prev_buffer = g_string_new(NULL);
 
-                    count = telnet->msp_parser.lex_pos_start;
+                    count = self->priv->msp_parser.lex_pos_start;
 
                     while(count != buf->len)
-                        telnet->prev_buffer = 
-                            g_string_append_c(telnet->prev_buffer, buf->str[count++]);
+                        self->priv->prev_buffer = 
+                            g_string_append_c(self->priv->prev_buffer, buf->str[count++]);
 
-                    telnet->msp_parser.lex_pos_start += count;
+                    self->priv->msp_parser.lex_pos_start += count;
                     continue;
                 }
 
-                if(buf->str[telnet->msp_parser.lex_pos_start + 2] == 'S' &&
-                        buf->str[telnet->msp_parser.lex_pos_start + 3] == 'O' &&
-                        buf->str[telnet->msp_parser.lex_pos_start + 4] == 'U' &&
-                        buf->str[telnet->msp_parser.lex_pos_start + 5] == 'N' &&
-                        buf->str[telnet->msp_parser.lex_pos_start + 6] == 'D')
-                    telnet->msp_type = MSP_TYPE_SOUND;
-                else if(buf->str[telnet->msp_parser.lex_pos_start + 2] == 'M' &&
-                        buf->str[telnet->msp_parser.lex_pos_start + 3] == 'U' &&
-                        buf->str[telnet->msp_parser.lex_pos_start + 4] == 'S' &&
-                        buf->str[telnet->msp_parser.lex_pos_start + 5] == 'I' &&
-                        buf->str[telnet->msp_parser.lex_pos_start + 6] == 'C')
-                    telnet->msp_type = MSP_TYPE_MUSIC;
+                if(buf->str[self->priv->msp_parser.lex_pos_start + 2] == 'S' &&
+                        buf->str[self->priv->msp_parser.lex_pos_start + 3] == 'O' &&
+                        buf->str[self->priv->msp_parser.lex_pos_start + 4] == 'U' &&
+                        buf->str[self->priv->msp_parser.lex_pos_start + 5] == 'N' &&
+                        buf->str[self->priv->msp_parser.lex_pos_start + 6] == 'D')
+                    self->priv->msp_type = MSP_TYPE_SOUND;
+                else if(buf->str[self->priv->msp_parser.lex_pos_start + 2] == 'M' &&
+                        buf->str[self->priv->msp_parser.lex_pos_start + 3] == 'U' &&
+                        buf->str[self->priv->msp_parser.lex_pos_start + 4] == 'S' &&
+                        buf->str[self->priv->msp_parser.lex_pos_start + 5] == 'I' &&
+                        buf->str[self->priv->msp_parser.lex_pos_start + 6] == 'C')
+                    self->priv->msp_type = MSP_TYPE_MUSIC;
                 else
                 {
                     /* Not an msp command, bail out. */
-                    telnet->msp_parser.output = 
-                        g_string_append_c(telnet->msp_parser.output,
-                                buf->str[telnet->msp_parser.lex_pos_start++]);
-                    telnet->msp_parser.output = 
-                        g_string_append_c(telnet->msp_parser.output,
-                                buf->str[telnet->msp_parser.lex_pos_start++]);
+                    self->priv->msp_parser.output = 
+                        g_string_append_c(self->priv->msp_parser.output,
+                                buf->str[self->priv->msp_parser.lex_pos_start++]);
+                    self->priv->msp_parser.output = 
+                        g_string_append_c(self->priv->msp_parser.output,
+                                buf->str[self->priv->msp_parser.lex_pos_start++]);
 
-                    telnet->msp_parser.state = MSP_STATE_TEXT;
+                    self->priv->msp_parser.state = MSP_STATE_TEXT;
                     continue;
                 }
 
                 // Skip leading (
-                telnet->msp_parser.lex_pos_start += 8;
-                telnet->msp_parser.state = MSP_STATE_GET_ARGS;
+                self->priv->msp_parser.lex_pos_start += 8;
+                self->priv->msp_parser.state = MSP_STATE_GET_ARGS;
                 continue;
                 break;
 
             case MSP_STATE_GET_ARGS:
-                telnet->msp_parser.lex_pos_end = telnet->msp_parser.lex_pos_start;
+                self->priv->msp_parser.lex_pos_end = self->priv->msp_parser.lex_pos_start;
 
-                if(telnet->msp_parser.arg_buffer == NULL)
-                    telnet->msp_parser.arg_buffer = g_string_new(NULL);
+                if(self->priv->msp_parser.arg_buffer == NULL)
+                    self->priv->msp_parser.arg_buffer = g_string_new(NULL);
 
-                while(telnet->msp_parser.lex_pos_end < *len &&
-                        buf->str[telnet->msp_parser.lex_pos_end] != ')')
-                    telnet->msp_parser.arg_buffer = 
-                        g_string_append_c(telnet->msp_parser.arg_buffer,
-                                buf->str[telnet->msp_parser.lex_pos_end++]);
+                while(self->priv->msp_parser.lex_pos_end < *len &&
+                        buf->str[self->priv->msp_parser.lex_pos_end] != ')')
+                    self->priv->msp_parser.arg_buffer = 
+                        g_string_append_c(self->priv->msp_parser.arg_buffer,
+                                buf->str[self->priv->msp_parser.lex_pos_end++]);
 
-                if(telnet->msp_parser.lex_pos_end >= *len &&
-                        buf->str[telnet->msp_parser.lex_pos_end - 1] != ')')
+                if(self->priv->msp_parser.lex_pos_end >= *len &&
+                        buf->str[self->priv->msp_parser.lex_pos_end - 1] != ')')
                 {
-                    telnet->msp_parser.lex_pos_start =
-                        telnet->msp_parser.lex_pos_end;
+                    self->priv->msp_parser.lex_pos_start =
+                        self->priv->msp_parser.lex_pos_end;
                     continue;
                 }
 
-                telnet->msp_parser.state = MSP_STATE_PARSE_ARGS;
+                self->priv->msp_parser.state = MSP_STATE_PARSE_ARGS;
 
                 break;
 
             case MSP_STATE_PARSE_ARGS:
-                mud_telnet_msp_parser_args(telnet);
+                mud_telnet_msp_parser_args(self);
 
-                g_string_free(telnet->msp_parser.arg_buffer, TRUE);
-                telnet->msp_parser.arg_buffer = NULL;
-                telnet->msp_parser.lex_pos_start =
-                    telnet->msp_parser.lex_pos_end + 1;
-                telnet->msp_parser.state = MSP_STATE_TEXT;
+                g_string_free(self->priv->msp_parser.arg_buffer, TRUE);
+                self->priv->msp_parser.arg_buffer = NULL;
+                self->priv->msp_parser.lex_pos_start =
+                    self->priv->msp_parser.lex_pos_end + 1;
+                self->priv->msp_parser.state = MSP_STATE_TEXT;
                 break;
         }
     }
 
-    if(telnet->msp_parser.state == MSP_STATE_TEXT)
+    if(self->priv->msp_parser.state == MSP_STATE_TEXT)
     {
-        ret = g_string_new(g_strdup(telnet->msp_parser.output->str));
-        *len = telnet->msp_parser.output->len;
+        ret = g_string_new(g_strdup(self->priv->msp_parser.output->str));
+        *len = self->priv->msp_parser.output->len;
     }
 
     g_string_free(buf, TRUE);
@@ -192,28 +508,6 @@
 }
 
 void
-mud_telnet_msp_init(MudTelnet *telnet)
-{
-    telnet->msp_parser.enabled = TRUE;
-    telnet->msp_parser.state = MSP_STATE_TEXT;
-    telnet->msp_parser.lex_pos_start = 0;
-    telnet->msp_parser.lex_pos_end = 0;
-    telnet->msp_parser.output = g_string_new(NULL);
-    telnet->msp_parser.arg_buffer = NULL;
-}
-
-void
-mud_telnet_msp_parser_clear(MudTelnet *telnet)
-{
-    if(telnet->msp_parser.output)
-	g_string_free(telnet->msp_parser.output, TRUE);
-
-    telnet->msp_parser.lex_pos_start = 0;
-    telnet->msp_parser.lex_pos_end = 0;
-    telnet->msp_parser.output = g_string_new(NULL);
-}
-
-void
 mud_telnet_msp_download_item_free(MudMSPDownloadItem *item)
 {
     if(!item)
@@ -228,32 +522,63 @@
     g_free(item);
 }
 
-static void
-mud_telnet_msp_parser_reset(MudTelnet *telnet)
+void
+mud_telnet_msp_stop_playing(MudTelnetMsp *self, MudMSPTypes type)
 {
-    telnet->msp_parser.lex_pos_start = 0;
-    telnet->msp_parser.lex_pos_end = 0;
+    g_return_if_fail(MUD_IS_TELNET_MSP(self));
+
+    self->priv->sound[type].playing = FALSE;
+
+    if(GST_IS_ELEMENT(self->priv->sound[type].play))
+    {
+        gst_element_set_state (self->priv->sound[type].play, GST_STATE_NULL);
+        gst_object_unref (GST_OBJECT (self->priv->sound[type].play));
+    }
+
+    if(self->priv->sound[type].files)
+    {
+        g_strfreev(self->priv->sound[type].files);
+        self->priv->sound[type].files = NULL;
+    }
+
+    self->priv->sound[type].files_len = 0;
+
+    mud_telnet_msp_command_free(self->priv->sound[type].current_command);
+    self->priv->sound[type].current_command = NULL;
 }
 
-#define ARG_STATE_FILE 0
-#define ARG_STATE_V 1
-#define ARG_STATE_L 2
-#define ARG_STATE_C 3
-#define ARG_STATE_T 4
-#define ARG_STATE_U 5
-#define ARG_STATE_P 6
+/* Private Methods */
+static void
+mud_telnet_msp_parser_reset(MudTelnetMsp *self)
+{
+    g_return_if_fail(MUD_IS_TELNET_MSP(self));
+
+    self->priv->msp_parser.lex_pos_start = 0;
+    self->priv->msp_parser.lex_pos_end = 0;
+}
 
 static void
-mud_telnet_msp_parser_args(MudTelnet *telnet)
+mud_telnet_msp_parser_args(MudTelnetMsp *self)
 {
     gint state = ARG_STATE_FILE;
     gint i;
-    GString *buffer = g_string_new(NULL);
-    gchar *args = g_strdup(telnet->msp_parser.arg_buffer->str);
-    gint len = strlen(args);
-    MudMSPCommand *command = g_new0(MudMSPCommand, 1);
+    GString *buffer;
+    gchar *args;
+    gint len;
+    MudMSPCommand *command;
+    MudConnectionView *view;
+
+    g_return_if_fail(MUD_IS_TELNET_MSP(self));
 
-    command->type = telnet->msp_type;
+    buffer = g_string_new(NULL);
+    args =  g_strdup(self->priv->msp_parser.arg_buffer->str);
+    len = strlen(args);;
+
+    command = g_new0(MudMSPCommand, 1);
+
+    g_object_get(self->priv->telnet, "parent-view", &view, NULL);
+
+    command->type = self->priv->msp_type;
     command->fName = NULL;
     command->V = NULL;
     command->L = NULL;
@@ -262,7 +587,7 @@
     command->U = NULL;
     command->P = NULL;
 
-    command->mud_name = g_strdup(telnet->mud_name);
+    g_object_get(view, "mud-name", &command->mud_name, NULL);
     command->sfx_type = NULL;
 
     /* Load defaults */
@@ -271,7 +596,7 @@
     command->initial_repeat_count = 1;
     command->current_repeat_count = 1;
     command->loop = FALSE;
-    command->cont = (telnet->msp_type == MSP_TYPE_MUSIC);
+    command->cont = (self->priv->msp_type == MSP_TYPE_MUSIC);
 
     for(i = 0; i < len; ++i)
     {
@@ -428,7 +753,7 @@
             command->loop = TRUE;
     }
 
-    mud_telnet_msp_process_command(telnet, command);
+    mud_telnet_msp_process_command(self, command);
 
     g_free(args);
     g_string_free(buffer, TRUE);
@@ -525,8 +850,10 @@
 }
 
 static void
-mud_telnet_msp_process_command(MudTelnet *telnet, MudMSPCommand *command)
+mud_telnet_msp_process_command(MudTelnetMsp *self, MudMSPCommand *command)
 {
+    g_return_if_fail(MUD_IS_TELNET_MSP(self));
+
     g_log("Telnet", G_LOG_LEVEL_INFO, "MSP Command Parse Results");
     g_log("Telnet", G_LOG_LEVEL_INFO, 
             "Type: %s", (command->type == MSP_TYPE_SOUND) ? "Sound" :
@@ -557,111 +884,90 @@
     {
         if(command->U)
         {
-            if(telnet->base_url)
-                g_free(telnet->base_url);
+            if(self->priv->base_url)
+                g_free(self->priv->base_url);
 
-            telnet->base_url = g_strdup(command->U);
+            self->priv->base_url = g_strdup(command->U);
         }
         else
-            mud_telnet_msp_stop_playing(telnet, command->type);
+            mud_telnet_msp_stop_playing(self, command->type);
 
         mud_telnet_msp_command_free(command);
 
         return;
     }
 
-    if(telnet->sound[command->type].current_command)
+    if(self->priv->sound[command->type].current_command)
     {
-        if(telnet->sound[command->type].playing)
+        if(self->priv->sound[command->type].playing)
         {
             if(command->priority >
-                    telnet->sound[command->type].current_command->priority)
+                   self->priv->sound[command->type].current_command->priority)
             {
-                mud_telnet_msp_stop_playing(telnet, command->type);
-                telnet->sound[command->type].current_command = command;
-                mud_telnet_msp_start_playing(telnet, command->type);
+                mud_telnet_msp_stop_playing(self, command->type);
+                self->priv->sound[command->type].current_command = command;
+                mud_telnet_msp_start_playing(self, command->type);
             }
             else
                 mud_telnet_msp_command_free(command);
         }
         else
         {
-            mud_telnet_msp_stop_playing(telnet, command->type);
-            telnet->sound[command->type].current_command = command;
-            mud_telnet_msp_start_playing(telnet, command->type);
+            mud_telnet_msp_stop_playing(self, command->type);
+            self->priv->sound[command->type].current_command = command;
+            mud_telnet_msp_start_playing(self, command->type);
         }
     }
     else
     {
-        telnet->sound[command->type].current_command = command;
-        mud_telnet_msp_start_playing(telnet, command->type);
+        self->priv->sound[command->type].current_command = command;
+        mud_telnet_msp_start_playing(self, command->type);
     }
 }
 
-void
-mud_telnet_msp_stop_playing(MudTelnet *telnet, MudMSPTypes type)
-{
-    telnet->sound[type].playing = FALSE;
-
-    if(GST_IS_ELEMENT(telnet->sound[type].play))
-    {
-        gst_element_set_state (telnet->sound[type].play, GST_STATE_NULL);
-        gst_object_unref (GST_OBJECT (telnet->sound[type].play));
-    }
-
-    if(telnet->sound[type].files)
-    {
-        g_strfreev(telnet->sound[type].files);
-        telnet->sound[type].files = NULL;
-    }
-
-    telnet->sound[type].files_len = 0;
-
-    mud_telnet_msp_command_free(telnet->sound[type].current_command);
-    telnet->sound[type].current_command = NULL;
-}
-
 static void
-mud_telnet_msp_start_playing(MudTelnet *telnet, MudMSPTypes type)
+mud_telnet_msp_start_playing(MudTelnetMsp *self, MudMSPTypes type)
 {
-    if(!telnet->sound[type].current_command)
+    g_return_if_fail(MUD_IS_TELNET_MSP(self));
+
+    if(!self->priv->sound[type].current_command)
         return;
 
-    if(mud_telnet_msp_get_files(telnet, type))
+    if(mud_telnet_msp_get_files(self, type))
     {
         gint num = 0;
 
-        telnet->sound[type].playing = TRUE;
+        self->priv->sound[type].playing = TRUE;
 
-        if(telnet->sound[type].files_len != 0)
-            num = rand() % telnet->sound[type].files_len;
+        if(self->priv->sound[type].files_len != 0)
+            num = rand() % self->priv->sound[type].files_len;
 
-        telnet->sound[type].play = gst_element_factory_make ("playbin", "play");
-        g_object_set (G_OBJECT(telnet->sound[type].play),
-                "uri", telnet->sound[type].files[num], NULL);
-        g_object_set(G_OBJECT(telnet->sound[type].play),
+        self->priv->sound[type].play = gst_element_factory_make ("playbin", "play");
+        g_object_set (G_OBJECT(self->priv->sound[type].play),
+                "uri", self->priv->sound[type].files[num], NULL);
+        g_object_set(G_OBJECT(self->priv->sound[type].play),
                 "volume",
-                (double)telnet->sound[type].current_command->volume/100,
+                (double)self->priv->sound[type].current_command->volume/100,
                 NULL);
 
-        telnet->sound[type].bus =
-            gst_pipeline_get_bus (GST_PIPELINE (telnet->sound[type].play));
+        self->priv->sound[type].bus =
+            gst_pipeline_get_bus (GST_PIPELINE (self->priv->sound[type].play));
 
         if(type == MSP_TYPE_SOUND)
-            gst_bus_add_watch (telnet->sound[type].bus,
-                    mud_telnet_msp_sound_bus_call, telnet);
+            gst_bus_add_watch (self->priv->sound[type].bus,
+                    mud_telnet_msp_sound_bus_call, self);
         else
-            gst_bus_add_watch (telnet->sound[type].bus,
-                    mud_telnet_msp_music_bus_call, telnet);
+            gst_bus_add_watch (self->priv->sound[type].bus,
+                    mud_telnet_msp_music_bus_call, self);
 
-        gst_object_unref (telnet->sound[type].bus);
+        gst_object_unref (self->priv->sound[type].bus);
 
-        gst_element_set_state (telnet->sound[type].play, GST_STATE_PLAYING);
+        gst_element_set_state (self->priv->sound[type].play, GST_STATE_PLAYING);
     }
 }
 
 static gboolean
-mud_telnet_msp_get_files(MudTelnet *telnet, MudMSPTypes type)
+mud_telnet_msp_get_files(MudTelnetMsp *self, MudMSPTypes type)
 {
     gchar sound_dir[2048];
     const gchar *file;
@@ -672,19 +978,28 @@
     GString *file_name;
     GString *subdir;
     GString *full_dir;
+    gchar *mud_name;
     GDir *dir;
     gint i, depth;
     GPatternSpec *regex;
+    MudConnectionView *view;
+
+    g_return_if_fail(MUD_IS_TELNET_MSP(self));
 
-    if(!telnet->sound[type].current_command)
+    g_object_get(self->priv->telnet, "parent-view", &view, NULL);
+    g_object_get(view, "mud-name", &mud_name, NULL);
+
+    if(!self->priv->sound[type].current_command)
         return FALSE;
 
     g_snprintf(sound_dir, 2048, "%s/.gnome-mud/audio/%s/",
-            g_get_home_dir(), telnet->mud_name);
+            g_get_home_dir(), mud_name);
     if(!g_file_test(sound_dir, G_FILE_TEST_IS_DIR))
         mkdir(sound_dir, 0777 );
 
-    structure = g_strsplit(telnet->sound[type].current_command->fName, "/", 0);
+    g_free(mud_name);
+
+    structure = g_strsplit(self->priv->sound[type].current_command->fName, "/", 0);
     depth = g_strv_length(structure);
 
     subdir = g_string_new(NULL);
@@ -702,8 +1017,8 @@
     full_dir = g_string_new(sound_dir);
     full_dir = g_string_append(full_dir, subdir->str);
 
-    if(telnet->sound[type].current_command->T)
-        full_dir = g_string_append(full_dir, telnet->sound[type].current_command->T);
+    if(self->priv->sound[type].current_command->T)
+        full_dir = g_string_append(full_dir, self->priv->sound[type].current_command->T);
 
     if(!g_file_test(full_dir->str, G_FILE_TEST_IS_DIR))
         g_mkdir_with_parents(full_dir->str, 0777);
@@ -732,7 +1047,7 @@
     // some servers ignore the standard concering the
     // T parameter and don't put the sound in a T-named
     // subdir.
-    if(file_output->len == 0 && telnet->sound[type].current_command->T)
+    if(file_output->len == 0 && self->priv->sound[type].current_command->T)
     {
         g_string_free(full_dir, TRUE);
         full_dir = g_string_new(sound_dir);
@@ -761,32 +1076,32 @@
     {
         url_output = g_string_new(NULL);
 
-        if(telnet->base_url || telnet->sound[type].current_command->U)
+        if(self->priv->base_url || self->priv->sound[type].current_command->U)
         {
-            if(telnet->base_url)
-                url_output = g_string_append(url_output, telnet->base_url);
+            if(self->priv->base_url)
+                url_output = g_string_append(url_output, self->priv->base_url);
             else
-                url_output = g_string_append(url_output, telnet->sound[type].current_command->U);
+                url_output = g_string_append(url_output, self->priv->sound[type].current_command->U);
 
             if(subdir->len != 0)
                 url_output = g_string_append(url_output, subdir->str);
 
-            /*	    if(telnet->sound[type].current_command->T)
+            /*	    if(self->priv->sound[type].current_command->T)
                     {
-                    url_output = g_string_append(url_output, telnet->sound[type].current_command->T);
+                    url_output = g_string_append(url_output, self->priv->sound[type].current_command->T);
                     url_output = g_string_append_c(url_output, '/');
                     }
                     */
             url_output = g_string_append(url_output, file_name->str);
 
             file_output = g_string_append(file_output, full_dir->str);
-            if(telnet->sound[type].current_command->T)
+            if(self->priv->sound[type].current_command->T)
                 file_output = g_string_append_c(file_output, '/');
             file_output = g_string_append(file_output, file_name->str);
 
-            telnet->sound[type].current_command->priority = 0;
+            self->priv->sound[type].current_command->priority = 0;
 
-            mud_connection_view_queue_download(telnet->parent, url_output->str, file_output->str);
+            mud_connection_view_queue_download(view, url_output->str, file_output->str);
         }
 
         g_string_free(url_output, TRUE);
@@ -800,11 +1115,11 @@
 
     files = g_strsplit(file_output->str, "\n", 0);
 
-    if(telnet->sound[type].files)
-        g_strfreev(telnet->sound[type].files);
+    if(self->priv->sound[type].files)
+        g_strfreev(self->priv->sound[type].files);
 
-    telnet->sound[type].files = files;
-    telnet->sound[type].files_len = g_strv_length(files) - 1;
+    self->priv->sound[type].files = files;
+    self->priv->sound[type].files_len = g_strv_length(files) - 1;
 
     g_string_free(file_output, TRUE);
     g_string_free(full_dir, TRUE);
@@ -817,34 +1132,34 @@
 static gboolean
 mud_telnet_msp_sound_bus_call (GstBus *bus, GstMessage *msg, gpointer data)
 {
-    MudTelnet *telnet = (MudTelnet *)data;
+    MudTelnetMsp *self = MUD_TELNET_MSP(data);
 
     switch (GST_MESSAGE_TYPE (msg))
     {
         case GST_MESSAGE_EOS:
-            telnet->sound[MSP_TYPE_SOUND].playing = FALSE;
+            self->priv->sound[MSP_TYPE_SOUND].playing = FALSE;
 
-            telnet->sound[MSP_TYPE_SOUND].current_command->current_repeat_count--;
+            self->priv->sound[MSP_TYPE_SOUND].current_command->current_repeat_count--;
 
-            gst_element_set_state (telnet->sound[MSP_TYPE_SOUND].play, GST_STATE_NULL);
+            gst_element_set_state (self->priv->sound[MSP_TYPE_SOUND].play, GST_STATE_NULL);
 
-            if(telnet->sound[MSP_TYPE_SOUND].current_command->loop ||
-                    telnet->sound[MSP_TYPE_SOUND].current_command->current_repeat_count != 0)
+            if(self->priv->sound[MSP_TYPE_SOUND].current_command->loop ||
+                    self->priv->sound[MSP_TYPE_SOUND].current_command->current_repeat_count != 0)
             {
                 gint num = 0;
 
-                if(telnet->sound[MSP_TYPE_SOUND].files_len != 0)
-                    num = rand() % telnet->sound[MSP_TYPE_SOUND].files_len;
+                if(self->priv->sound[MSP_TYPE_SOUND].files_len != 0)
+                    num = rand() % self->priv->sound[MSP_TYPE_SOUND].files_len;
 
-                g_object_set (G_OBJECT(telnet->sound[MSP_TYPE_SOUND].play),
-                        "uri", telnet->sound[MSP_TYPE_SOUND].files[num], NULL);
-                g_object_set(G_OBJECT(telnet->sound[MSP_TYPE_SOUND].play),
-                        "volume", (double)telnet->sound[MSP_TYPE_SOUND].current_command->volume/100.0, NULL);
+                g_object_set (G_OBJECT(self->priv->sound[MSP_TYPE_SOUND].play),
+                        "uri", self->priv->sound[MSP_TYPE_SOUND].files[num], NULL);
+                g_object_set(G_OBJECT(self->priv->sound[MSP_TYPE_SOUND].play),
+                        "volume", (double)self->priv->sound[MSP_TYPE_SOUND].current_command->volume/100.0, NULL);
 
-                gst_element_set_state (telnet->sound[MSP_TYPE_SOUND].play, GST_STATE_PLAYING);
+                gst_element_set_state (self->priv->sound[MSP_TYPE_SOUND].play, GST_STATE_PLAYING);
             }
             else
-                mud_telnet_msp_stop_playing(telnet, MSP_TYPE_SOUND);
+                mud_telnet_msp_stop_playing(self, MSP_TYPE_SOUND);
             break;
 
         case GST_MESSAGE_ERROR:
@@ -871,34 +1186,34 @@
 static gboolean
 mud_telnet_msp_music_bus_call (GstBus *bus, GstMessage *msg, gpointer data)
 {
-    MudTelnet *telnet = (MudTelnet *)data;
+    MudTelnetMsp *self = MUD_TELNET_MSP(data);
 
     switch (GST_MESSAGE_TYPE (msg))
     {
         case GST_MESSAGE_EOS:
-            telnet->sound[MSP_TYPE_MUSIC].playing = FALSE;
+            self->priv->sound[MSP_TYPE_MUSIC].playing = FALSE;
 
-            telnet->sound[MSP_TYPE_MUSIC].current_command->current_repeat_count--;
+            self->priv->sound[MSP_TYPE_MUSIC].current_command->current_repeat_count--;
 
-            gst_element_set_state (telnet->sound[MSP_TYPE_MUSIC].play, GST_STATE_NULL);
+            gst_element_set_state (self->priv->sound[MSP_TYPE_MUSIC].play, GST_STATE_NULL);
 
-            if(telnet->sound[MSP_TYPE_MUSIC].current_command->loop ||
-                    telnet->sound[MSP_TYPE_MUSIC].current_command->current_repeat_count != 0)
+            if(self->priv->sound[MSP_TYPE_MUSIC].current_command->loop ||
+                    self->priv->sound[MSP_TYPE_MUSIC].current_command->current_repeat_count != 0)
             {
                 gint num = 0;
 
-                if(telnet->sound[MSP_TYPE_MUSIC].files_len != 0)
-                    num = rand() % telnet->sound[MSP_TYPE_MUSIC].files_len;
+                if(self->priv->sound[MSP_TYPE_MUSIC].files_len != 0)
+                    num = rand() % self->priv->sound[MSP_TYPE_MUSIC].files_len;
 
-                g_object_set (G_OBJECT(telnet->sound[MSP_TYPE_MUSIC].play),
-                        "uri", telnet->sound[MSP_TYPE_MUSIC].files[num], NULL);
-                g_object_set(G_OBJECT(telnet->sound[MSP_TYPE_MUSIC].play),
-                        "volume", (double)telnet->sound[MSP_TYPE_MUSIC].current_command->volume/100.0, NULL);
+                g_object_set (G_OBJECT(self->priv->sound[MSP_TYPE_MUSIC].play),
+                        "uri", self->priv->sound[MSP_TYPE_MUSIC].files[num], NULL);
+                g_object_set(G_OBJECT(self->priv->sound[MSP_TYPE_MUSIC].play),
+                        "volume", (double)self->priv->sound[MSP_TYPE_MUSIC].current_command->volume/100.0, NULL);
 
-                gst_element_set_state (telnet->sound[MSP_TYPE_MUSIC].play, GST_STATE_PLAYING);
+                gst_element_set_state (self->priv->sound[MSP_TYPE_MUSIC].play, GST_STATE_PLAYING);
             }
             else
-                mud_telnet_msp_stop_playing(telnet, MSP_TYPE_MUSIC);
+                mud_telnet_msp_stop_playing(self, MSP_TYPE_MUSIC);
 
             break;
 
@@ -922,4 +1237,6 @@
 
     return TRUE;
 }
+
 #endif
+

Modified: trunk/src/mud-telnet-msp.h
==============================================================================
--- trunk/src/mud-telnet-msp.h	(original)
+++ trunk/src/mud-telnet-msp.h	Fri Mar 13 23:41:46 2009
@@ -22,9 +22,38 @@
 
 #ifdef ENABLE_GST
 
+G_BEGIN_DECLS
+
 #include <glib.h>
+#include <gst/gst.h>
+
 #include "mud-telnet.h"
 
+#define MUD_TYPE_TELNET_MSP              (mud_telnet_msp_get_type ())
+#define MUD_TELNET_MSP(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), MUD_TYPE_TELNET_MSP, MudTelnetMsp))
+#define MUD_TELNET_MSP_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), MUD_TYPE_TELNET_MSP, MudTelnetMspClass))
+#define MUD_IS_TELNET_MSP(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), MUD_TYPE_TELNET_MSP))
+#define MUD_IS_TELNET_MSP_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MUD_TYPE_TELNET_MSP))
+#define MUD_TELNET_MSP_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), MUD_TYPE_TELNET_MSP, MudTelnetMspClass))
+#define MUD_TELNET_MSP_GET_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUD_TYPE_TELNET_MSP, MudTelnetMspPrivate))
+
+typedef struct _MudTelnetMsp            MudTelnetMsp;
+typedef struct _MudTelnetMspClass       MudTelnetMspClass;
+typedef struct _MudTelnetMspPrivate     MudTelnetMspPrivate;
+
+struct _MudTelnetMspClass
+{
+    GObjectClass parent_class;
+};
+
+struct _MudTelnetMsp
+{
+    GObject parent_instance;
+
+    /*< private >*/
+    MudTelnetMspPrivate *priv;
+};
+
 typedef enum
 {
     MSP_TYPE_SOUND,
@@ -40,6 +69,17 @@
     MSP_STATE_PARSE_ARGS
 } MudMSPStates;
 
+typedef enum
+{
+    ARG_STATE_FILE,
+    ARG_STATE_V,
+    ARG_STATE_L,
+    ARG_STATE_C,
+    ARG_STATE_T,
+    ARG_STATE_U,
+    ARG_STATE_P
+} MudMSPArgStates;
+
 typedef struct MudMSPParser
 {
     gboolean enabled;
@@ -84,7 +124,6 @@
     gchar *file;
 } MudMSPDownloadItem;
 
-#include <gst/gst.h>
 typedef struct MudMSPSound
 {
     gboolean playing;
@@ -97,12 +136,16 @@
     MudMSPCommand *current_command;
 } MudMSPSound;
 
-void mud_telnet_msp_init(MudTelnet *telnet);
-void mud_telnet_msp_parser_clear(MudTelnet *telnet);
+GType mud_telnet_msp_get_type (void);
+
 void mud_telnet_msp_download_item_free(MudMSPDownloadItem *item);
-GString *mud_telnet_msp_parse(MudTelnet *telnet, GString *buf, gint *len);
-void mud_telnet_msp_stop_playing(MudTelnet *telnet, MudMSPTypes type);
+GString *mud_telnet_msp_parse(MudTelnetMsp *self, GString *buf, gint *len);
+void mud_telnet_msp_stop_playing(MudTelnetMsp *self, MudMSPTypes type);
+void mud_telnet_msp_parser_clear(MudTelnetMsp *self);
 
-#endif
+G_END_DECLS
+
+#endif // ENABLE_MSP
 
 #endif // MUD_TELNET_MSP_H
+

Added: trunk/src/mud-telnet-naws.c
==============================================================================
--- (empty file)
+++ trunk/src/mud-telnet-naws.c	Fri Mar 13 23:41:46 2009
@@ -0,0 +1,302 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-naws.c
+ * Copyright (C) 2005-2009 Les Harris <lharris gnome org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+#include <glib/gi18n.h>
+
+#include "gnome-mud.h"
+#include "mud-telnet.h"
+#include "mud-telnet-handler-interface.h"
+#include "mud-telnet-naws.h"
+
+struct _MudTelnetNawsPrivate
+{
+    /* Interface Properties */
+    MudTelnet *telnet;
+    gboolean enabled;
+    gint option;
+
+    /* Private Instance Members */
+};
+
+/* Property Identifiers */
+enum
+{
+    PROP_MUD_TELNET_NAWS_0,
+    PROP_ENABLED,
+    PROP_HANDLES_OPTION,
+    PROP_TELNET
+};
+
+/* Class Functions */
+static void mud_telnet_naws_init (MudTelnetNaws *self);
+static void mud_telnet_naws_class_init (MudTelnetNawsClass *klass);
+static void mud_telnet_naws_interface_init(MudTelnetHandlerInterface *iface);
+static void mud_telnet_naws_finalize (GObject *object);
+static GObject *mud_telnet_naws_constructor (GType gtype,
+                                             guint n_properties,
+                                             GObjectConstructParam *properties);
+static void mud_telnet_naws_set_property(GObject *object,
+                                         guint prop_id,
+                                         const GValue *value,
+                                         GParamSpec *pspec);
+static void mud_telnet_naws_get_property(GObject *object,
+                                         guint prop_id,
+                                         GValue *value,
+                                         GParamSpec *pspec);
+
+/*Interface Implementation */
+void mud_telnet_naws_enable(MudTelnetHandler *self);
+void mud_telnet_naws_disable(MudTelnetHandler *self);
+void mud_telnet_naws_handle_sub_neg(MudTelnetHandler *self,
+                                    guchar *buf,
+                                    guint len);
+
+/* Create the Type. We implement MudTelnetHandlerInterface */
+G_DEFINE_TYPE_WITH_CODE(MudTelnetNaws, mud_telnet_naws, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE (MUD_TELNET_HANDLER_TYPE,
+                                               mud_telnet_naws_interface_init));
+/* MudTelnetNaws class functions */
+static void
+mud_telnet_naws_class_init (MudTelnetNawsClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+    /* Override base object constructor */
+    object_class->constructor = mud_telnet_naws_constructor;
+
+    /* Override base object's finalize */
+    object_class->finalize = mud_telnet_naws_finalize;
+
+    /* Override base object property methods */
+    object_class->set_property = mud_telnet_naws_set_property;
+    object_class->get_property = mud_telnet_naws_get_property;
+
+    /* Add private data to class */
+    g_type_class_add_private(klass, sizeof(MudTelnetNawsPrivate));
+
+    /* Override Implementation Properties */
+    g_object_class_override_property(object_class,
+                                     PROP_ENABLED,
+                                     "enabled");
+
+    g_object_class_override_property(object_class,
+                                     PROP_HANDLES_OPTION,
+                                     "handles-option");
+
+    g_object_class_override_property(object_class,
+                                     PROP_TELNET,
+                                     "telnet");
+}
+
+static void
+mud_telnet_naws_interface_init(MudTelnetHandlerInterface *iface)
+{
+    iface->Enable = mud_telnet_naws_enable;
+    iface->Disable = mud_telnet_naws_disable;
+    iface->HandleSubNeg = mud_telnet_naws_handle_sub_neg;
+}
+
+static void
+mud_telnet_naws_init (MudTelnetNaws *self)
+{
+    /* Get our private data */
+    self->priv = MUD_TELNET_NAWS_GET_PRIVATE(self);
+
+    /* Set the defaults */
+    self->priv->telnet = NULL;
+    self->priv->option = TELOPT_NAWS;
+    self->priv->enabled = FALSE;
+}
+
+static GObject *
+mud_telnet_naws_constructor (GType gtype,
+                              guint n_properties,
+                              GObjectConstructParam *properties)
+{
+    MudTelnetNaws *self;
+    GObject *obj;
+    MudTelnetNawsClass *klass;
+    GObjectClass *parent_class;
+
+    /* Chain up to parent constructor */
+    klass = MUD_TELNET_NAWS_CLASS( g_type_class_peek(MUD_TYPE_TELNET_NAWS) );
+    parent_class = G_OBJECT_CLASS( g_type_class_peek_parent(klass) );
+    obj = parent_class->constructor(gtype, n_properties, properties);
+
+    self = MUD_TELNET_NAWS(obj);
+
+    if(!self->priv->telnet)
+    {
+        g_printf("ERROR: Tried to instantiate MudTelnetNaws without passing parent MudTelnet\n");
+        g_error("Tried to instantiate MudTelnetNaws without passing parent MudTelnet");
+    }
+
+    return obj;
+}
+
+static void
+mud_telnet_naws_finalize (GObject *object)
+{
+    MudTelnetNaws *self;
+    GObjectClass *parent_class;
+
+    self = MUD_TELNET_NAWS(object);
+
+    parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
+    parent_class->finalize(object);
+}
+
+static void
+mud_telnet_naws_set_property(GObject *object,
+                              guint prop_id,
+                              const GValue *value,
+                              GParamSpec *pspec)
+{
+    MudTelnetNaws *self;
+
+    self = MUD_TELNET_NAWS(object);
+
+    switch(prop_id)
+    {
+        case PROP_TELNET:
+            self->priv->telnet = MUD_TELNET(g_value_get_object(value));
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
+
+static void
+mud_telnet_naws_get_property(GObject *object,
+                              guint prop_id,
+                              GValue *value,
+                              GParamSpec *pspec)
+{
+    MudTelnetNaws *self;
+
+    self = MUD_TELNET_NAWS(object);
+
+    switch(prop_id)
+    {
+        case PROP_ENABLED:
+            g_value_set_boolean(value, self->priv->enabled);
+            break;
+
+        case PROP_HANDLES_OPTION:
+            g_value_set_int(value, self->priv->option);
+            break;
+
+        case PROP_TELNET:
+            g_value_take_object(value, self->priv->telnet);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
+
+/* Interface Implementation */
+void 
+mud_telnet_naws_enable(MudTelnetHandler *handler)
+{
+    MudTelnetNaws *self;
+    MudConnectionView *view;
+    gint w, h;
+
+    self = MUD_TELNET_NAWS(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_NAWS(self));
+
+    self->priv->enabled = TRUE;
+
+    mud_telnet_get_parent_size(self->priv->telnet, &w, &h);
+
+    g_object_get(self->priv->telnet, "parent-view", &view, NULL);
+    g_object_set(view,
+                 "naws-enabled", TRUE,
+                 NULL);
+
+    mud_telnet_send_naws(self->priv->telnet, w, h);
+
+    g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "NAWS Enabled");
+}
+
+void
+mud_telnet_naws_disable(MudTelnetHandler *handler)
+{
+    MudTelnetNaws *self;
+    MudConnectionView *view;
+
+    self = MUD_TELNET_NAWS(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_NAWS(self));
+
+    self->priv->enabled = FALSE;
+
+    g_object_get(self->priv->telnet, "parent-view", &view, NULL);
+    g_object_set(view,
+                 "naws-enabled", FALSE,
+                 NULL);
+
+    g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "NAWS Disabled");
+}
+
+void
+mud_telnet_naws_handle_sub_neg(MudTelnetHandler *handler,
+                               guchar *buf,
+                               guint len)
+{
+    MudTelnetNaws *self;
+
+    self = MUD_TELNET_NAWS(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_NAWS(self));
+
+    /* We never receive a NAWS subreq, we just send them */
+    return;
+}
+
+/* Public Methods */
+void
+mud_telnet_naws_send(MudTelnetNaws *self, gint width, gint height)
+{
+    guchar w1, h1, w0, h0;
+    
+    g_return_if_fail(MUD_IS_TELNET_NAWS(self));
+
+    w1 = (width >> 8) & 0xff;
+    w0 = width & 0xff;
+
+    h1 = (height >> 8) & 0xff;
+    h0 = height & 0xff;
+
+    mud_telnet_send_sub_req(self->priv->telnet, 5,
+                            (guchar)self->priv->option,
+                            w1, w0, h1, h0);
+}
+

Added: trunk/src/mud-telnet-naws.h
==============================================================================
--- (empty file)
+++ trunk/src/mud-telnet-naws.h	Fri Mar 13 23:41:46 2009
@@ -0,0 +1,59 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-naws.h
+ * Copyright (C) 2005-2009 Les Harris <lharris gnome org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef MUD_TELNET_NAWS_H
+#define MUD_TELNET_NAWS_H
+
+G_BEGIN_DECLS
+
+#include <glib.h>
+
+#define MUD_TYPE_TELNET_NAWS              (mud_telnet_naws_get_type ())
+#define MUD_TELNET_NAWS(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), MUD_TYPE_TELNET_NAWS, MudTelnetNaws))
+#define MUD_TELNET_NAWS_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), MUD_TYPE_TELNET_NAWS, MudTelnetNawsClass))
+#define MUD_IS_TELNET_NAWS(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), MUD_TYPE_TELNET_NAWS))
+#define MUD_IS_TELNET_NAWS_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MUD_TYPE_TELNET_NAWS))
+#define MUD_TELNET_NAWS_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), MUD_TYPE_TELNET_NAWS, MudTelnetNawsClass))
+#define MUD_TELNET_NAWS_GET_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUD_TYPE_TELNET_NAWS, MudTelnetNawsPrivate))
+
+typedef struct _MudTelnetNaws            MudTelnetNaws;
+typedef struct _MudTelnetNawsClass       MudTelnetNawsClass;
+typedef struct _MudTelnetNawsPrivate     MudTelnetNawsPrivate;
+
+struct _MudTelnetNawsClass
+{
+    GObjectClass parent_class;
+};
+
+struct _MudTelnetNaws
+{
+    GObject parent_instance;
+
+    /*< private >*/
+    MudTelnetNawsPrivate *priv;
+};
+
+GType mud_telnet_naws_get_type (void);
+
+void mud_telnet_naws_send(MudTelnetNaws *self, gint w, gint h);
+
+G_END_DECLS
+
+#endif // MUD_TELNET_NAWS_H
+

Added: trunk/src/mud-telnet-ttype.c
==============================================================================
--- (empty file)
+++ trunk/src/mud-telnet-ttype.c	Fri Mar 13 23:41:46 2009
@@ -0,0 +1,317 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-ttype.c
+ * Copyright (C) 2005-2009 Les Harris <lharris gnome org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+#include <glib/gi18n.h>
+
+#include "gnome-mud.h"
+#include "mud-telnet.h"
+#include "mud-telnet-handler-interface.h"
+#include "mud-telnet-ttype.h"
+
+struct _MudTelnetTTypePrivate
+{
+    /* Interface Properties */
+    MudTelnet *telnet;
+    gboolean enabled;
+    gint option;
+
+    /* Private Instance Members */
+    gint ttype_iteration;
+};
+
+/* Property Identifiers */
+enum
+{
+    PROP_MUD_TELNET_TTYPE_0,
+    PROP_ENABLED,
+    PROP_HANDLES_OPTION,
+    PROP_TELNET
+};
+
+/* Class Functions */
+static void mud_telnet_ttype_init (MudTelnetTType *self);
+static void mud_telnet_ttype_class_init (MudTelnetTTypeClass *klass);
+static void mud_telnet_ttype_interface_init(MudTelnetHandlerInterface *iface);
+static void mud_telnet_ttype_finalize (GObject *object);
+static GObject *mud_telnet_ttype_constructor (GType gtype,
+                                              guint n_properties,
+                                              GObjectConstructParam *properties);
+static void mud_telnet_ttype_set_property(GObject *object,
+                                          guint prop_id,
+                                          const GValue *value,
+                                          GParamSpec *pspec);
+static void mud_telnet_ttype_get_property(GObject *object,
+                                          guint prop_id,
+                                          GValue *value,
+                                          GParamSpec *pspec);
+
+/*Interface Implementation */
+void mud_telnet_ttype_enable(MudTelnetHandler *self);
+void mud_telnet_ttype_disable(MudTelnetHandler *self);
+void mud_telnet_ttype_handle_sub_neg(MudTelnetHandler *self,
+                                     guchar *buf,
+                                     guint len);
+
+/* Create the Type. We implement MudTelnetHandlerInterface */
+G_DEFINE_TYPE_WITH_CODE(MudTelnetTType, mud_telnet_ttype, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE (MUD_TELNET_HANDLER_TYPE,
+                                               mud_telnet_ttype_interface_init));
+/* MudTelnetTType class functions */
+static void
+mud_telnet_ttype_class_init (MudTelnetTTypeClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+    /* Override base object constructor */
+    object_class->constructor = mud_telnet_ttype_constructor;
+
+    /* Override base object's finalize */
+    object_class->finalize = mud_telnet_ttype_finalize;
+
+    /* Override base object property methods */
+    object_class->set_property = mud_telnet_ttype_set_property;
+    object_class->get_property = mud_telnet_ttype_get_property;
+
+    /* Add private data to class */
+    g_type_class_add_private(klass, sizeof(MudTelnetTTypePrivate));
+
+    /* Override Implementation Properties */
+    g_object_class_override_property(object_class,
+                                     PROP_ENABLED,
+                                     "enabled");
+
+    g_object_class_override_property(object_class,
+                                     PROP_HANDLES_OPTION,
+                                     "handles-option");
+
+    g_object_class_override_property(object_class,
+                                     PROP_TELNET,
+                                     "telnet");
+}
+
+static void
+mud_telnet_ttype_interface_init(MudTelnetHandlerInterface *iface)
+{
+    iface->Enable = mud_telnet_ttype_enable;
+    iface->Disable = mud_telnet_ttype_disable;
+    iface->HandleSubNeg = mud_telnet_ttype_handle_sub_neg;
+}
+
+static void
+mud_telnet_ttype_init (MudTelnetTType *self)
+{
+    /* Get our private data */
+    self->priv = MUD_TELNET_TTYPE_GET_PRIVATE(self);
+
+    /* Set the defaults */
+    self->priv->telnet = NULL;
+    self->priv->option = TELOPT_TTYPE;
+    self->priv->enabled = FALSE;
+}
+
+static GObject *
+mud_telnet_ttype_constructor (GType gtype,
+                              guint n_properties,
+                              GObjectConstructParam *properties)
+{
+    MudTelnetTType *self;
+    GObject *obj;
+    MudTelnetTTypeClass *klass;
+    GObjectClass *parent_class;
+
+    /* Chain up to parent constructor */
+    klass = MUD_TELNET_TTYPE_CLASS( g_type_class_peek(MUD_TYPE_TELNET_TTYPE) );
+    parent_class = G_OBJECT_CLASS( g_type_class_peek_parent(klass) );
+    obj = parent_class->constructor(gtype, n_properties, properties);
+
+    self = MUD_TELNET_TTYPE(obj);
+
+    if(!self->priv->telnet)
+    {
+        g_printf("ERROR: Tried to instantiate MudTelnetTType without passing parent MudTelnet\n");
+        g_error("Tried to instantiate MudTelnetTType without passing parent MudTelnet");
+    }
+
+    self->priv->ttype_iteration = 0;
+
+    return obj;
+}
+
+static void
+mud_telnet_ttype_finalize (GObject *object)
+{
+    MudTelnetTType *self;
+    GObjectClass *parent_class;
+
+    self = MUD_TELNET_TTYPE(object);
+
+    parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
+    parent_class->finalize(object);
+}
+
+static void
+mud_telnet_ttype_set_property(GObject *object,
+                              guint prop_id,
+                              const GValue *value,
+                              GParamSpec *pspec)
+{
+    MudTelnetTType *self;
+
+    self = MUD_TELNET_TTYPE(object);
+
+    switch(prop_id)
+    {
+        case PROP_TELNET:
+            self->priv->telnet = MUD_TELNET(g_value_get_object(value));
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
+
+static void
+mud_telnet_ttype_get_property(GObject *object,
+                              guint prop_id,
+                              GValue *value,
+                              GParamSpec *pspec)
+{
+    MudTelnetTType *self;
+
+    self = MUD_TELNET_TTYPE(object);
+
+    switch(prop_id)
+    {
+        case PROP_ENABLED:
+            g_value_set_boolean(value, self->priv->enabled);
+            break;
+
+        case PROP_HANDLES_OPTION:
+            g_value_set_int(value, self->priv->option);
+            break;
+
+        case PROP_TELNET:
+            g_value_take_object(value, self->priv->telnet);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
+
+/* Interface Implementation */
+void 
+mud_telnet_ttype_enable(MudTelnetHandler *handler)
+{
+    MudTelnetTType *self;
+
+    self = MUD_TELNET_TTYPE(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_TTYPE(self));
+
+    self->priv->enabled = TRUE;
+    self->priv->ttype_iteration = 0;
+
+    g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "Terminal Type Enabled");
+}
+
+void
+mud_telnet_ttype_disable(MudTelnetHandler *handler)
+{
+    MudTelnetTType *self;
+
+    self = MUD_TELNET_TTYPE(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_TTYPE(self));
+
+    self->priv->enabled = FALSE;
+
+    g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "Terminal Type Disabled");
+}
+
+void
+mud_telnet_ttype_handle_sub_neg(MudTelnetHandler *handler,
+                                guchar *buf,
+                                guint len)
+{
+    MudTelnetTType *self;
+
+    self = MUD_TELNET_TTYPE(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_TTYPE(self));
+
+    g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "Sending Terminal Type");
+
+    if(self->priv->enabled)
+    {
+        switch(self->priv->ttype_iteration)
+        {
+            case 0:
+                mud_telnet_send_sub_req(self->priv->telnet, 11,
+                        (guchar)self->priv->option,
+                        (guchar)TEL_TTYPE_IS,
+                        'g','n','o','m','e','-','m','u','d');
+                self->priv->ttype_iteration++;
+                break;
+
+            case 1:
+                mud_telnet_send_sub_req(self->priv->telnet, 7,
+                        (guchar)TELOPT_TTYPE,
+                        (guchar)TEL_TTYPE_IS,
+                        'x','t','e','r','m');
+                self->priv->ttype_iteration++;
+                break;
+
+            case 2:
+                mud_telnet_send_sub_req(self->priv->telnet, 6,
+                        (guchar)TELOPT_TTYPE,
+                        (guchar)TEL_TTYPE_IS,
+                        'a','n','s','i');
+                self->priv->ttype_iteration++;
+                break;
+
+            case 3:
+                mud_telnet_send_sub_req(self->priv->telnet, 9,
+                        (guchar)TELOPT_TTYPE,
+                        (guchar)TEL_TTYPE_IS,
+                        'U','N','K','N','O','W','N');
+                self->priv->ttype_iteration++;
+                break;
+
+            /* RFC 1091 says we need to repeat the last type */
+            case 4:
+                mud_telnet_send_sub_req(self->priv->telnet, 9,
+                        (guchar)TELOPT_TTYPE,
+                        (gchar)TEL_TTYPE_IS,
+                        'U','N','K','N','O','W','N');
+                self->priv->ttype_iteration = 0;
+                break;
+
+        }
+    }
+}
+

Added: trunk/src/mud-telnet-ttype.h
==============================================================================
--- (empty file)
+++ trunk/src/mud-telnet-ttype.h	Fri Mar 13 23:41:46 2009
@@ -0,0 +1,57 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-ttype.h
+ * Copyright (C) 2005-2009 Les Harris <lharris gnome org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef MUD_TELNET_TTYPE_H
+#define MUD_TELNET_TTYPE_H
+
+G_BEGIN_DECLS
+
+#include <glib.h>
+
+#define MUD_TYPE_TELNET_TTYPE              (mud_telnet_ttype_get_type ())
+#define MUD_TELNET_TTYPE(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), MUD_TYPE_TELNET_TTYPE, MudTelnetTType))
+#define MUD_TELNET_TTYPE_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), MUD_TYPE_TELNET_TTYPE, MudTelnetTTypeClass))
+#define MUD_IS_TELNET_TTYPE(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), MUD_TYPE_TELNET_TTYPE))
+#define MUD_IS_TELNET_TTYPE_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MUD_TYPE_TELNET_TTYPE))
+#define MUD_TELNET_TTYPE_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), MUD_TYPE_TELNET_TTYPE, MudTelnetTTypeClass))
+#define MUD_TELNET_TTYPE_GET_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUD_TYPE_TELNET_TTYPE, MudTelnetTTypePrivate))
+
+typedef struct _MudTelnetTType            MudTelnetTType;
+typedef struct _MudTelnetTTypeClass       MudTelnetTTypeClass;
+typedef struct _MudTelnetTTypePrivate     MudTelnetTTypePrivate;
+
+struct _MudTelnetTTypeClass
+{
+    GObjectClass parent_class;
+};
+
+struct _MudTelnetTType
+{
+    GObject parent_instance;
+
+    /*< private >*/
+    MudTelnetTTypePrivate *priv;
+};
+
+GType mud_telnet_ttype_get_type (void);
+
+G_END_DECLS
+
+#endif // MUD_TELNET_TTYPE_H
+

Modified: trunk/src/mud-telnet-zmp.c
==============================================================================
--- trunk/src/mud-telnet-zmp.c	(original)
+++ trunk/src/mud-telnet-zmp.c	Fri Mar 13 23:41:46 2009
@@ -1,5 +1,5 @@
 /* GNOME-Mud - A simple Mud Client
- * mud-telnet-zmp.c
+ * mud-self-zmp.c
  * Copyright (C) 2008-2009 Les Harris <lharris gnome org>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -30,94 +30,316 @@
 
 #include "gnome-mud.h"
 #include "mud-telnet.h"
+#include "mud-telnet-handler-interface.h"
 #include "mud-telnet-zmp.h"
 
-static void mud_zmp_register_core_functions(MudTelnet *telnet);
-static void mud_zmp_send_command(MudTelnet *telnet, guint32 count, ...);
+struct _MudTelnetZmpPrivate
+{
+    /* Interface Properties */
+    MudTelnet *telnet;
+    gboolean enabled;
+    gint option;
+
+    /* Private Instance Members */
+    GHashTable *commands;
+};
+
+/* Property Identifiers */
+enum
+{
+    PROP_MUD_TELNET_ZMP_0,
+    PROP_ENABLED,
+    PROP_HANDLES_OPTION,
+    PROP_TELNET
+};
+
+/* Class Functions */
+static void mud_telnet_zmp_init (MudTelnetZmp *self);
+static void mud_telnet_zmp_class_init (MudTelnetZmpClass *klass);
+static void mud_telnet_zmp_interface_init(MudTelnetHandlerInterface *iface);
+static void mud_telnet_zmp_finalize (GObject *object);
+static GObject *mud_telnet_zmp_constructor (GType gtype,
+                                             guint n_properties,
+                                             GObjectConstructParam *properties);
+static void mud_telnet_zmp_set_property(GObject *object,
+                                         guint prop_id,
+                                         const GValue *value,
+                                         GParamSpec *pspec);
+static void mud_telnet_zmp_get_property(GObject *object,
+                                         guint prop_id,
+                                         GValue *value,
+                                         GParamSpec *pspec);
+
+/*Interface Implementation */
+void mud_telnet_zmp_enable(MudTelnetHandler *self);
+void mud_telnet_zmp_disable(MudTelnetHandler *self);
+void mud_telnet_zmp_handle_sub_neg(MudTelnetHandler *self,
+                                    guchar *buf,
+                                    guint len);
+
+/* Create the Type. We implement MudTelnetHandlerInterface */
+G_DEFINE_TYPE_WITH_CODE(MudTelnetZmp, mud_telnet_zmp, G_TYPE_OBJECT,
+                        G_IMPLEMENT_INTERFACE (MUD_TELNET_HANDLER_TYPE,
+                                               mud_telnet_zmp_interface_init));
+
+/* Private Methods */
+static void mud_zmp_register_core_functions(MudTelnetZmp *self);
+static void mud_zmp_send_command(MudTelnetZmp *self, guint32 count, ...);
 static void mud_zmp_destroy_key(gpointer k);
 static void mud_zmp_destroy_command(gpointer c);
+static gboolean mud_zmp_has_command(MudTelnetZmp *self, gchar *name);
+static gboolean mud_zmp_has_package(MudTelnetZmp *self, gchar *package);
+static MudZMPFunction mud_zmp_get_function(MudTelnetZmp *self, gchar *name);
 
 /* Core ZMP Functions */
-static void ZMP_ident(MudTelnet *telnet, gint argc, gchar **argv);
-static void ZMP_ping_and_time(MudTelnet *telnet, gint argc, gchar **argv);
-static void ZMP_check(MudTelnet *telnet, gint argc, gchar **argv);
+static void ZMP_ident(MudTelnetZmp *self, gint argc, gchar **argv);
+static void ZMP_ping_and_time(MudTelnetZmp *self, gint argc, gchar **argv);
+static void ZMP_check(MudTelnetZmp *self, gint argc, gchar **argv);
 
-/* Public Interface */
-void
-mud_zmp_init(MudTelnet *telnet)
+/* MudTelnetZmp class functions */
+static void
+mud_telnet_zmp_class_init (MudTelnetZmpClass *klass)
 {
-    telnet->zmp_commands = g_hash_table_new_full(g_str_hash, g_str_equal,
-            mud_zmp_destroy_key, mud_zmp_destroy_command);
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+    /* Override base object constructor */
+    object_class->constructor = mud_telnet_zmp_constructor;
+
+    /* Override base object's finalize */
+    object_class->finalize = mud_telnet_zmp_finalize;
+
+    /* Override base object property methods */
+    object_class->set_property = mud_telnet_zmp_set_property;
+    object_class->get_property = mud_telnet_zmp_get_property;
+
+    /* Add private data to class */
+    g_type_class_add_private(klass, sizeof(MudTelnetZmpPrivate));
+
+    /* Override Implementation Properties */
+    g_object_class_override_property(object_class,
+                                     PROP_ENABLED,
+                                     "enabled");
 
-    mud_zmp_register_core_functions(telnet);
+    g_object_class_override_property(object_class,
+                                     PROP_HANDLES_OPTION,
+                                     "handles-option");
+
+    g_object_class_override_property(object_class,
+                                     PROP_TELNET,
+                                     "telnet");
 }
 
-void
-mud_zmp_finalize(MudTelnet *telnet)
+static void
+mud_telnet_zmp_interface_init(MudTelnetHandlerInterface *iface)
 {
-    if(telnet->zmp_commands)
-        g_hash_table_destroy(telnet->zmp_commands);
+    iface->Enable = mud_telnet_zmp_enable;
+    iface->Disable = mud_telnet_zmp_disable;
+    iface->HandleSubNeg = mud_telnet_zmp_handle_sub_neg;
 }
 
-void
-mud_zmp_register(MudTelnet *telnet, MudZMPCommand *command)
+static void
+mud_telnet_zmp_init (MudTelnetZmp *self)
 {
-    if(command && mud_zmp_has_command(telnet, command->name))
-        return; // Function already registered.
+    /* Get our private data */
+    self->priv = MUD_TELNET_ZMP_GET_PRIVATE(self);
 
-    g_hash_table_insert(telnet->zmp_commands, g_strdup(command->name), command);
+    /* Set the defaults */
+    self->priv->telnet = NULL;
+    self->priv->option = TELOPT_ZMP;
+    self->priv->enabled = FALSE;
 }
 
-gboolean
-mud_zmp_has_command(MudTelnet *telnet, gchar *name)
+static GObject *
+mud_telnet_zmp_constructor (GType gtype,
+                              guint n_properties,
+                              GObjectConstructParam *properties)
 {
-    return !(g_hash_table_lookup(telnet->zmp_commands, name) == NULL);
+    MudTelnetZmp *self;
+    GObject *obj;
+    MudTelnetZmpClass *klass;
+    GObjectClass *parent_class;
+
+    /* Chain up to parent constructor */
+    klass = MUD_TELNET_ZMP_CLASS( g_type_class_peek(MUD_TYPE_TELNET_ZMP) );
+    parent_class = G_OBJECT_CLASS( g_type_class_peek_parent(klass) );
+    obj = parent_class->constructor(gtype, n_properties, properties);
+
+    self = MUD_TELNET_ZMP(obj);
+
+    if(!self->priv->telnet)
+    {
+        g_printf("ERROR: Tried to instantiate MudTelnetZmp without passing parent MudTelnet\n");
+        g_error("Tried to instantiate MudTelnetZmp without passing parent MudTelnet");
+    }
+
+    self->priv->commands = g_hash_table_new_full(g_str_hash,
+                                                 g_str_equal,
+                                                 mud_zmp_destroy_key,
+                                                 mud_zmp_destroy_command);
+
+    mud_zmp_register_core_functions(self);
+
+    return obj;
 }
 
-gboolean
-mud_zmp_has_package(MudTelnet *telnet, gchar *package)
+static void
+mud_telnet_zmp_finalize (GObject *object)
 {
-    GList *keys = g_hash_table_get_keys(telnet->zmp_commands);
-    GList *iter;
+    MudTelnetZmp *self;
+    GObjectClass *parent_class;
 
-    for(iter = g_list_first(keys); iter != NULL; iter = g_list_next(iter))
+    self = MUD_TELNET_ZMP(object);
+
+    if(self->priv->commands)
+        g_hash_table_destroy(self->priv->commands);
+
+    parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
+    parent_class->finalize(object);
+}
+
+static void
+mud_telnet_zmp_set_property(GObject *object,
+                              guint prop_id,
+                              const GValue *value,
+                              GParamSpec *pspec)
+{
+    MudTelnetZmp *self;
+
+    self = MUD_TELNET_ZMP(object);
+
+    switch(prop_id)
     {
-        MudZMPCommand *command =
-            (MudZMPCommand *)g_hash_table_lookup(telnet->zmp_commands,
-                    (gchar *)iter->data);
+        case PROP_TELNET:
+            self->priv->telnet = MUD_TELNET(g_value_get_object(value));
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
 
-        if(strcmp(command->package, package) == 0)
-        {
-            g_list_free(keys);
-            return TRUE;
-        }
+static void
+mud_telnet_zmp_get_property(GObject *object,
+                              guint prop_id,
+                              GValue *value,
+                              GParamSpec *pspec)
+{
+    MudTelnetZmp *self;
+
+    self = MUD_TELNET_ZMP(object);
+
+    switch(prop_id)
+    {
+        case PROP_ENABLED:
+            g_value_set_boolean(value, self->priv->enabled);
+            break;
+
+        case PROP_HANDLES_OPTION:
+            g_value_set_int(value, self->priv->option);
+            break;
+
+        case PROP_TELNET:
+            g_value_take_object(value, self->priv->telnet);
+            break;
+
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
     }
+}
 
-    g_list_free(keys);
+/* Interface Implementation */
+void 
+mud_telnet_zmp_enable(MudTelnetHandler *handler)
+{
+    MudTelnetZmp *self;
 
-    return FALSE;
+    self = MUD_TELNET_ZMP(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_ZMP(self));
+
+    self->priv->enabled = TRUE;
+
+    g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "ZMP Enabled");
 }
 
-MudZMPFunction
-mud_zmp_get_function(MudTelnet *telnet, gchar *name)
+void
+mud_telnet_zmp_disable(MudTelnetHandler *handler)
 {
-    MudZMPFunction ret = NULL;
-    MudZMPCommand *val;
+    MudTelnetZmp *self;
 
-    if(!mud_zmp_has_command(telnet, name))
-        return NULL;
+    self = MUD_TELNET_ZMP(handler);
 
-    val = (MudZMPCommand *)g_hash_table_lookup(telnet->zmp_commands, name);
+    g_return_if_fail(MUD_IS_TELNET_ZMP(self));
 
-    if(val)
-        ret = (MudZMPFunction)val->execute;
+    /* Cannot disable ZMP once enabled per specification */
+    return;
+
+}
+
+void
+mud_telnet_zmp_handle_sub_neg(MudTelnetHandler *handler,
+                              guchar *buf,
+                              guint len)
+{
+    gchar command_buf[1024];
+    gint count = 0;
+    gint index = 0;
+    GString *args = g_string_new(NULL);
+    gchar **argv;
+    gint argc;
+    MudZMPFunction zmp_handler = NULL;
+    MudTelnetZmp *self;
+
+    self = MUD_TELNET_ZMP(handler);
+
+    g_return_if_fail(MUD_IS_TELNET_ZMP(self));
+
+    while(buf[count] != '\0' && count < len)
+        command_buf[index++] = buf[count++];
+    command_buf[index] = '\0';
+
+    /* FIXME: This is a silly way to do this */
+    while(count < len - 1)
+    {
+        if(buf[count] == '\0')
+        {
+            args = g_string_append(args,"|gmud_sep|");
+            count++;
+            continue;
+        }
+
+        args = g_string_append_c(args, buf[count++]);
+    }
+
+    args = g_string_prepend(args, command_buf);
+
+    argv = g_strsplit(args->str, "|gmud_sep|", -1);
+    argc = g_strv_length(argv);
+
+    g_log("Telnet", G_LOG_LEVEL_MESSAGE, "Received: ZMP Command: %s", command_buf);
+    for(count = 0; count < argc - 1; ++count)
+        g_log("Telnet", G_LOG_LEVEL_MESSAGE, "\t%s", argv[count]);
+
+    if(mud_zmp_has_command(self, command_buf))
+    {
+        zmp_handler = mud_zmp_get_function(self, command_buf);
+
+        if(zmp_handler)
+            zmp_handler(self, argc, argv);
+        else
+            g_warning("NULL ZMP functioned returned.");
+    }
+
+    g_strfreev(argv);
+    g_string_free(args, TRUE);
 
-    return ret;
 }
 
 /* Private Methods */
 static void
-mud_zmp_send_command(MudTelnet *telnet, guint32 count, ...)
+mud_zmp_send_command(MudTelnetZmp *self, guint32 count, ...)
 {
     guchar byte;
     guint32 i;
@@ -125,16 +347,22 @@
     guchar null = '\0';
     byte = (guchar)TEL_IAC;
     va_list va;
-    va_start(va, count);
     gchar *arg;
+    GConn *conn;
+
+    g_return_if_fail(MUD_IS_TELNET_ZMP(self));
+
+    g_object_get(self->priv->telnet, "connection", &conn, NULL);
+
+    va_start(va, count);
 
     g_log("Telnet", G_LOG_LEVEL_DEBUG, "Sending ZMP Command:");
 
-    gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
+    gnet_conn_write(conn, (gchar *)&byte, 1);
     byte = (guchar)TEL_SB;
-    gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
+    gnet_conn_write(conn, (gchar *)&byte, 1);
     byte = (guchar)TELOPT_ZMP;
-    gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
+    gnet_conn_write(conn, (gchar *)&byte, 1);
 
     for (i = 0; i < count; ++i)
     {
@@ -146,47 +374,40 @@
         {
             byte = (guchar)arg[j];
 
-            gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
+            gnet_conn_write(conn, (gchar *)&byte, 1);
 
             if (byte == (guchar)TEL_IAC)
-                gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
+                gnet_conn_write(conn, (gchar *)&byte, 1);
         }
 
-        gnet_conn_write(telnet->conn, (gchar *)&null, 1);
+        gnet_conn_write(conn, (gchar *)&null, 1);
     }
 
     va_end(va);
 
     byte = (guchar)TEL_IAC;
-    gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
+    gnet_conn_write(conn, (gchar *)&byte, 1);
     byte = (guchar)TEL_SE;
-    gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
+    gnet_conn_write(conn, (gchar *)&byte, 1);
 }
 
 static void
-mud_zmp_register_core_functions(MudTelnet *telnet)
+mud_zmp_register_core_functions(MudTelnetZmp *self)
 {
-    gint count = 4;
-    gint i;
-
-    telnet->commands[0].name = g_strdup("zmp.ident");
-    telnet->commands[0].package = g_strdup("zmp.");
-    telnet->commands[0].execute = ZMP_ident;
+    g_return_if_fail(MUD_IS_TELNET_ZMP(self));
 
-    telnet->commands[1].name = g_strdup("zmp.ping");
-    telnet->commands[1].package = g_strdup("zmp.");
-    telnet->commands[1].execute = ZMP_ping_and_time;
-
-    telnet->commands[2].name = g_strdup("zmp.time");
-    telnet->commands[2].package = g_strdup("zmp.");
-    telnet->commands[2].execute = ZMP_ping_and_time;
-
-    telnet->commands[3].name = g_strdup("zmp.check");
-    telnet->commands[3].package = g_strdup("zmp.");
-    telnet->commands[3].execute = ZMP_check;
-
-    for(i = 0; i < count; ++i)
-        mud_zmp_register(telnet, &telnet->commands[i]);
+    mud_zmp_register(self, mud_zmp_new_command("zmp.",
+                                               "zmp.ident",
+                                               ZMP_ident));
+    mud_zmp_register(self, mud_zmp_new_command("zmp.",
+                                               "zmp.ping",
+                                               ZMP_ping_and_time));
+    mud_zmp_register(self, mud_zmp_new_command("zmp.",
+                                               "zmp.time",
+                                               ZMP_ping_and_time));
+    mud_zmp_register(self, mud_zmp_new_command("zmp.",
+                                               "zmp.check",
+                                               ZMP_check));
 }
 
 static void
@@ -210,48 +431,151 @@
 
         if(command->package)
             g_free(command->package);
+
+        g_free(command);
     }
 }
 
+static gboolean
+mud_zmp_has_command(MudTelnetZmp *self, gchar *name)
+{
+    if(!MUD_IS_TELNET_ZMP(self))
+        return FALSE;
+
+    return !(g_hash_table_lookup(self->priv->commands, name) == NULL);
+}
+
+static gboolean
+mud_zmp_has_package(MudTelnetZmp *self, gchar *package)
+{
+    GList *keys;
+    GList *iter;
+
+    g_return_if_fail(MUD_IS_TELNET_ZMP(self));
+
+    keys = g_hash_table_get_keys(self->priv->commands);
+
+    for(iter = g_list_first(keys); iter != NULL; iter = g_list_next(iter))
+    {
+        MudZMPCommand *command =
+            (MudZMPCommand *)g_hash_table_lookup(self->priv->commands,
+                    (gchar *)iter->data);
+
+        if(g_str_equal(command->package, package))
+        {
+            g_list_free(keys);
+            return TRUE;
+        }
+    }
+
+    g_list_free(keys);
+
+    return FALSE;
+}
+
+static MudZMPFunction
+mud_zmp_get_function(MudTelnetZmp *self, gchar *name)
+{
+    MudZMPFunction ret = NULL;
+    MudZMPCommand *val;
+
+    g_return_if_fail(MUD_IS_TELNET_ZMP(self));
+
+    if(!mud_zmp_has_command(self, name))
+        return NULL;
+
+    val = (MudZMPCommand *)g_hash_table_lookup(self->priv->commands, name);
+
+    if(val)
+        ret = (MudZMPFunction)val->execute;
+
+    return ret;
+}
+
+
 /* Core ZMP Functions */
 static void
-ZMP_ident(MudTelnet *telnet, gint argc, gchar **argv)
+ZMP_ident(MudTelnetZmp *self, gint argc, gchar **argv)
 {
-    mud_zmp_send_command(telnet, 4,
+    g_return_if_fail(MUD_IS_TELNET_ZMP(self));
+
+    mud_zmp_send_command(self, 4,
             "zmp.ident", "gnome-mud", VERSION,
             "A mud client written for the GNOME environment.");
 }
 
 static void
-ZMP_ping_and_time(MudTelnet *telnet, gint argc, gchar **argv)
+ZMP_ping_and_time(MudTelnetZmp *self, gint argc, gchar **argv)
 {
     time_t t;
-    time(&t);
     gchar time_buffer[128];
 
+    g_return_if_fail(MUD_IS_TELNET_ZMP(self));
+
+    time(&t);
+
     strftime(time_buffer, sizeof(time_buffer),
             "%Y-%m-%d %H:%M:%S", gmtime(&t));
 
-    mud_zmp_send_command(telnet, 2, "zmp.time", time_buffer);
+    mud_zmp_send_command(self, 2, "zmp.time", time_buffer);
 }
 
 static void
-ZMP_check(MudTelnet *telnet, gint argc, gchar **argv)
+ZMP_check(MudTelnetZmp *self, gint argc, gchar **argv)
 {
-    gchar *item = argv[1];
+    gchar *item;
+
+    g_return_if_fail(MUD_IS_TELNET_ZMP(self));
+
+    item = argv[1];
 
     if(item[strlen(item) - 1] == '.') // Check for package.
     {
-        if(mud_zmp_has_package(telnet, item))
-            mud_zmp_send_command(telnet, 2, "zmp.support", item);
+        if(mud_zmp_has_package(self, item))
+            mud_zmp_send_command(self, 2, "zmp.support", item);
         else
-            mud_zmp_send_command(telnet, 2, "zmp.no-support", item);
+            mud_zmp_send_command(self, 2, "zmp.no-support", item);
     }
     else // otherwise command
     {
-        if(mud_zmp_has_command(telnet, item))
-            mud_zmp_send_command(telnet, 2, "zmp.support", item);
+        if(mud_zmp_has_command(self, item))
+            mud_zmp_send_command(self, 2, "zmp.support", item);
         else
-            mud_zmp_send_command(telnet, 2, "zmp.no-support", item);
+            mud_zmp_send_command(self, 2, "zmp.no-support", item);
     }
 }
+
+/* Public Methods */
+void
+mud_zmp_register(MudTelnetZmp *self, MudZMPCommand *command)
+{
+    g_return_if_fail(MUD_IS_TELNET_ZMP(self));
+
+    if(!command)
+        return;
+
+    if(mud_zmp_has_command(self, command->name))
+        return; // Function already registered.
+
+    g_hash_table_replace(self->priv->commands,
+                         g_strdup(command->name),
+                         command);
+}
+
+MudZMPCommand *
+mud_zmp_new_command(const gchar *package,
+                    const gchar *name,
+                    MudZMPFunction execute)
+{
+    MudZMPCommand *new_command = g_new0(MudZMPCommand, 1);
+
+    if(!new_command)
+        return NULL;
+
+    new_command->name = g_strdup(name);
+    new_command->package = g_strdup(package);
+    new_command->execute = execute;
+
+    return new_command;
+}
+

Modified: trunk/src/mud-telnet-zmp.h
==============================================================================
--- trunk/src/mud-telnet-zmp.h	(original)
+++ trunk/src/mud-telnet-zmp.h	Fri Mar 13 23:41:46 2009
@@ -1,6 +1,6 @@
 /* GNOME-Mud - A simple Mud Client
  * mud-telnet-zmp.h
- * Copyright (C) 2008-2009 Les Harris <lharris gnome org>
+ * Copyright (C) 2005-2009 Les Harris <lharris gnome org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,10 +20,36 @@
 #ifndef MUD_TELNET_ZMP_H
 #define MUD_TELNET_ZMP_H
 
+G_BEGIN_DECLS
+
 #include <glib.h>
-#include "mud-telnet.h"
 
-typedef void(*MudZMPFunction)(MudTelnet *telnet, gint argc, gchar **argv);
+#define MUD_TYPE_TELNET_ZMP              (mud_telnet_zmp_get_type ())
+#define MUD_TELNET_ZMP(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), MUD_TYPE_TELNET_ZMP, MudTelnetZmp))
+#define MUD_TELNET_ZMP_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), MUD_TYPE_TELNET_ZMP, MudTelnetZmpClass))
+#define MUD_IS_TELNET_ZMP(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), MUD_TYPE_TELNET_ZMP))
+#define MUD_IS_TELNET_ZMP_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MUD_TYPE_TELNET_ZMP))
+#define MUD_TELNET_ZMP_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), MUD_TYPE_TELNET_ZMP, MudTelnetZmpClass))
+#define MUD_TELNET_ZMP_GET_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUD_TYPE_TELNET_ZMP, MudTelnetZmpPrivate))
+
+typedef struct _MudTelnetZmp            MudTelnetZmp;
+typedef struct _MudTelnetZmpClass       MudTelnetZmpClass;
+typedef struct _MudTelnetZmpPrivate     MudTelnetZmpPrivate;
+
+struct _MudTelnetZmpClass
+{
+    GObjectClass parent_class;
+};
+
+struct _MudTelnetZmp
+{
+    GObject parent_instance;
+
+    /*< private >*/
+    MudTelnetZmpPrivate *priv;
+};
+
+typedef void(*MudZMPFunction)(MudTelnetZmp *self, gint argc, gchar **argv);
 
 typedef struct MudZMPCommand
 {
@@ -32,10 +58,13 @@
     MudZMPFunction execute;
 } MudZMPCommand;
 
-void mud_zmp_init(MudTelnet *telnet);
-void mud_zmp_finalize(MudTelnet *telnet);
-void mud_zmp_register(MudTelnet *telnet, MudZMPCommand *command);
-gboolean mud_zmp_has_command(MudTelnet *telnet, gchar *name);
-MudZMPFunction mud_zmp_get_function(MudTelnet *telnet, gchar *name);
+GType mud_telnet_zmp_get_type (void);
+
+MudZMPCommand* mud_zmp_new_command(const gchar *package,
+                                   const gchar *name,
+                                   MudZMPFunction execute);
+
+void mud_zmp_register(MudTelnetZmp *self, MudZMPCommand *command);
 
 #endif // MUD_TELNET_ZMP_H
+

Modified: trunk/src/mud-telnet.c
==============================================================================
--- trunk/src/mud-telnet.c	(original)
+++ trunk/src/mud-telnet.c	Fri Mar 13 23:41:46 2009
@@ -31,335 +31,344 @@
 
 #include "gnome-mud.h"
 #include "mud-telnet.h"
-#include "mud-telnet-handlers.h"
+
+/* Handlers */
+#include "mud-telnet-handler-interface.h"
+#include "mud-telnet-ttype.h"
+#include "mud-telnet-naws.h"
+#include "mud-telnet-echo.h"
+#include "mud-telnet-eor.h"
+#include "mud-telnet-charset.h"
 #include "mud-telnet-zmp.h"
 
+#ifdef ENABLE_GST
+#include "mud-telnet-msp.h"
+#endif
+
 #ifdef ENABLE_MCCP
 #include "mud-telnet-mccp.h"
 #endif
 
 struct _MudTelnetPrivate
 {
-};
+    GConn *conn;
+    gchar *mud_name;
 
-GType mud_telnet_get_type (void);
-static void mud_telnet_init (MudTelnet *pt);
-static void mud_telnet_class_init (MudTelnetClass *klass);
-static void mud_telnet_finalize (GObject *object);
-
-static void mud_telnet_send_iac(MudTelnet *telnet, guchar ch1, guchar ch2);
-static void mud_telnet_on_handle_subnego(MudTelnet *telnet);
-static void mud_telnet_on_enable_opt(MudTelnet *telnet,
-				     const guchar opt_no, gint him);
-static void mud_telnet_on_disable_opt(MudTelnet *telnet,
-				      const guchar opt_no, gint him);
-static guchar mud_telnet_get_telopt_state(guchar *storage, const guint bitshift);
-static gint mud_telnet_get_telopt_queue(guchar *storage, const guint bitshift);
-static void  mud_telnet_set_telopt_state(guchar *storage,
-					 const enum TelnetOptionState state, const guint bitshift);
-static gint mud_telnet_get_index_by_option(MudTelnet *telnet, guchar option_number);
-static void mud_telnet_set_telopt_queue(guchar *storage,
-					gint bit_on, const guint bitshift);
+    enum TelnetState tel_state;
+    GHashTable *handlers;
 
-static gint 
-mud_telnet_handle_positive_nego(MudTelnet *telnet,
-				const guchar opt_no,
-				const guchar affirmative,
-				const guchar negative,
-				gint him);
-static gint
-mud_telnet_handle_negative_nego(MudTelnet *telnet,
-                                const guchar opt_no,
-				const guchar affirmative,
-				const guchar negative,
-				gint him);
+    guchar telopt_states[256];
 
+    guint32 subreq_pos;
+    guchar subreq_buffer[TEL_SUBREQ_BUFFER_SIZE];
 
-gchar *mud_telnet_get_telopt_string(guchar c);
+    GString *processed;
+    GString *buffer;
+    size_t pos;
+};
 
-// MudTelnet class functions
-GType
-mud_telnet_get_type (void)
+/* Property Identifiers */
+enum
 {
-    static GType object_type = 0;
+    PROP_MUD_TELNET_0,
+    PROP_PARENT_VIEW,
+    PROP_GA_RECEIVED,
+    PROP_EOR_RECEIVED,
+    PROP_CONNECTION
+};
 
-    g_type_init();
+/* Create the Type */
+G_DEFINE_TYPE(MudTelnet, mud_telnet, G_TYPE_OBJECT);
 
-    if (!object_type)
-    {
-        static const GTypeInfo object_info =
-        {
-            sizeof (MudTelnetClass),
-            NULL,
-            NULL,
-            (GClassInitFunc) mud_telnet_class_init,
-            NULL,
-            NULL,
-            sizeof (MudTelnet),
-            0,
-            (GInstanceInitFunc) mud_telnet_init,
-        };
+/* Class Functions */
+static void mud_telnet_init (MudTelnet *pt);
+static void mud_telnet_class_init (MudTelnetClass *klass);
+static void mud_telnet_finalize (GObject *object);
+static GObject *mud_telnet_constructor (GType gtype,
+                                        guint n_properties,
+                                        GObjectConstructParam *properties);
+static void mud_telnet_set_property(GObject *object,
+                                    guint prop_id,
+                                    const GValue *value,
+                                    GParamSpec *pspec);
+static void mud_telnet_get_property(GObject *object,
+                                    guint prop_id,
+                                    GValue *value,
+                                    GParamSpec *pspec);
+
+/* Private Methods */
+static gchar *mud_telnet_get_telopt_string(guchar c);
+static gchar *mud_telnet_get_telnet_string(guchar c);
 
-        object_type = g_type_register_static(G_TYPE_OBJECT, "MudTelnet", &object_info, 0);
-    }
+static void mud_telnet_register_handlers(MudTelnet *telnet);
+static void mud_telnet_send_iac(MudTelnet *telnet, guchar ch1, guchar ch2);
 
-    return object_type;
-}
+static gint   mud_telnet_get_telopt_queue(guchar *storage, const guint bitshift);
+static guchar mud_telnet_get_telopt_state(guchar *storage, const guint bitshift);
+static void   mud_telnet_set_telopt_state(guchar *storage,
+					  const enum TelnetOptionState state,
+                                          const guint bitshift);
 
-static void
-mud_telnet_init (MudTelnet *telnet)
-{
-    telnet->priv = g_new0(MudTelnetPrivate, 1);
+static void mud_telnet_set_telopt_queue    (guchar *storage,
+					    gint bit_on,
+                                            const guint bitshift);
 
-    telnet->tel_state = TEL_STATE_TEXT;
-    telnet->ttype_iteration = 0;
+static gint mud_telnet_handle_positive_nego(MudTelnet *telnet,
+                                            const guchar opt_no,
+                                            const guchar affirmative,
+                                            const guchar negative,
+                                            gint him);
 
-    memset(telnet->telopt_states, 0, sizeof(telnet->telopt_states));
-    memset(telnet->handlers, 0, sizeof(telnet->handlers));
+static gint mud_telnet_handle_negative_nego(MudTelnet *telnet,
+                                            const guchar opt_no,
+                                            const guchar affirmative,
+                                            const guchar negative,
+                                            gint him);
 
-    mud_telnet_register_handlers(telnet);
+static void mud_telnet_on_handle_subnego   (MudTelnet *telnet);
 
-    telnet->eor_enabled = FALSE;
+static void mud_telnet_on_enable_opt       (MudTelnet *telnet,
+				            const guchar opt_no);
 
-    telnet->buffer = NULL;
-    telnet->pos = 0;
-    telnet->subreq_pos = 0;
+static void mud_telnet_on_disable_opt      (MudTelnet *telnet,
+				            const guchar opt_no);
 
-    telnet->zmp_commands = NULL;
 
-    telnet->processed = g_string_new(NULL);
+static gboolean mud_telnet_isenabled       (MudTelnet *telnet,
+                                            gint option_number);
 
-#ifdef ENABLE_GST
-    telnet->sound[0].files = NULL;
-    telnet->sound[0].current_command = NULL;
-    telnet->sound[0].playing = FALSE;
-    telnet->sound[0].files_len = 0;
-
-    telnet->sound[1].files = NULL;
-    telnet->sound[1].current_command = NULL;
-    telnet->sound[1].playing = FALSE;
-    telnet->sound[1].files_len = 0;
-
-    telnet->prev_buffer = NULL;
-    telnet->base_url = NULL;
-    telnet->msp_parser.enabled = FALSE;
 
-#endif
+static void mud_telnet_unref_handler       (gpointer data);
 
-#ifdef ENABLE_MCCP
-    telnet->mccp_new = TRUE;
-#endif
-}
 
+/* Class Functions */
 static void
 mud_telnet_class_init (MudTelnetClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS(klass);
 
+    /* Override base object constructor */
+    object_class->constructor = mud_telnet_constructor;
+
+    /* Override base object's finalize */
     object_class->finalize = mud_telnet_finalize;
+
+    /* Override base object property methods */
+    object_class->set_property = mud_telnet_set_property;
+    object_class->get_property = mud_telnet_get_property;
+
+    /* Add private data to class */
+    g_type_class_add_private(klass, sizeof(MudTelnetPrivate));
+
+    /* Install Properties */
+    g_object_class_install_property(object_class,
+            PROP_PARENT_VIEW,
+            g_param_spec_object("parent-view",
+                "parent view",
+                "the parent mudconnectionview",
+                MUD_TYPE_CONNECTION_VIEW,
+                G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
+
+    g_object_class_install_property(object_class,
+            PROP_GA_RECEIVED,
+            g_param_spec_boolean("ga-received",
+                "ga received",
+                "set if GA has been received",
+                FALSE,
+                G_PARAM_READABLE));
+
+    g_object_class_install_property(object_class,
+            PROP_EOR_RECEIVED,
+            g_param_spec_boolean("eor-received",
+                "eor received",
+                "set if EOR has been received",
+                FALSE,
+                G_PARAM_READABLE));
+
+    g_object_class_install_property(object_class,
+            PROP_CONNECTION,
+            g_param_spec_pointer("connection",
+                "Connection",
+                "The Connection Object to the MUD",
+                G_PARAM_READABLE));
 }
 
 static void
-mud_telnet_finalize (GObject *object)
+mud_telnet_init (MudTelnet *telnet)
 {
-    MudTelnet *telnet;
-    GObjectClass *parent_class;
+    /* Get our private data */
+    telnet->priv = MUD_TELNET_GET_PRIVATE(telnet);
 
-    telnet = MUD_TELNET(object);
-
-    if(telnet->processed)
-        g_string_free(telnet->processed, TRUE);
+    /* Set some defaults */
 
-    if(telnet->buffer)
-        g_string_free(telnet->buffer, TRUE);
+    telnet->parent_view = NULL;
+    telnet->ga_received = FALSE;
+    telnet->eor_received = FALSE;
+
+    telnet->priv->pos = 0;
+    telnet->priv->buffer = NULL;
+    telnet->priv->subreq_pos = 0;
+    telnet->priv->tel_state = TEL_STATE_TEXT;
+    telnet->priv->processed = g_string_new(NULL);
+}
+
+static GObject *
+mud_telnet_constructor (GType gtype,
+                        guint n_properties,
+                        GObjectConstructParam *properties)
+{
+    MudTelnet *self;
+    GObject *obj;
+    MudTelnetClass *klass;
+    GObjectClass *parent_class;
 
-    if(telnet->mud_name)
-        g_free(telnet->mud_name);
+    /* Chain up to parent constructor */
+    klass = MUD_TELNET_CLASS( g_type_class_peek(MUD_TYPE_TELNET) );
+    parent_class = G_OBJECT_CLASS( g_type_class_peek_parent(klass) );
+    obj = parent_class->constructor(gtype, n_properties, properties);
 
-#ifdef ENABLE_GST
-    mud_telnet_msp_stop_playing(telnet, MSP_TYPE_SOUND);
-    mud_telnet_msp_stop_playing(telnet, MSP_TYPE_MUSIC);
-    
-    if(telnet->prev_buffer)
-        g_string_free(telnet->prev_buffer, TRUE);
-    if(telnet->base_url)
-        g_free(telnet->base_url);
-#endif
+    self = MUD_TELNET(obj);
 
-#ifdef ENABLE_MCCP
-    if(telnet->compress_out != NULL)
+    if(!self->parent_view)
     {
-        inflateEnd(telnet->compress_out);
-
-        g_free(telnet->compress_out);
-        g_free(telnet->compress_out_buf);
+        g_printf("ERROR: Tried to instantiate MudTelnet without passing parent view\n");
+        g_error("Tried to instantiate MudTelnet without passing parent view");
     }
-#endif
 
-    mud_zmp_finalize(telnet);
+    self->priv->handlers = g_hash_table_new_full(g_direct_hash,
+                                                 g_direct_equal,
+                                                 NULL,
+                                                 mud_telnet_unref_handler);
 
-    g_free(telnet->priv);
+    memset(self->priv->telopt_states, 0, sizeof(self->priv->telopt_states));
 
-    parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
-    parent_class->finalize(object);
-}
+    mud_telnet_register_handlers(self);
 
-/*** Public Methods ***/
+    g_object_get(self->parent_view,
+                 "connection", &self->priv->conn,
+                 "mud-name", &self->priv->mud_name,
+                 NULL);
+
+    return obj;
+}
 
-// Instantiate MudTelnet
-MudTelnet*
-mud_telnet_new(MudConnectionView *parent, GConn *connection, gchar *mud_name)
+static void
+mud_telnet_finalize (GObject *object)
 {
     MudTelnet *telnet;
+    GObjectClass *parent_class;
 
-    telnet = g_object_new(MUD_TYPE_TELNET, NULL);
+    telnet = MUD_TELNET(object);
 
-    telnet->parent = parent;
-    telnet->mud_name = g_strdup(mud_name);
-    telnet->conn = connection;
+    if(telnet->priv->processed)
+        g_string_free(telnet->priv->processed, TRUE);
 
-    return telnet;
-}
+    if(telnet->priv->buffer)
+        g_string_free(telnet->priv->buffer, TRUE);
 
-void
-mud_telnet_register_handlers(MudTelnet *telnet)
-{
-    gint i;
+    if(telnet->priv->mud_name)
+        g_free(telnet->priv->mud_name);
 
-    for(i = 0; i < TEL_HANDLERS_SIZE; ++i)
-    {
-        telnet->handlers[i].type = HANDLER_NONE;
-        telnet->handlers[i].enabled = FALSE;
-        telnet->handlers[i].instance = NULL;
-        telnet->handlers[i].enable = NULL;
-        telnet->handlers[i].disable = NULL;
-        telnet->handlers[i].handle_sub_neg = NULL;
-    }
+    g_hash_table_destroy(telnet->priv->handlers);
 
-    /* TTYPE */
-    telnet->handlers[0].type = HANDLER_TTYPE;
-    telnet->handlers[0].option_number = (guchar)TELOPT_TTYPE;
-    telnet->handlers[0].enabled = TRUE;
-    telnet->handlers[0].enable = MudHandler_TType_Enable;
-    telnet->handlers[0].disable = MudHandler_TType_Disable;
-    telnet->handlers[0].handle_sub_neg = MudHandler_TType_HandleSubNeg;
-    
-    /* NAWS */
-    telnet->handlers[1].type = HANDLER_NAWS;
-    telnet->handlers[1].option_number = (guchar)TELOPT_NAWS;
-    telnet->handlers[1].enabled = TRUE;
-    telnet->handlers[1].enable = MudHandler_NAWS_Enable;
-    telnet->handlers[1].disable = MudHandler_NAWS_Disable;
-    telnet->handlers[1].handle_sub_neg = MudHandler_NAWS_HandleSubNeg;
+    parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
+    parent_class->finalize(object);
+}
 
-    /* ECHO */
-    telnet->handlers[2].type = HANDLER_ECHO;
-    telnet->handlers[2].option_number = (guchar)TELOPT_ECHO;
-    telnet->handlers[2].enabled = TRUE;
-    telnet->handlers[2].enable = MudHandler_ECHO_Enable;
-    telnet->handlers[2].disable = MudHandler_ECHO_Disable;
-    telnet->handlers[2].handle_sub_neg = MudHandler_ECHO_HandleSubNeg;
+static void
+mud_telnet_set_property(GObject *object,
+                        guint prop_id,
+                        const GValue *value,
+                        GParamSpec *pspec)
+{
+    MudTelnet *self;
 
-    /* EOR */
-    telnet->handlers[3].type = HANDLER_EOR;
-    telnet->handlers[3].option_number = (guchar)TELOPT_EOR;
-    telnet->handlers[3].enabled = TRUE;
-    telnet->handlers[3].enable = MudHandler_EOR_Enable;
-    telnet->handlers[3].disable = MudHandler_EOR_Disable;
-    telnet->handlers[3].handle_sub_neg = MudHandler_EOR_HandleSubNeg;
+    self = MUD_TELNET(object);
 
-    /* CHARSET */
-    telnet->handlers[4].type = HANDLER_CHARSET;
-    telnet->handlers[4].option_number = (guchar)TELOPT_CHARSET;
-    telnet->handlers[4].enabled = TRUE;
-    telnet->handlers[4].enable = MudHandler_CHARSET_Enable;
-    telnet->handlers[4].disable = MudHandler_CHARSET_Disable;
-    telnet->handlers[4].handle_sub_neg = MudHandler_CHARSET_HandleSubNeg;
+    switch(prop_id)
+    {
+        /* Parent is Construct Only */
+        case PROP_PARENT_VIEW:
+            self->parent_view = MUD_CONNECTION_VIEW(g_value_get_object(value));
+            break;
 
-    /* ZMP */
-    telnet->handlers[5].type = HANDLER_ZMP;
-    telnet->handlers[5].option_number = (guchar)TELOPT_ZMP;
-    telnet->handlers[5].enabled = TRUE;
-    telnet->handlers[5].enable = MudHandler_ZMP_Enable;
-    telnet->handlers[5].disable = MudHandler_ZMP_Disable;
-    telnet->handlers[5].handle_sub_neg = MudHandler_ZMP_HandleSubNeg;
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
+}
 
-#ifdef ENABLE_GST
-    /* MSP */
-    telnet->handlers[6].type = HANDLER_MSP;
-    telnet->handlers[6].option_number = (guchar)TELOPT_MSP;
-    telnet->handlers[6].enabled = TRUE;
-    telnet->handlers[6].enable = MudHandler_MSP_Enable;
-    telnet->handlers[6].disable = MudHandler_MSP_Disable;
-    telnet->handlers[6].handle_sub_neg = MudHandler_MSP_HandleSubNeg;
-#endif
+static void
+mud_telnet_get_property(GObject *object,
+                        guint prop_id,
+                        GValue *value,
+                        GParamSpec *pspec)
+{
+    MudTelnet *self;
 
-#ifdef ENABLE_MCCP
-    /* MCCP */
-    telnet->handlers[7].type = HANDLER_MCCP2;
-    telnet->handlers[7].option_number = (guchar)TELOPT_MCCP2;
-    telnet->handlers[7].enabled = TRUE;
-    telnet->handlers[7].enable = MudHandler_MCCP_Enable;
-    telnet->handlers[7].disable = MudHandler_MCCP_Disable;
-    telnet->handlers[7].handle_sub_neg = MudHandler_MCCP_HandleSubNeg;
-#endif
+    self = MUD_TELNET(object);
 
-}
+    switch(prop_id)
+    {
+        case PROP_PARENT_VIEW:
+            g_value_take_object(value, self->parent_view);
+            break;
 
-gint
-mud_telnet_isenabled(MudTelnet *telnet, guint8 option_number, gint him)
-{
-    gint i;
+        case PROP_GA_RECEIVED:
+            g_value_set_boolean(value, self->ga_received);
+            break;
+
+        case PROP_EOR_RECEIVED:
+            g_value_set_boolean(value, self->eor_received);
+            break;
 
-    for(i = 0; i < TEL_HANDLERS_SIZE; ++i)
-        if(telnet->handlers[i].type != HANDLER_NONE)
-            if(option_number == telnet->handlers[i].option_number)
-                return telnet->handlers[i].enabled;
+        case PROP_CONNECTION:
+            g_value_set_pointer(value, self->priv->conn);
+            break;
 
-    return FALSE;
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+            break;
+    }
 }
 
+/*** Public Methods ***/
 void
 mud_telnet_get_parent_size(MudTelnet *telnet, gint *w, gint *h)
 {
-    mud_connection_view_get_term_size(telnet->parent, w, h);
-}
+    g_return_if_fail(MUD_IS_TELNET(telnet));
 
-void
-mud_telnet_set_parent_naws(MudTelnet *telnet, gint enabled)
-{
-    mud_connection_view_set_naws(telnet->parent, enabled);
+    mud_connection_view_get_term_size(telnet->parent_view, w, h);
 }
 
 void
-mud_telnet_set_parent_remote_encode(MudTelnet *telnet, gint enabled, gchar *encoding)
+mud_telnet_send_naws(MudTelnet *telnet, gint width, gint height)
 {
-    telnet->parent->remote_encode = enabled;
+    MudTelnetHandler *handler;
+    
+    g_return_if_fail(MUD_IS_TELNET(telnet));
 
-    if(enabled)
-        telnet->parent->remote_encoding = g_strdup(encoding);
-    else if(telnet->parent->remote_encoding)
-        g_free(telnet->parent->remote_encoding);
-}
+    handler = MUD_TELNET_HANDLER(
+                g_hash_table_lookup(telnet->priv->handlers,
+                                    GINT_TO_POINTER(TELOPT_NAWS)));
+    if(!handler)
+        return;
 
-void
-mud_telnet_set_local_echo(MudTelnet *telnet, gint enabled)
-{
-    telnet->parent->local_echo = enabled;
+    mud_telnet_naws_send(MUD_TELNET_NAWS(handler), width, height);
 }
 
-void
-mud_telnet_send_naws(MudTelnet *telnet, gint width, gint height)
+MudTelnetHandler *
+mud_telnet_get_handler(MudTelnet *telnet, gint opt_no)
 {
-    guchar w1, h1, w0, h0;
+    MudTelnetHandler *handler;
 
-    w1 = (width >> 8) & 0xff;
-    w0 = width & 0xff;
+    if(!MUD_IS_TELNET(telnet))
+        return NULL;
 
-    h1 = (height >> 8) & 0xff;
-    h0 = height & 0xff;
-
-    mud_telnet_send_sub_req(telnet, 5, (guchar)TELOPT_NAWS, w1, w0, h1, h0);
+    handler = MUD_TELNET_HANDLER(
+            g_hash_table_lookup(telnet->priv->handlers,
+                                GINT_TO_POINTER(opt_no)));
+    return handler;
 }
 
 GString *
@@ -369,299 +378,313 @@
     guint32 count;
     gchar *opt;
 
-    g_assert(telnet != NULL);
+#ifdef ENABLE_MCCP
+    gboolean mccp_active, mccp_new;
+    MudTelnetMccp *mccp_handler;
+#endif
 
-    if(telnet->buffer != NULL)
-        g_string_free(telnet->buffer, TRUE);
+    g_assert(MUD_IS_TELNET(telnet));
 
-    telnet->buffer = g_string_new(NULL);
+    if(telnet->priv->buffer != NULL)
+    {
+        g_string_free(telnet->priv->buffer, TRUE);
+        telnet->priv->buffer = NULL;
+    }
+
+    telnet->priv->buffer = g_string_new(NULL);
 
 #ifdef ENABLE_MCCP
-    if(telnet->mccp)
+    mccp_active = FALSE;
+    mccp_new = TRUE;
+    mccp_handler = MUD_TELNET_MCCP(mud_telnet_get_handler(telnet, TELOPT_MCCP2));
+
+    if(mccp_handler != NULL)
+        g_object_get(mccp_handler,
+                "mccp-active", &mccp_active,
+                "mccp-new",    &mccp_new,
+                NULL);
+
+
+    if(mccp_active)
     {
         GString *ret = NULL;
 
         // decompress the buffer.
-        ret = mud_mccp_decompress(telnet, buf, c);
+        ret = mud_mccp_decompress(mccp_handler, buf, c);
 
-        telnet->mccp_new = FALSE;
+        g_object_set(mccp_handler, "mccp-new", FALSE, NULL);
 
         if(ret == NULL)
-        {
-            if(telnet->buffer)
-                g_string_free(telnet->buffer, TRUE);
-
             return ret;
-        }
         else
         {
-            telnet->buffer = g_string_append_len(telnet->buffer, ret->str, ret->len);
+            telnet->priv->buffer = g_string_append_len(telnet->priv->buffer, ret->str, ret->len);
             g_string_free(ret, TRUE);
         }
     }
     else
 #endif
-        telnet->buffer = g_string_append_len(telnet->buffer, (gchar *)buf, c);
+        telnet->priv->buffer = g_string_append_len(telnet->priv->buffer, (gchar *)buf, c);
 
-    count = telnet->buffer->len;
+    count = telnet->priv->buffer->len;
 
     for (i = 0; i < count; ++i)
     {
-        switch (telnet->tel_state)
+        if(mccp_handler)
+            g_object_get(mccp_handler, "mccp-active", &mccp_active, NULL);
+
+        switch (telnet->priv->tel_state)
         {
             case TEL_STATE_TEXT:
 #ifdef ENABLE_MCCP
                 /* The following is only done when compressing is first
                    enabled in order to decompress any part of the buffer
                    that remains after the subnegotation takes place */
-                if(telnet->mccp && telnet->mccp_new)
+
+                if(mccp_active && mccp_new)
                 {
                     GString *ret = NULL;
-                    telnet->mccp_new = FALSE;
+                    g_object_set(mccp_handler, "mccp-new", FALSE, NULL);
+
 
                     // decompress the rest of the buffer.
-                    ret = mud_mccp_decompress(telnet, &buf[i], count - i);
+                    ret = mud_mccp_decompress(mccp_handler, &buf[i], count - i);
 
-                    if(telnet->buffer)
+                    if(telnet->priv->buffer)
                     {
-                        g_string_free(telnet->buffer, TRUE);
-                        telnet->buffer = NULL;
+                        g_string_free(telnet->priv->buffer, TRUE);
+                        telnet->priv->buffer = NULL;
                     }
 
                     if(ret == NULL)
                     {
                         GString *ret_string =
-                            g_string_new_len(telnet->processed->str, telnet->pos);
+                            g_string_new_len(telnet->priv->processed->str, telnet->priv->pos);
 
-                        *len = telnet->pos;
-                        telnet->pos= 0;
+                        *len = telnet->priv->pos;
+                        telnet->priv->pos= 0;
 
-                        if(telnet->processed)
+                        if(telnet->priv->processed)
                         {
-                            g_string_free(telnet->processed, TRUE);
-                            telnet->processed = g_string_new(NULL);
+                            g_string_free(telnet->priv->processed, TRUE);
+                            telnet->priv->processed = g_string_new(NULL);
                         }
 
                         return ret_string;
                     }
 
-                    telnet->buffer = g_string_new(ret->str);
+                    telnet->priv->buffer = g_string_new(ret->str);
 
-                    if(telnet->buffer->len == 0)
+                    if(telnet->priv->buffer->len == 0)
                     {
                         GString *ret_string =
-                            g_string_new_len(telnet->processed->str, telnet->pos);
-                        *len = telnet->pos;
+                            g_string_new_len(telnet->priv->processed->str, telnet->priv->pos);
+                        *len = telnet->priv->pos;
 
-                        telnet->pos= 0;
+                        telnet->priv->pos= 0;
 
-                        if(telnet->processed)
+                        if(telnet->priv->processed)
                         {
-                            g_string_free(telnet->processed, TRUE);
-                            telnet->processed = g_string_new(NULL);
+                            g_string_free(telnet->priv->processed, TRUE);
+                            telnet->priv->processed = g_string_new(NULL);
                         }
 
-                        if(telnet->buffer)
+                        if(telnet->priv->buffer)
                         {
-                            g_string_free(telnet->buffer, TRUE);
-                            telnet->buffer = NULL;
+                            g_string_free(telnet->priv->buffer, TRUE);
+                            telnet->priv->buffer = NULL;
                         }
                         return ret_string;
                     }
 
                     i = 0;
-                    count = telnet->buffer->len;
+                    count = telnet->priv->buffer->len;
                 }
 #endif
-                if ((guchar)telnet->buffer->str[i] == (guchar)TEL_IAC)
-                    telnet->tel_state = TEL_STATE_IAC;
+
+                if ((guchar)telnet->priv->buffer->str[i] == (guchar)TEL_IAC)
+                    telnet->priv->tel_state = TEL_STATE_IAC;
                 else
                 {
-                    telnet->processed = 
-                        g_string_append_c(telnet->processed, telnet->buffer->str[i]);
-                    telnet->pos++;
+                    telnet->priv->processed = 
+                        g_string_append_c(telnet->priv->processed, telnet->priv->buffer->str[i]);
+                    telnet->priv->pos++;
                 }
                 break;
 
             case TEL_STATE_IAC:
-                switch ((guchar)telnet->buffer->str[i])
+                switch ((guchar)telnet->priv->buffer->str[i])
                 {
                     case (guchar)TEL_IAC:
-                        telnet->pos++;
-                        telnet->processed = 
-                            g_string_append_c(telnet->processed, telnet->buffer->str[i]);
-                        telnet->tel_state = TEL_STATE_TEXT;
+                        telnet->priv->pos++;
+                        telnet->priv->processed = 
+                            g_string_append_c(telnet->priv->processed, telnet->priv->buffer->str[i]);
+                        telnet->priv->tel_state = TEL_STATE_TEXT;
                         break;
 
                     case (guchar)TEL_DO:
-                        telnet->tel_state = TEL_STATE_DO;
+                        telnet->priv->tel_state = TEL_STATE_DO;
                         break;
 
                     case (guchar)TEL_DONT:
-                        telnet->tel_state = TEL_STATE_DONT;
+                        telnet->priv->tel_state = TEL_STATE_DONT;
                         break;
 
                     case (guchar)TEL_WILL:
-                        telnet->tel_state = TEL_STATE_WILL;
+                        telnet->priv->tel_state = TEL_STATE_WILL;
                         break;
 
                     case (guchar)TEL_NOP:
-                        telnet->tel_state = TEL_STATE_TEXT;
+                        telnet->priv->tel_state = TEL_STATE_TEXT;
                         break;
 
                     case (guchar)TEL_GA:
                         // TODO: Hook up to triggers.
-                        telnet->tel_state = TEL_STATE_TEXT;
+                        telnet->priv->tel_state = TEL_STATE_TEXT;
                         break;
 
                     case (guchar)TEL_EOR_BYTE:
                         // TODO: Hook up to triggers.
-                        telnet->tel_state = TEL_STATE_TEXT;
+                        telnet->priv->tel_state = TEL_STATE_TEXT;
                         break;
 
                     case (guchar)TEL_WONT:
-                        telnet->tel_state = TEL_STATE_WONT;
+                        telnet->priv->tel_state = TEL_STATE_WONT;
                         break;
 
                     case (guchar)TEL_SB:
-                        telnet->tel_state = TEL_STATE_SB;
-                        telnet->subreq_pos = 0;
+                        telnet->priv->tel_state = TEL_STATE_SB;
+                        telnet->priv->subreq_pos = 0;
                         break;
 
                     default:
-                        g_warning("Illegal IAC command %d received", telnet->buffer->str[i]);
-                        telnet->tel_state = TEL_STATE_TEXT;
+                        g_warning("Illegal IAC command %d received", telnet->priv->buffer->str[i]);
+                        telnet->priv->tel_state = TEL_STATE_TEXT;
                         break;
                 }
                 break;
 
             case TEL_STATE_DO:
-                opt = mud_telnet_get_telopt_string((guchar)telnet->buffer->str[i]);
+                opt = mud_telnet_get_telopt_string((guchar)telnet->priv->buffer->str[i]);
                 g_log("Telnet", G_LOG_LEVEL_MESSAGE, "Recieved: DO %s", opt);
                 g_free(opt);
 
                 mud_telnet_handle_positive_nego(
                         telnet,
-                        (guchar)telnet->buffer->str[i],
+                        (guchar)telnet->priv->buffer->str[i],
                         (guchar)TEL_WILL,
                         (guchar)TEL_WONT, FALSE);
 
-                telnet->tel_state = TEL_STATE_TEXT;
+                telnet->priv->tel_state = TEL_STATE_TEXT;
                 break;
 
             case TEL_STATE_WILL:
-                opt = mud_telnet_get_telopt_string((guchar)telnet->buffer->str[i]);
+                opt = mud_telnet_get_telopt_string((guchar)telnet->priv->buffer->str[i]);
                 g_log("Telnet", G_LOG_LEVEL_MESSAGE, "Recieved: WILL %s", opt);
                 g_free(opt);
 
                 mud_telnet_handle_positive_nego(
                         telnet,
-                        (guchar)telnet->buffer->str[i],
+                        (guchar)telnet->priv->buffer->str[i],
                         (guchar)TEL_DO,
                         (guchar)TEL_DONT, TRUE);
 
-                telnet->tel_state = TEL_STATE_TEXT;
+                telnet->priv->tel_state = TEL_STATE_TEXT;
                 break;
 
             case TEL_STATE_DONT:
-                opt = mud_telnet_get_telopt_string((guchar)telnet->buffer->str[i]);
+                opt = mud_telnet_get_telopt_string((guchar)telnet->priv->buffer->str[i]);
                 g_log("Telnet", G_LOG_LEVEL_MESSAGE, "Recieved: DONT %s", opt);
                 g_free(opt);
 
                 mud_telnet_handle_negative_nego(
                         telnet,
-                        (guchar)telnet->buffer->str[i],
+                        (guchar)telnet->priv->buffer->str[i],
                         (guchar)TEL_WILL,
                         (guchar)TEL_WONT, FALSE);
 
-                telnet->tel_state = TEL_STATE_TEXT;
+                telnet->priv->tel_state = TEL_STATE_TEXT;
                 break;
 
             case TEL_STATE_WONT:
-                opt = mud_telnet_get_telopt_string((guchar)telnet->buffer->str[i]);
+                opt = mud_telnet_get_telopt_string((guchar)telnet->priv->buffer->str[i]);
                 g_log("Telnet", G_LOG_LEVEL_MESSAGE, "Recieved: WONT %s", opt);
                 g_free(opt);
 
                 mud_telnet_handle_negative_nego(
                         telnet,
-                        (guchar)telnet->buffer->str[i],
+                        (guchar)telnet->priv->buffer->str[i],
                         (guchar)TEL_DO,
                         (guchar)TEL_DONT, TRUE);
 
-                telnet->tel_state = TEL_STATE_TEXT;
+                telnet->priv->tel_state = TEL_STATE_TEXT;
                 break;
 
             case TEL_STATE_SB:
-                if ((guchar)telnet->buffer->str[i] == (guchar)TEL_IAC)
-                    telnet->tel_state = TEL_STATE_SB_IAC;
+                if ((guchar)telnet->priv->buffer->str[i] == (guchar)TEL_IAC)
+                    telnet->priv->tel_state = TEL_STATE_SB_IAC;
                 else
                 {
                     // FIXME: Handle overflow
-                    if (telnet->subreq_pos >= TEL_SUBREQ_BUFFER_SIZE)
+                    if (telnet->priv->subreq_pos >= TEL_SUBREQ_BUFFER_SIZE)
                     {
                         g_warning("Subrequest buffer full. Oddities in output will happen. Sorry.");
-                        telnet->subreq_pos = 0;
-                        telnet->tel_state = TEL_STATE_TEXT;
+                        telnet->priv->subreq_pos = 0;
+                        telnet->priv->tel_state = TEL_STATE_TEXT;
                     }
                     else
-                        telnet->subreq_buffer[telnet->subreq_pos++] =
-                            (guchar)telnet->buffer->str[i];
+                        telnet->priv->subreq_buffer[telnet->priv->subreq_pos++] =
+                            (guchar)telnet->priv->buffer->str[i];
                 }
                 break;
 
             case TEL_STATE_SB_IAC:
-                if ((guchar)telnet->buffer->str[i] == (guchar)TEL_IAC)
+                if ((guchar)telnet->priv->buffer->str[i] == (guchar)TEL_IAC)
                 {
-                    if (telnet->subreq_pos >= TEL_SUBREQ_BUFFER_SIZE)
+                    if (telnet->priv->subreq_pos >= TEL_SUBREQ_BUFFER_SIZE)
                     {
                         g_warning("Subrequest buffer full. Oddities in output will happen. Sorry.");
-                        telnet->subreq_pos = 0;
-                        telnet->tel_state = TEL_STATE_TEXT;
+                        telnet->priv->subreq_pos = 0;
+                        telnet->priv->tel_state = TEL_STATE_TEXT;
                     }
                     else
-                        telnet->subreq_buffer[telnet->subreq_pos++] =
-                            (guchar)telnet->buffer->str[i];
+                        telnet->priv->subreq_buffer[telnet->priv->subreq_pos++] =
+                            (guchar)telnet->priv->buffer->str[i];
 
-                    telnet->tel_state = TEL_STATE_SB;
+                    telnet->priv->tel_state = TEL_STATE_SB;
                 }
-                else if ((guchar)telnet->buffer->str[i] == (guchar)TEL_SE)
+                else if ((guchar)telnet->priv->buffer->str[i] == (guchar)TEL_SE)
                 {
-                    telnet->subreq_buffer[telnet->subreq_pos++] =
-                        (guchar)telnet->buffer->str[i];
+                    telnet->priv->subreq_buffer[telnet->priv->subreq_pos++] =
+                        (guchar)telnet->priv->buffer->str[i];
 
                     mud_telnet_on_handle_subnego(telnet);
 
-                    telnet->subreq_pos = 0;
-                    telnet->tel_state = TEL_STATE_TEXT;
+                    telnet->priv->subreq_pos = 0;
+                    telnet->priv->tel_state = TEL_STATE_TEXT;
                 } else {
                     g_warning("Erronous byte %d after an IAC inside a subrequest",
-                            telnet->buffer->str[i]);
+                            telnet->priv->buffer->str[i]);
 
-                    telnet->subreq_pos = 0;
-                    telnet->tel_state = TEL_STATE_TEXT;
+                    telnet->priv->subreq_pos = 0;
+                    telnet->priv->tel_state = TEL_STATE_TEXT;
                 }
                 break;
         }
     }
 
-    if(telnet->buffer)
-    {
-        g_string_free(telnet->buffer, TRUE);
-        telnet->buffer = NULL;
-    }
-
-    if(telnet->tel_state == TEL_STATE_TEXT)
+    if(telnet->priv->tel_state == TEL_STATE_TEXT)
     {
         GString *ret =
-            g_string_new_len(telnet->processed->str, telnet->pos);
-        *len = telnet->pos;
+            g_string_new_len(telnet->priv->processed->str, telnet->priv->pos);
+        *len = telnet->priv->pos;
 
-        telnet->pos= 0;
+        telnet->priv->pos= 0;
 
-        if(telnet->processed)
+        if(telnet->priv->processed)
         {
-            g_string_free(telnet->processed, TRUE);
-            telnet->processed = g_string_new(NULL);
+            g_string_free(telnet->priv->processed, TRUE);
+            telnet->priv->processed = g_string_new(NULL);
         }
 
         return ret;
@@ -670,11 +693,131 @@
     return NULL;
 }
 
-gchar*
+void
+mud_telnet_send_sub_req(MudTelnet *telnet, guint32 count, ...)
+{
+    guchar byte;
+    guint32 i;
+    va_list va;
+
+    g_return_if_fail(MUD_IS_TELNET(telnet));
+
+    va_start(va, count);
+
+    g_log("Telnet", G_LOG_LEVEL_DEBUG, "Sending Subreq...");
+    
+    byte = (guchar)TEL_IAC;
+
+    gnet_conn_write(telnet->priv->conn, (gchar *)&byte, 1);
+    byte = (guchar)TEL_SB;
+    gnet_conn_write(telnet->priv->conn, (gchar *)&byte, 1);
+
+    for (i = 0; i < count; ++i)
+    {
+	byte = (guchar)va_arg(va, gint);
+	gnet_conn_write(telnet->priv->conn, (gchar *)&byte, 1);
+
+	if (byte == (guchar)TEL_IAC)
+	    gnet_conn_write(telnet->priv->conn, (gchar *)&byte, 1);
+    }
+
+    va_end(va);
+
+    byte = (guchar)TEL_IAC;
+    gnet_conn_write(telnet->priv->conn, (gchar *)&byte, 1);
+    byte = (guchar)TEL_SE;
+    gnet_conn_write(telnet->priv->conn, (gchar *)&byte, 1);
+}
+
+void
+mud_telnet_send_raw(MudTelnet *telnet, guint32 count, ...)
+{
+    guchar byte;
+    guint32 i;
+    va_list va;
+
+    g_return_if_fail(MUD_IS_TELNET(telnet));
+
+    va_start(va, count);
+
+    for (i = 0; i < count; ++i)
+    {
+	byte = (guchar)va_arg(va, gint);
+	gnet_conn_write(telnet->priv->conn, (gchar *)&byte, 1);
+
+	if (byte == (guchar)TEL_IAC)
+	    gnet_conn_write(telnet->priv->conn, (gchar *)&byte, 1);
+    }
+
+    va_end(va);
+}
+
+/*** Private Methods ***/
+static void
+mud_telnet_register_handlers(MudTelnet *telnet)
+{
+    g_return_if_fail(MUD_IS_TELNET(telnet));
+
+    /* TTYPE */
+    g_hash_table_replace(telnet->priv->handlers,
+                         GINT_TO_POINTER(TELOPT_TTYPE),
+                         g_object_new(MUD_TYPE_TELNET_TTYPE,
+                                      "telnet", telnet,
+                                      NULL));
+    /* NAWS */
+    g_hash_table_replace(telnet->priv->handlers,
+                         GINT_TO_POINTER(TELOPT_NAWS),
+                         g_object_new(MUD_TYPE_TELNET_NAWS,
+                                      "telnet", telnet,
+                                      NULL));
+    /* ECHO */
+    g_hash_table_replace(telnet->priv->handlers,
+                         GINT_TO_POINTER(TELOPT_ECHO),
+                         g_object_new(MUD_TYPE_TELNET_ECHO,
+                                      "telnet", telnet,
+                                      NULL));
+    /* EOR */
+    g_hash_table_replace(telnet->priv->handlers,
+                         GINT_TO_POINTER(TELOPT_EOR),
+                         g_object_new(MUD_TYPE_TELNET_EOR,
+                                      "telnet", telnet,
+                                      NULL));
+    /* CHARSET */
+    g_hash_table_replace(telnet->priv->handlers,
+                         GINT_TO_POINTER(TELOPT_CHARSET),
+                         g_object_new(MUD_TYPE_TELNET_CHARSET,
+                                      "telnet", telnet,
+                                      NULL));
+    /* ZMP */
+    g_hash_table_replace(telnet->priv->handlers,
+                         GINT_TO_POINTER(TELOPT_ZMP),
+                         g_object_new(MUD_TYPE_TELNET_ZMP,
+                                      "telnet", telnet,
+                                      NULL));
+#ifdef ENABLE_GST
+    /* MSP */
+    g_hash_table_replace(telnet->priv->handlers,
+                         GINT_TO_POINTER(TELOPT_MSP),
+                         g_object_new(MUD_TYPE_TELNET_MSP,
+                                      "telnet", telnet,
+                                      NULL));
+#endif
+
+#ifdef ENABLE_MCCP
+    /* MCCP2 */
+    g_hash_table_replace(telnet->priv->handlers,
+                         GINT_TO_POINTER(TELOPT_MCCP2),
+                         g_object_new(MUD_TYPE_TELNET_MCCP,
+                                      "telnet", telnet,
+                                      NULL));
+#endif
+
+}
+
+static gchar *
 mud_telnet_get_telnet_string(guchar ch)
 {
     GString *string = g_string_new(NULL);
-    gchar *ret;
 
     switch (ch)
     {
@@ -698,13 +841,10 @@
             break;
     }
 
-    ret = g_strdup(string->str);
-    g_string_free(string, TRUE);
-
-    return ret;
+    return g_string_free(string, FALSE);
 }
 
-gchar*
+static gchar*
 mud_telnet_get_telopt_string(guchar ch)
 {
     GString *string = g_string_new(NULL);
@@ -739,14 +879,6 @@
             string = g_string_append(string, "COMPRESS2");
             break;
 
-        case TELOPT_CLIENT:
-            string = g_string_append(string, "CLIENT");
-            break;
-
-        case TELOPT_CLIENTVER:
-            string = g_string_append(string, "CLIENTVER");
-            break;
-
         case TELOPT_MSP:
             string = g_string_append(string, "MSP");
             break;
@@ -767,97 +899,6 @@
     return g_string_free(string, FALSE);
 }
 
-void
-mud_telnet_send_charset_req(MudTelnet *telnet, gchar *encoding)
-{
-    guchar byte;
-    guint32 i;
-
-    if(!encoding)
-	return;
-
-    g_log("Telnet", G_LOG_LEVEL_DEBUG, "Sending Charset Accepted SubReq");
-
-    /* Writes IAC SB CHARSET ACCEPTED <charset> IAC SE to server */
-    byte = (guchar)TEL_IAC;
-
-    gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
-    byte = (guchar)TEL_SB;
-    gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
-    byte = (guchar)TELOPT_CHARSET;
-    gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
-    byte = (guchar)TEL_CHARSET_ACCEPT;
-    gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
-
-    for (i = 0; i < strlen(encoding); ++i)
-    {
-	byte = (guchar)encoding[i];
-	gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
-
-	if (byte == (guchar)TEL_IAC)
-	    gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
-    }
-
-    byte = (guchar)TEL_IAC;
-    gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
-    byte = (guchar)TEL_SE;
-    gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
-}
-
-void
-mud_telnet_send_sub_req(MudTelnet *telnet, guint32 count, ...)
-{
-    guchar byte;
-    guint32 i;
-    va_list va;
-    va_start(va, count);
-
-    g_log("Telnet", G_LOG_LEVEL_DEBUG, "Sending Subreq...");
-    
-    byte = (guchar)TEL_IAC;
-
-    gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
-    byte = (guchar)TEL_SB;
-    gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
-
-    for (i = 0; i < count; ++i)
-    {
-	byte = (guchar)va_arg(va, gint);
-	gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
-
-	if (byte == (guchar)TEL_IAC)
-	    gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
-    }
-
-    va_end(va);
-
-    byte = (guchar)TEL_IAC;
-    gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
-    byte = (guchar)TEL_SE;
-    gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
-}
-
-void
-mud_telnet_send_raw(MudTelnet *telnet, guint32 count, ...)
-{
-    guchar byte;
-    guint32 i;
-    va_list va;
-    va_start(va, count);
-
-    for (i = 0; i < count; ++i)
-    {
-	byte = (guchar)va_arg(va, gint);
-	gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
-
-	if (byte == (guchar)TEL_IAC)
-	    gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
-    }
-
-    va_end(va);
-}
-
-/*** Private Methods ***/
 static void
 mud_telnet_send_iac(MudTelnet *telnet, guchar ch1, guchar ch2)
 {
@@ -866,54 +907,107 @@
     buf[1] = ch1;
     buf[2] = ch2;
 
-    gnet_conn_write(telnet->conn, (gchar *)buf, 3);
+    gnet_conn_write(telnet->priv->conn, (gchar *)buf, 3);
+}
+
+static void
+mud_telnet_unref_handler(gpointer data)
+{
+    MudTelnetHandler *handler = MUD_TELNET_HANDLER(data);
+
+    g_object_unref(handler);
 }
 
 static void
 mud_telnet_on_handle_subnego(MudTelnet *telnet)
 {
-    int index;
+    MudTelnetHandler *handler;
+    gboolean enabled;
+
+    g_return_if_fail(MUD_IS_TELNET(telnet));
 
-    if (telnet->subreq_pos < 1)
+    if (telnet->priv->subreq_pos < 1)
 	return;
 
-    if((index = mud_telnet_get_index_by_option(telnet, telnet->subreq_buffer[0])) == -1)
+    handler = 
+        MUD_TELNET_HANDLER(
+                g_hash_table_lookup(telnet->priv->handlers,
+                                    GINT_TO_POINTER(
+                                        (gint)telnet->priv->subreq_buffer[0])));
+
+    if(!handler)
     {
-        g_warning("Invalid Telnet Option passed: %d", telnet->subreq_buffer[0]);
+        g_warning("Invalid Telnet Option passed: %d", telnet->priv->subreq_buffer[0]);
         return;
     }
 
-    if (mud_telnet_isenabled(telnet, telnet->subreq_buffer[0], FALSE))
-        telnet->handlers[index].handle_sub_neg(telnet, telnet->subreq_buffer + 1,
-					       telnet->subreq_pos - 1, &telnet->handlers[index]);
+    g_object_get(handler, "enabled", &enabled, NULL);
+
+    if(enabled)
+        mud_telnet_handler_handle_sub_neg(handler,
+                telnet->priv->subreq_buffer + 1,
+                telnet->priv->subreq_pos - 1);
 }
 
 static void
-mud_telnet_on_enable_opt(MudTelnet *telnet, const guchar opt_no, gint him)
+mud_telnet_on_enable_opt(MudTelnet *telnet, const guchar opt_no)
 {
-    int index;
+    MudTelnetHandler *handler;
+
+    g_return_if_fail(MUD_IS_TELNET(telnet));
 
-    if((index = mud_telnet_get_index_by_option(telnet, opt_no)) == -1)
+    handler = MUD_TELNET_HANDLER(
+            g_hash_table_lookup(telnet->priv->handlers,
+                                GINT_TO_POINTER((gint)opt_no)));
+
+    if(!handler)
     {
         g_warning("Invalid Telnet Option passed: %d", opt_no);
         return;
     }
 
-    telnet->handlers[index].enable(telnet, &telnet->handlers[index]);
+    mud_telnet_handler_enable(handler);
 }
 
+
 static void
-mud_telnet_on_disable_opt(MudTelnet *telnet, const guchar opt_no, gint him)
+mud_telnet_on_disable_opt(MudTelnet *telnet, const guchar opt_no)
 {
-    int index;
+    MudTelnetHandler *handler;
+
+    g_return_if_fail(MUD_IS_TELNET(telnet));
 
-    if((index = mud_telnet_get_index_by_option(telnet, opt_no)) == -1)
+    handler = MUD_TELNET_HANDLER(
+            g_hash_table_lookup(telnet->priv->handlers,
+                                GINT_TO_POINTER((gint)opt_no)));
+
+    if(!handler)
     {
         g_warning("Invalid Telnet Option passed: %d", opt_no);
         return;
     }
 
-    telnet->handlers[index].disable(telnet, &telnet->handlers[index]);
+    mud_telnet_handler_disable(handler);
+}
+
+static gboolean
+mud_telnet_isenabled(MudTelnet *telnet, gint option_number)
+{
+    MudTelnetHandler *handler;
+    gboolean enabled;
+
+    if(!MUD_IS_TELNET(telnet))
+        return FALSE;
+
+    handler = MUD_TELNET_HANDLER(
+            g_hash_table_lookup(telnet->priv->handlers,
+                                GINT_TO_POINTER(option_number)));
+    if(!handler)
+        return FALSE;
+
+    g_object_get(handler, "enabled", &enabled, NULL);
+
+    return !enabled;
 }
 
 static guchar
@@ -929,7 +1023,8 @@
 }
 
 static void
-mud_telnet_set_telopt_state(guchar *storage, const enum TelnetOptionState state,
+mud_telnet_set_telopt_state(guchar *storage,
+                            const enum TelnetOptionState state,
 			    const guint bitshift)
 {
     *storage = (*storage & ~(0x03u << bitshift)) | (state << bitshift);
@@ -941,8 +1036,6 @@
     *storage = bit_on ? (*storage | (0x04u << bitshift)) : (*storage & ~(0x04u << bitshift));
 }
 
-// Otherwise handlers called on state changes could see the wrong options
-// (I think theoretically they should not care at all, but in practice...)
 static gint
 mud_telnet_handle_positive_nego(MudTelnet *telnet,
                                 const guchar opt_no,
@@ -951,90 +1044,99 @@
 				gint him)
 {
     const guint bitshift = him ? 4 : 0;
-    guchar * opt = &(telnet->telopt_states[opt_no]);
+    guchar *opt;
     gchar *tel_string, *opt_string;
 
+    if(!MUD_IS_TELNET(telnet))
+        return FALSE;
+
+    opt = &(telnet->priv->telopt_states[opt_no]);
+
     switch (mud_telnet_get_telopt_state(opt, bitshift))
     {
-    case TELOPT_STATE_NO:
-	// If we agree that server should enable telopt, set
-	// his state to YES and send DO; otherwise send DONT
-	// FIXME-US/HIM
-	// FIXME: What to do in the opposite "him" gint value case?
-	if (mud_telnet_isenabled(telnet, opt_no, him))
-	{
-            tel_string = mud_telnet_get_telnet_string(affirmative);
-            opt_string = mud_telnet_get_telopt_string(opt_no);
-            g_log("Telnet", G_LOG_LEVEL_DEBUG, "Sent: %s %s",
-                    tel_string, opt_string );
-            g_free(tel_string);
-            g_free(opt_string);
+        case TELOPT_STATE_NO:
+            // if we agree that server should enable telopt, set
+            // his state to yes and send do; otherwise send dont
+            // fixme-us/him
+            // fixme: what to do in the opposite "him" gint value case?
+            if (mud_telnet_isenabled(telnet, opt_no))
+            {
+                tel_string = mud_telnet_get_telnet_string(affirmative);
+                opt_string = mud_telnet_get_telopt_string(opt_no);
+                g_log("Telnet", G_LOG_LEVEL_DEBUG, "sent: %s %s",
+                        tel_string, opt_string );
+                g_free(tel_string);
+                g_free(opt_string);
+
+                mud_telnet_set_telopt_state(opt, TELOPT_STATE_YES, bitshift);
+                mud_telnet_send_iac(telnet, affirmative, opt_no);
+                mud_telnet_on_enable_opt(telnet, opt_no);
+                return TRUE;
+            } else {
+                tel_string = mud_telnet_get_telnet_string(negative);
+                opt_string = mud_telnet_get_telopt_string(opt_no);
+                g_log("Telnet", G_LOG_LEVEL_DEBUG, "sent: %s %s",
+                        tel_string, opt_string );
+                g_free(tel_string);
+                g_free(opt_string);
+
+                mud_telnet_send_iac(telnet, negative, opt_no);
+                return FALSE;
+            }
+            break;
 
-	    mud_telnet_set_telopt_state(opt, TELOPT_STATE_YES, bitshift);
-	    mud_telnet_send_iac(telnet, affirmative, opt_no);
-	    mud_telnet_on_enable_opt(telnet, opt_no, him);
-	    return TRUE;
-	} else {
-            tel_string = mud_telnet_get_telnet_string(negative);
-            opt_string = mud_telnet_get_telopt_string(opt_no);
-            g_log("Telnet", G_LOG_LEVEL_DEBUG, "Sent: %s %s",
-                    tel_string, opt_string );
-            g_free(tel_string);
-            g_free(opt_string);
+        case TELOPT_STATE_YES:
+            // ignore, he already supposedly has it enabled. includes the case where
+            // dont was answered by will with himq = opposite to prevent loop.
+            return FALSE;
+            break;
 
-	    mud_telnet_send_iac(telnet, negative, opt_no);
-	    return FALSE;
-	}
-
-    case TELOPT_STATE_YES:
-	// Ignore, he already supposedly has it enabled. Includes the case where
-	// DONT was answered by WILL with himq = OPPOSITE to prevent loop.
-	return FALSE;
-
-    case TELOPT_STATE_WANTNO:
-	if (mud_telnet_get_telopt_queue(opt, bitshift) == TELOPT_STATE_QUEUE_EMPTY)
-	{
-	    mud_telnet_set_telopt_state(opt, TELOPT_STATE_NO, bitshift);
-	    g_warning("TELNET NEGOTIATION: DONT answered by WILL; ill-behaved server. Ignoring IAC WILL %d. him = NO\n", opt_no);
-	    return FALSE;
-	} else { // The opposite is queued
-	    mud_telnet_set_telopt_state(opt, TELOPT_STATE_YES, bitshift);
-	    mud_telnet_set_telopt_queue(opt, TELOPT_STATE_QUEUE_EMPTY, bitshift);
-	    g_warning("TELNET NEGOTIATION: DONT answered by WILL; ill-behaved server. Ignoring IAC WILL %d. him = YES, himq = EMPTY\n", opt_no);
-	    return FALSE;
-	}
-	break;
-
-    case TELOPT_STATE_WANTYES:
-	if (mud_telnet_get_telopt_queue(opt, bitshift) == TELOPT_STATE_QUEUE_EMPTY)
-	{
-            tel_string = mud_telnet_get_telnet_string(affirmative);
-            opt_string = mud_telnet_get_telopt_string(opt_no);
-            g_log("Telnet", G_LOG_LEVEL_DEBUG, "Sent: %s %s",
-                    tel_string, opt_string );
-            g_free(tel_string);
-            g_free(opt_string);
+        case TELOPT_STATE_WANTNO:
+            if (mud_telnet_get_telopt_queue(opt, bitshift) == TELOPT_STATE_QUEUE_EMPTY)
+            {
+                mud_telnet_set_telopt_state(opt, TELOPT_STATE_NO, bitshift);
+                g_warning("telnet negotiation: dont answered by will; ill-behaved server. ignoring iac will %d. him = no\n", opt_no);
+                return FALSE;
+            } else { // the opposite is queued
+                mud_telnet_set_telopt_state(opt, TELOPT_STATE_YES, bitshift);
+                mud_telnet_set_telopt_queue(opt, TELOPT_STATE_QUEUE_EMPTY, bitshift);
+                g_warning("telnet negotiation: dont answered by will; ill-behaved server. ignoring iac will %d. him = yes, himq = empty\n", opt_no);
+                return FALSE;
+            }
+            break;
 
-	    mud_telnet_set_telopt_state(opt, TELOPT_STATE_YES, bitshift);
-	    mud_telnet_send_iac(telnet, affirmative, opt_no);
-	    mud_telnet_on_enable_opt(telnet, opt_no, him);
-	    return TRUE;
-	} else { // The opposite is queued
-            tel_string = mud_telnet_get_telnet_string(negative);
-            opt_string = mud_telnet_get_telopt_string(opt_no);
-            g_log("Telnet", G_LOG_LEVEL_DEBUG, "Sent: %s %s",
-                    tel_string, opt_string );
-            g_free(tel_string);
-            g_free(opt_string);
+        case TELOPT_STATE_WANTYES:
+            if (mud_telnet_get_telopt_queue(opt, bitshift) == TELOPT_STATE_QUEUE_EMPTY)
+            {
+                tel_string = mud_telnet_get_telnet_string(affirmative);
+                opt_string = mud_telnet_get_telopt_string(opt_no);
+                g_log("Telnet", G_LOG_LEVEL_DEBUG, "sent: %s %s",
+                        tel_string, opt_string );
+                g_free(tel_string);
+                g_free(opt_string);
+
+                mud_telnet_set_telopt_state(opt, TELOPT_STATE_YES, bitshift);
+                mud_telnet_send_iac(telnet, affirmative, opt_no);
+                mud_telnet_on_enable_opt(telnet, opt_no);
+                return TRUE;
+            } else { // the opposite is queued
+                tel_string = mud_telnet_get_telnet_string(negative);
+                opt_string = mud_telnet_get_telopt_string(opt_no);
+                g_log("Telnet", G_LOG_LEVEL_DEBUG, "sent: %s %s",
+                        tel_string, opt_string );
+                g_free(tel_string);
+                g_free(opt_string);
+
+                mud_telnet_set_telopt_state(opt, TELOPT_STATE_WANTNO, bitshift);
+                mud_telnet_set_telopt_queue(opt, TELOPT_STATE_QUEUE_EMPTY, bitshift);
+                mud_telnet_send_iac(telnet, negative, opt_no);
+                return FALSE;
+            }
+            break;
 
-	    mud_telnet_set_telopt_state(opt, TELOPT_STATE_WANTNO, bitshift);
-	    mud_telnet_set_telopt_queue(opt, TELOPT_STATE_QUEUE_EMPTY, bitshift);
-	    mud_telnet_send_iac(telnet, negative, opt_no);
-	    return FALSE;
-	}
-    default:
-	g_warning("Something went really wrong\n");
-	return FALSE;
+        default:
+            g_warning("something went really wrong\n");
+            return FALSE;
     }
 }
 
@@ -1046,74 +1148,70 @@
 				gint him)
 {
     const guint bitshift = him ? 4 : 0;
-    guchar * opt = &(telnet->telopt_states[opt_no]);
+    guchar *opt;
     gchar *opt_string, *tel_string;
 
+    if(!MUD_IS_TELNET(telnet))
+        return FALSE;
+
+    opt = &(telnet->priv->telopt_states[opt_no]);
+
     switch (mud_telnet_get_telopt_state(opt, bitshift))
     {
-    case TELOPT_STATE_NO:
-	// Ignore, he already supposedly has it disabled
-	return FALSE;
-
-    case TELOPT_STATE_YES:
-        tel_string = mud_telnet_get_telnet_string(negative);
-        opt_string = mud_telnet_get_telopt_string(opt_no);
-        g_log("Telnet", G_LOG_LEVEL_DEBUG, "Sent: %s %s",
-            tel_string, opt_string );
-        g_free(tel_string);
-        g_free(opt_string);
-
-	mud_telnet_set_telopt_state(opt, TELOPT_STATE_NO, bitshift);
-	mud_telnet_send_iac(telnet, negative, opt_no);
-	mud_telnet_on_disable_opt(telnet, opt_no, him);
-	return TRUE;
-
-    case TELOPT_STATE_WANTNO:
-        if (mud_telnet_get_telopt_queue(opt, bitshift) == TELOPT_STATE_QUEUE_EMPTY)
-        {
-            mud_telnet_set_telopt_state(opt, TELOPT_STATE_NO, bitshift);
+        case TELOPT_STATE_NO:
+            // ignore, he already supposedly has it disabled
             return FALSE;
-        } else {
-            tel_string = mud_telnet_get_telnet_string(affirmative);
+
+        case TELOPT_STATE_YES:
+            tel_string = mud_telnet_get_telnet_string(negative);
             opt_string = mud_telnet_get_telopt_string(opt_no);
-            g_log("Telnet", G_LOG_LEVEL_DEBUG, "Sent: %s %s",
+            g_log("Telnet", G_LOG_LEVEL_DEBUG, "sent: %s %s",
                     tel_string, opt_string );
             g_free(tel_string);
             g_free(opt_string);
 
-            mud_telnet_set_telopt_state(opt, TELOPT_STATE_WANTYES, bitshift);
-            mud_telnet_set_telopt_queue(opt, TELOPT_STATE_QUEUE_EMPTY, bitshift);
-            mud_telnet_send_iac(telnet, affirmative, opt_no);
-            mud_telnet_on_enable_opt(telnet, opt_no, him); // FIXME: Is this correct?
+            mud_telnet_set_telopt_state(opt, TELOPT_STATE_NO, bitshift);
+            mud_telnet_send_iac(telnet, negative, opt_no);
+            mud_telnet_on_disable_opt(telnet, opt_no);
             return TRUE;
-        }
-
-    case TELOPT_STATE_WANTYES:
-	if (mud_telnet_get_telopt_queue(opt, bitshift) == TELOPT_STATE_QUEUE_EMPTY)
-	{
-	    mud_telnet_set_telopt_state(opt, TELOPT_STATE_NO, bitshift);
-	    return FALSE;
-	} else { // The opposite is queued
-	    mud_telnet_set_telopt_state(opt, TELOPT_STATE_NO, bitshift);
-	    mud_telnet_set_telopt_queue(opt, TELOPT_STATE_QUEUE_EMPTY, bitshift);
-	    return FALSE;
-	}
-    default:
-	g_warning("TELNET NEGOTIATION: Something went really wrong\n");
-	return FALSE;
-    }
-}
+            break;
 
-static gint
-mud_telnet_get_index_by_option(MudTelnet *telnet, guchar option_number)
-{
-    gint i;
+        case TELOPT_STATE_WANTNO:
+            if (mud_telnet_get_telopt_queue(opt, bitshift) == TELOPT_STATE_QUEUE_EMPTY)
+            {
+                mud_telnet_set_telopt_state(opt, TELOPT_STATE_NO, bitshift);
+                return FALSE;
+            } else {
+                tel_string = mud_telnet_get_telnet_string(affirmative);
+                opt_string = mud_telnet_get_telopt_string(opt_no);
+                g_log("Telnet", G_LOG_LEVEL_DEBUG, "sent: %s %s",
+                        tel_string, opt_string );
+                g_free(tel_string);
+                g_free(opt_string);
+
+                mud_telnet_set_telopt_state(opt, TELOPT_STATE_WANTYES, bitshift);
+                mud_telnet_set_telopt_queue(opt, TELOPT_STATE_QUEUE_EMPTY, bitshift);
+                mud_telnet_send_iac(telnet, affirmative, opt_no);
+                mud_telnet_on_enable_opt(telnet, opt_no); // fixme: is this correct?
+                return TRUE;
+            }
+            break;
 
-    for(i = 0; i < TEL_HANDLERS_SIZE; i++)
-        if(telnet->handlers[i].type != HANDLER_NONE)
-            if(telnet->handlers[i].option_number == option_number)
-                return i;
+        case TELOPT_STATE_WANTYES:
+            if (mud_telnet_get_telopt_queue(opt, bitshift) == TELOPT_STATE_QUEUE_EMPTY)
+            {
+                mud_telnet_set_telopt_state(opt, TELOPT_STATE_NO, bitshift);
+                return FALSE;
+            } else { // the opposite is queued
+                mud_telnet_set_telopt_state(opt, TELOPT_STATE_NO, bitshift);
+                mud_telnet_set_telopt_queue(opt, TELOPT_STATE_QUEUE_EMPTY, bitshift);
+                return FALSE;
+            }
+            break;
 
-    return -1;
+        default:
+            g_warning("telnet negotiation: something went really wrong\n");
+            return FALSE;
+    }
 }
 

Modified: trunk/src/mud-telnet.h
==============================================================================
--- trunk/src/mud-telnet.h	(original)
+++ trunk/src/mud-telnet.h	Fri Mar 13 23:41:46 2009
@@ -31,57 +31,70 @@
 #define MUD_IS_TELNET(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), MUD_TYPE_TELNET))
 #define MUD_IS_TELNET_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MUD_TYPE_TELNET))
 #define MUD_TELNET_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), MUD_TYPE_TELNET, MudTelnetClass))
+#define MUD_TELNET_GET_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUD_TYPE_TELNET, MudTelnetPrivate))
 
-#define TEL_SE				240	// End of subnegotiation parameters
-#define TEL_NOP				241	// No operation
-#define TEL_GA				249	// Go ahead
-#define TEL_SB				250	// Indicates that what follows is subnegotiation of the indicated option
-#define TEL_WILL			251	// I will use option
-#define TEL_WONT			252	// I won't use option
-#define TEL_DO				253	// Please, you use this option
-#define TEL_DONT			254	// You are not to use this option
-#define TEL_IAC				255	// Interpret as command escape sequence - prefix to all telnet commands
-// Two IAC's in a row means Data Byte 255
-
-#define TELOPT_ECHO			  1	// Echo					- RFC  857
-#define TELOPT_TTYPE		 24	// Terminal type		- RFC 1091
-#	define TEL_TTYPE_IS		  0	// Terminal type IS ...
-#	define TEL_TTYPE_SEND	  1	// SEND me terminal type
-#define TELOPT_EOR			 25	// End of record		- RFC  885
-#   define TEL_EOR_BYTE     239 // End of record byte.
-#define TELOPT_NAWS			 31	// Window size			- RFC 1073
-#define TELOPT_CHARSET		 42	// Charset				- RFC 2066
-#   define TEL_CHARSET_REQUEST              1
-#   define TEL_CHARSET_ACCEPT               2
-#   define TEL_CHARSET_REJECT               3
-#   define TEL_CHARSET_TTABLE_IS            4
-#   define TEL_CHARSET_TTABLE_REJECTED      5
-#   define TEL_CHARSET_TTABLE_ACK           6
-#   define TEL_CHARSET_TTABLE_NAK           7
-#define TELOPT_MCCP			 85	// MCCP is not support by GnomeMud.
-#define TELOPT_MCCP2		 86	// MCCP2
-#define TELOPT_CLIENT		 88	// Client name - from Clandestine MUD protocol
-#define TELOPT_CLIENTVER	 89	// Client version - from Clandestine MUD protocol
-#define TELOPT_MSP			 90	// MSP - http://www.zuggsoft.com/zmud/msp.htm
-#define TELOPT_MXP			 91	// MXP - http://www.zuggsoft.com/zmud/mxp.htm
-#define TELOPT_ZMP			 93	// ZMP - http://www.awemud.net/zmp/draft.php
+#define TEL_SE				240 // End of subnegotiation parameters
+#define TEL_NOP				241 // No operation
+#define TEL_GA				249 // Go ahead
+#define TEL_SB				250 // Indicates that what follows is subnegotiation of the indicated option
+#define TEL_WILL			251 // I will use option
+#define TEL_WONT			252 // I won't use option
+#define TEL_DO				253 // Please, you use this option
+#define TEL_DONT			254 // You are not to use this option
+#define TEL_IAC				255 // Interpret as command escape sequence - prefix to all telnet commands
+                                            // Two IAC's in a row means Data Byte 255
+
+/* RFC 857 - Echo */
+#define TELOPT_ECHO			1
+
+/* RFC 1091 - Terminal Type */
+#define TELOPT_TTYPE		        24
+#	define TEL_TTYPE_IS		0   // Terminal type IS ...
+#	define TEL_TTYPE_SEND	        1   // SEND me terminal type
+
+/* RFC 885 - End of Record */
+#define TELOPT_EOR			25
+#   define TEL_EOR_BYTE                 239 // End of record byte.
+
+/* RFC 1073 - Negotiate About Window Size */
+#define TELOPT_NAWS			31
+
+/* RFC 2066 - Charset */
+#define TELOPT_CHARSET                  42
+#   define TEL_CHARSET_REQUEST          1
+#   define TEL_CHARSET_ACCEPT           2
+#   define TEL_CHARSET_REJECT           3
+#   define TEL_CHARSET_TTABLE_IS        4
+#   define TEL_CHARSET_TTABLE_REJECTED  5
+#   define TEL_CHARSET_TTABLE_ACK       6
+#   define TEL_CHARSET_TTABLE_NAK       7
+
+/* MCCP */
+// We do not support COMPRESS1
+#define TELOPT_MCCP                     85
+#define TELOPT_MCCP2		        86
+
+/* Mud Sound Protocol - http://www.zuggsoft.com/zmud/msp.htm */
+#define TELOPT_MSP			90
+
+/* Mud Extension Protocol - http://www.zuggsoft.com/zmud/mxp.htm */
+#define TELOPT_MXP                      91
+
+/* Zenith Mud Protocol - http://www.awemud.net/zmp/draft.php */
+#define TELOPT_ZMP                      93
 
 // FIXME: What size should we use?
 #define TEL_SUBREQ_BUFFER_SIZE 2048 
-#define TEL_HANDLERS_SIZE 256
 #define TELOPT_STATE_QUEUE_EMPTY	FALSE
 #define TELOPT_STATE_QUEUE_OPPOSITE	TRUE
 
 typedef struct _MudTelnet            MudTelnet;
 typedef struct _MudTelnetClass       MudTelnetClass;
 typedef struct _MudTelnetPrivate     MudTelnetPrivate;
-typedef struct _MudTelnetBuffer      MudTelnetBuffer;
-typedef struct _MudTelnetHandler     MudTelnetHandler;
 
-typedef void(*MudTelnetOnEnableFunc)(MudTelnet *telnet, MudTelnetHandler *handler);
-typedef void(*MudTelnetOnDisableFunc)(MudTelnet *telnet, MudTelnetHandler *handler);
-typedef void(*MudTelnetOnHandleSubNegFunc)(MudTelnet *telnet,
-        guchar *buf, guint len, MudTelnetHandler *handler);
+#include <gnet.h>
+#include "mud-connection-view.h"
+#include "mud-telnet-handler-interface.h"
 
 enum TelnetState
 {
@@ -103,111 +116,35 @@
     TELOPT_STATE_YES = 3,     // bits 11
 };
 
-enum TelnetHandlerType
-{
-    HANDLER_NONE,
-    HANDLER_TTYPE,
-    HANDLER_NAWS,
-    HANDLER_ECHO,
-    HANDLER_EOR,
-    HANDLER_CHARSET,
-    HANDLER_ZMP,
-    HANDLER_MSP,
-    HANDLER_MCCP2
-};
-
 struct _MudTelnetClass
 {
     GObjectClass parent_class;
 };
 
-struct _MudTelnetHandler
-{
-    enum TelnetHandlerType type;
-    guchar option_number;
-
-    gint enabled;
-
-    MudTelnet *instance;
-
-    MudTelnetOnEnableFunc enable;
-    MudTelnetOnDisableFunc disable;
-    MudTelnetOnHandleSubNegFunc handle_sub_neg;
-};
-
-#include <gnet.h>
-#include "mud-connection-view.h"
-#include "mud-telnet-zmp.h"
-
-#ifdef ENABLE_GST
-#include "mud-telnet-msp.h"
-#endif
-
-#ifdef ENABLE_MCCP
-#include <zlib.h>
-typedef struct z_stream_s z_stream;
-#endif
-
 struct _MudTelnet
 {
     GObject parent_instance;
 
+    /*< Private >*/
     MudTelnetPrivate *priv;
 
-    enum TelnetState tel_state;
-    guchar subreq_buffer[TEL_SUBREQ_BUFFER_SIZE];
-    guint32 subreq_pos;
-
-    guchar telopt_states[256];
-    gint eor_enabled;
-    gint ttype_iteration;
-
-    GConn *conn;
-    MudConnectionView *parent;
-
-    MudTelnetHandler handlers[TEL_HANDLERS_SIZE];
-
-    GHashTable *zmp_commands;
-    MudZMPCommand commands[2048];
-
-#ifdef ENABLE_GST
-    MudMSPParser msp_parser;
-    MudMSPTypes msp_type;
-    MudMSPSound sound[2];
-    gchar *base_url;
-    GString *prev_buffer;
-#endif
-
-#ifdef ENABLE_MCCP
-    z_stream *compress_out;
-    guchar *compress_out_buf;
-    gboolean mccp;
-    gboolean mccp_new;
-#endif
-
-    GString *processed;
-    GString *buffer;
-    size_t pos;
+    /*< Public >*/
+    gboolean ga_received;
+    gboolean eor_received;
 
-    gchar *mud_name;
+    MudConnectionView *parent_view;
 };
 
-GType mud_telnet_get_type (void) G_GNUC_CONST;
-
-MudTelnet *mud_telnet_new(MudConnectionView *parent, GConn *connection, gchar *mud_name);
+GType mud_telnet_get_type (void);
 
-void mud_telnet_register_handlers(MudTelnet *telnet);
-gint mud_telnet_isenabled(MudTelnet *telnet, guint8 option_number, gint him);
 GString *mud_telnet_process(MudTelnet *telnet, guchar * buf, guint32 count, gint *length);
 void mud_telnet_send_sub_req(MudTelnet *telnet, guint32 count, ...);
-void mud_telnet_get_parent_size(MudTelnet *telnet, gint *w, gint *h);
 void mud_telnet_send_raw(MudTelnet *telnet, guint32 count, ...);
-void mud_telnet_set_parent_naws(MudTelnet *telnet, gint enabled);
-void mud_telnet_set_parent_remote_encode(MudTelnet *telnet, gint enabled, gchar *encoding);
 void mud_telnet_send_naws(MudTelnet *telnet, gint w, gint h);
-void mud_telnet_set_local_echo(MudTelnet *telnet, gint enabled);
-void mud_telnet_send_charset_req(MudTelnet *telnet, gchar *encoding);
+void mud_telnet_get_parent_size(MudTelnet *telnet, gint *w, gint *h);
+MudTelnetHandler *mud_telnet_get_handler(MudTelnet *telnet, gint opt_no);
 
 G_END_DECLS
 
 #endif // MUD_TELNET_H
+

Modified: trunk/src/mud-tray.c
==============================================================================
--- trunk/src/mud-tray.c	(original)
+++ trunk/src/mud-tray.c	Fri Mar 13 23:41:46 2009
@@ -121,7 +121,6 @@
                       guint n_properties,
                       GObjectConstructParam *properties)
 {
-    guint i;
     MudTray *self;
     GObject *obj;
     MudTrayClass *klass;

Modified: trunk/src/mud-window-profile.c
==============================================================================
--- trunk/src/mud-window-profile.c	(original)
+++ trunk/src/mud-window-profile.c	Fri Mar 13 23:41:46 2009
@@ -118,7 +118,7 @@
             g_param_spec_object("parent-window",
                 "parent gtk window",
                 "the gtk window parent of this window",
-                TYPE_MUD_WINDOW,
+                MUD_TYPE_WINDOW,
                 G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
 }
 

Modified: trunk/src/mud-window.c
==============================================================================
--- trunk/src/mud-window.c	(original)
+++ trunk/src/mud-window.c	Fri Mar 13 23:41:46 2009
@@ -62,7 +62,7 @@
     GtkWidget *toolbar_reconnect;
 
     GtkWidget *blank_label;
-    GtkWidget *current_view;
+    MudConnectionView *current_view;
 
     GtkWidget *mi_profiles;
 
@@ -74,12 +74,6 @@
     gint textview_line_height;
 };
 
-typedef struct MudViewEntry
-{
-	gint id;
-	MudConnectionView *view;
-} MudViewEntry;
-
 /* Create the Type */
 G_DEFINE_TYPE(MudWindow, mud_window, G_TYPE_OBJECT);
 
@@ -129,10 +123,6 @@
 static gboolean mud_window_configure_event(GtkWidget *widget,
                                            GdkEventConfigure *event,
                                            gpointer user_data);
-static gboolean save_dialog_vte_cb (VteTerminal *terminal, 
-                                    glong column,
-                                    glong row,
-                                    gpointer data);
 static void mud_window_buffer_cb(GtkWidget *widget, MudWindow *self);
 static void mud_window_select_profile(GtkWidget *widget, MudWindow *self);
 static void mud_window_profile_menu_set_cb(GtkWidget *widget, gpointer data);
@@ -358,7 +348,7 @@
 
     while(entry != NULL)
     {
-        g_object_unref( ( (MudViewEntry *)entry->data )->view );
+        g_object_unref(entry->data);
         entry = g_slist_next(entry);
     }
 
@@ -454,7 +444,7 @@
         gtk_widget_set_sensitive(self->priv->startlog, FALSE);
         gtk_widget_set_sensitive(self->priv->menu_disconnect, FALSE);
         gtk_widget_set_sensitive(self->priv->toolbar_disconnect, FALSE);
-        mud_connection_view_disconnect(MUD_CONNECTION_VIEW(self->priv->current_view));
+        mud_connection_view_disconnect(self->priv->current_view);
     }
 }
 
@@ -466,7 +456,7 @@
         gtk_widget_set_sensitive(self->priv->startlog, TRUE);
         gtk_widget_set_sensitive(self->priv->menu_disconnect, TRUE);
         gtk_widget_set_sensitive(self->priv->toolbar_disconnect, TRUE);
-        mud_connection_view_reconnect(MUD_CONNECTION_VIEW(self->priv->current_view));
+        mud_connection_view_reconnect(self->priv->current_view);
     }
 }
 
@@ -486,6 +476,7 @@
 mud_window_textview_keypress(GtkWidget *widget, GdkEventKey *event, MudWindow *self)
 {
     gchar *text;
+    const gchar *history;
     GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self->priv->textview));
     GtkTextIter start, end;
     MudParseBase *base;
@@ -503,10 +494,12 @@
             if (g_str_equal(text, ""))
                 text = g_strdup(" ");
 
-            base = mud_connection_view_get_parsebase(MUD_CONNECTION_VIEW(self->priv->current_view));
+            g_object_get(self->priv->current_view,
+                        "parse-base", &base,
+                        NULL);
 
             if(mud_parse_base_do_aliases(base, text))
-                mud_connection_view_send(MUD_CONNECTION_VIEW(self->priv->current_view), text);
+                mud_connection_view_send(self->priv->current_view, text);
 
             g_free(text);
         }
@@ -528,12 +521,13 @@
     {
         if(event->keyval == GDK_Up)
         {
-            text = mud_connection_view_get_history_item(
-                    MUD_CONNECTION_VIEW(self->priv->current_view), HISTORY_UP);
+            history = 
+                mud_connection_view_get_history_item(self->priv->current_view, 
+                                                     HISTORY_UP);
 
-            if(text)
+            if(history)
             {
-                gtk_text_buffer_set_text(buffer, text, strlen(text));
+                gtk_text_buffer_set_text(buffer, history, strlen(history));
                 gtk_text_buffer_get_bounds(buffer, &start, &end);
                 gtk_text_buffer_select_range(buffer, &start, &end);
             }
@@ -543,12 +537,13 @@
 
         if(event->keyval == GDK_Down)
         {
-            text = mud_connection_view_get_history_item(
-                    MUD_CONNECTION_VIEW(self->priv->current_view), HISTORY_DOWN);
+            history =
+                mud_connection_view_get_history_item(self->priv->current_view,
+                                                     HISTORY_DOWN);
 
-            if(text)
+            if(history)
             {
-                gtk_text_buffer_set_text(buffer, text, strlen(text));
+                gtk_text_buffer_set_text(buffer, history, strlen(history));
                 gtk_text_buffer_get_bounds(buffer, &start, &end);
                 gtk_text_buffer_select_range(buffer, &start, &end);
             }
@@ -565,6 +560,7 @@
 {
     gchar *name;
     gboolean connected;
+    gboolean logging;
 
     self->priv->current_view =
         g_object_get_data(
@@ -573,16 +569,20 @@
 
     if (self->priv->nr_of_tabs != 0)
     {
-        name = mud_profile_get_name(
-                mud_connection_view_get_current_profile(
-                    MUD_CONNECTION_VIEW(self->priv->current_view)));
+        g_object_get(self->priv->current_view,
+                     "profile-name", &name,
+                     NULL);
 
         mud_window_profile_menu_set_active(self, name);
 
-        connected = mud_connection_view_is_connected(
-                MUD_CONNECTION_VIEW(self->priv->current_view));
+        g_free(name);
 
-        if(mud_connection_view_islogging(MUD_CONNECTION_VIEW(self->priv->current_view)))
+        g_object_get(self->priv->current_view,
+                     "connected", &connected,
+                     "logging", &logging,
+                     NULL);
+        
+        if(logging)
         {
             gtk_widget_set_sensitive(self->priv->startlog, FALSE);
             gtk_widget_set_sensitive(self->priv->stoplog, TRUE);
@@ -711,6 +711,7 @@
 
     for(i = 0; i < self->priv->nr_of_tabs; ++i)
     {
+        gboolean connected;
         MudConnectionView *iter =
             g_object_get_data(
                     G_OBJECT(
@@ -718,8 +719,12 @@
                             GTK_NOTEBOOK(self->priv->notebook),
                             i)),
                     "connection-view");
+        
+        g_object_get(iter,
+                     "connected", &connected,
+                     NULL);
 
-        if(mud_connection_view_is_connected(iter))
+        if(connected)
             mud_connection_view_send_naws(iter);
     }
 
@@ -728,12 +733,6 @@
     return FALSE;
 }
 
-static gboolean
-save_dialog_vte_cb (VteTerminal *terminal,glong column,glong row,gpointer data)
-{
-    return TRUE;
-}
-
 static void
 mud_window_buffer_cb(GtkWidget *widget, MudWindow *self)
 {
@@ -760,14 +759,16 @@
         else
         {
             gchar *bufferText;
-            GtkWidget *term;
-
-            term = mud_connection_view_get_terminal(MUD_CONNECTION_VIEW(self->priv->current_view));
+            VteTerminal *term;
 
-            bufferText = vte_terminal_get_text_range(VTE_TERMINAL(term),0,0,
-                    vte_terminal_get_row_count(VTE_TERMINAL(term)),
-                    vte_terminal_get_column_count(VTE_TERMINAL(term)),
-                    save_dialog_vte_cb,
+            g_object_get(self->priv->current_view,
+                         "terminal", &term,
+                         NULL);
+
+            bufferText = vte_terminal_get_text_range(term,0,0,
+                    vte_terminal_get_row_count(term),
+                    vte_terminal_get_column_count(term),
+                    NULL,
                     NULL,
                     NULL);
 
@@ -837,23 +838,14 @@
 static void
 mud_window_remove_connection_view(MudWindow *self, gint nr)
 {
-    GSList *entry, *rementry;
-
-    rementry = NULL;
-    rementry = g_slist_append(rementry, NULL);
+    GSList *entry;
 
-    g_object_unref(self->priv->current_view);
     gtk_notebook_remove_page(GTK_NOTEBOOK(self->priv->notebook), nr);
 
-    for(entry = self->priv->mud_views_list; entry != NULL; entry = g_slist_next(entry))
-        if(((MudViewEntry *)entry->data)->id == nr)
-        {
-            rementry->data = entry->data;
-            break;
-        }
-
     self->priv->mud_views_list =
-        g_slist_remove(self->priv->mud_views_list, rementry->data);
+        g_slist_remove(self->priv->mud_views_list, self->priv->current_view);
+
+    g_object_unref(self->priv->current_view);
 
     if (--self->priv->nr_of_tabs < 2)
     {
@@ -1006,22 +998,28 @@
 mud_window_add_connection_view(MudWindow *self, GObject *cview, gchar *tabLbl)
 {
     gint nr;
-    MudViewEntry *entry;
-    GtkWidget *terminal;
+    VteTerminal *terminal;
+    GtkVBox *viewport;
     MudConnectionView *view = MUD_CONNECTION_VIEW(cview);
 
     g_return_if_fail(IS_MUD_WINDOW(self));
     g_return_if_fail(IS_MUD_CONNECTION_VIEW(view));
 
-    entry = g_new(MudViewEntry, 1);
-
     if (self->priv->nr_of_tabs++ == 0)
     {
         gtk_notebook_remove_page(GTK_NOTEBOOK(self->priv->notebook), 0);
         self->priv->image = NULL;
     }
 
-    nr = gtk_notebook_append_page(GTK_NOTEBOOK(self->priv->notebook), mud_connection_view_get_viewport(view), gtk_label_new(tabLbl));
+    g_object_get(view,
+                 "ui-vbox", &viewport,
+                 "terminal", &terminal,
+                 NULL);
+
+    nr = gtk_notebook_append_page(GTK_NOTEBOOK(self->priv->notebook),
+                                  GTK_WIDGET(viewport),
+                                  gtk_label_new(tabLbl));
+
     gtk_notebook_set_current_page(GTK_NOTEBOOK(self->priv->notebook), nr);
 
     gtk_widget_set_sensitive(self->priv->startlog, TRUE);
@@ -1032,19 +1030,12 @@
     gtk_widget_set_sensitive(self->priv->toolbar_disconnect, TRUE);
     gtk_widget_set_sensitive(self->priv->toolbar_reconnect, TRUE);
 
-    mud_connection_view_set_id(view, nr);
-    mud_connection_view_set_parent(view, self);
-
-    terminal = mud_connection_view_get_terminal(view);
     g_signal_connect(terminal,
                      "focus-in-event",
                      G_CALLBACK(mud_window_grab_entry_focus_cb),
                      self);
 
-    entry->id = nr;
-    entry->view = view;
-
-    self->priv->mud_views_list = g_slist_append(self->priv->mud_views_list, entry);
+    self->priv->mud_views_list = g_slist_append(self->priv->mud_views_list, view);
 
     if (self->priv->nr_of_tabs > 1)
     {

Modified: trunk/src/mud-window.h
==============================================================================
--- trunk/src/mud-window.h	(original)
+++ trunk/src/mud-window.h	Fri Mar 13 23:41:46 2009
@@ -26,13 +26,13 @@
 #include <gtk/gtk.h>
 #include "mud-tray.h"
 
-#define TYPE_MUD_WINDOW             (mud_window_get_type ())
-#define MUD_WINDOW(object)          (G_TYPE_CHECK_INSTANCE_CAST ((object), TYPE_MUD_WINDOW, MudWindow))
-#define MUD_WINDOW_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_MUD_WINDOW, MudWindowClass))
-#define IS_MUD_WINDOW(object)       (G_TYPE_CHECK_INSTANCE_TYPE ((object), TYPE_MUD_WINDOW))
-#define IS_MUD_WINDOW_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_MUD_WINDOW))
-#define MUD_WINDOW_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_MUD_WINDOW, MudWindowClass))
-#define MUD_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_MUD_WINDOW, MudWindowPrivate))
+#define MUD_TYPE_WINDOW             (mud_window_get_type ())
+#define MUD_WINDOW(object)          (G_TYPE_CHECK_INSTANCE_CAST ((object), MUD_TYPE_WINDOW, MudWindow))
+#define MUD_WINDOW_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), MUD_TYPE_WINDOW, MudWindowClass))
+#define IS_MUD_WINDOW(object)       (G_TYPE_CHECK_INSTANCE_TYPE ((object), MUD_TYPE_WINDOW))
+#define IS_MUD_WINDOW_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), MUD_TYPE_WINDOW))
+#define MUD_WINDOW_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), MUD_TYPE_WINDOW, MudWindowClass))
+#define MUD_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUD_TYPE_WINDOW, MudWindowPrivate))
 
 typedef struct _MudWindow           MudWindow;
 typedef struct _MudWindowClass      MudWindowClass;

Modified: trunk/src/utils.c
==============================================================================
--- trunk/src/utils.c	(original)
+++ trunk/src/utils.c	Fri Mar 13 23:41:46 2009
@@ -26,30 +26,60 @@
 gchar *
 utils_remove_whitespace(const gchar *string)
 {
-    gint i;
+    guint i, len;
     GString *s;
 
     if(string == NULL)
         return NULL;
 
     s = g_string_new(NULL);
+    len = strlen(string);
 
-    for(i = 0; i < strlen(string); i++)
+    for(i = 0; i < len; i++)
         if(!g_ascii_isspace(string[i]))
             s = g_string_append_c(s, string[i]);
 
     return g_string_free(s, FALSE);
 }
 
+// FIXME: This is terrible. We should replace this with something
+// that can handle any sized string.
+void
+utils_str_replace (gchar *buf, const gchar *s, const gchar *repl)
+{
+    gchar out_buf[4608];
+    gchar *pc, *out;
+    gint  len = strlen (s);
+    gboolean found = FALSE;
+
+    for ( pc = buf, out = out_buf; *pc && (out-out_buf) < (4608-len-4);)
+        if ( !strncasecmp(pc, s, len))
+        {
+            out += sprintf (out, "%s", repl);
+            pc += len;
+            found = TRUE;
+        }
+        else
+            *out++ = *pc++;
+
+    if ( found)
+    {
+        *out = '\0';
+        strcpy (buf, out_buf);
+    }
+}
+
 gchar *
 utils_strip_ansi(const gchar *orig)
 {
-    GString *buf = g_string_new(NULL);
+    GString *buf;
     const gchar *c;
 
     if (!orig)
         return NULL;
 
+    buf = g_string_new(NULL);
+
     for (c = orig; *c;)
     {
         switch (*c)

Modified: trunk/src/utils.h
==============================================================================
--- trunk/src/utils.h	(original)
+++ trunk/src/utils.h	Fri Mar 13 23:41:46 2009
@@ -26,6 +26,7 @@
 gchar *utils_strip_ansi(const gchar *orig);
 void utils_activate_url(GtkAboutDialog *about, const gchar *url, gpointer data);
 void utils_error_message(GtkWidget *parent, const gchar *title, const gchar *fmt, ...);
+void utils_str_replace (gchar *buf, const gchar *s, const gchar *repl);
 
 #endif // UTILS_H
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]