gnome-mud r788 - in trunk: . src
- From: lharris svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-mud r788 - in trunk: . src
- Date: Fri, 13 Mar 2009 23:41:47 +0000 (UTC)
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", ®ex,
+ 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", ®ex,
+ 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]