gnome-mud r797 - in trunk: . src src/handlers src/zmp
- From: lharris svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-mud r797 - in trunk: . src src/handlers src/zmp
- Date: Tue, 17 Mar 2009 18:08:13 +0000 (UTC)
Author: lharris
Date: Tue Mar 17 18:08:13 2009
New Revision: 797
URL: http://svn.gnome.org/viewvc/gnome-mud?rev=797&view=rev
Log:
Telnet Handlers are now compiled as a static library and linked in.
Added:
trunk/src/handlers/
trunk/src/handlers/Makefile.am
trunk/src/handlers/mud-telnet-charset.c
trunk/src/handlers/mud-telnet-charset.h
trunk/src/handlers/mud-telnet-echo.c
trunk/src/handlers/mud-telnet-echo.h
trunk/src/handlers/mud-telnet-eor.c
trunk/src/handlers/mud-telnet-eor.h
trunk/src/handlers/mud-telnet-handler-interface.c
trunk/src/handlers/mud-telnet-handler-interface.h
trunk/src/handlers/mud-telnet-handlers.h
trunk/src/handlers/mud-telnet-mccp.c
trunk/src/handlers/mud-telnet-mccp.h
trunk/src/handlers/mud-telnet-msp.c
trunk/src/handlers/mud-telnet-msp.h
trunk/src/handlers/mud-telnet-mssp.c
trunk/src/handlers/mud-telnet-mssp.h
trunk/src/handlers/mud-telnet-naws.c
trunk/src/handlers/mud-telnet-naws.h
trunk/src/handlers/mud-telnet-new-environ.c
trunk/src/handlers/mud-telnet-new-environ.h
trunk/src/handlers/mud-telnet-ttype.c
trunk/src/handlers/mud-telnet-ttype.h
trunk/src/handlers/mud-telnet-zmp.c
trunk/src/handlers/mud-telnet-zmp.h
trunk/src/zmp/
trunk/src/zmp/Makefile.am
trunk/src/zmp/zmp-subwindow.c
trunk/src/zmp/zmp-subwindow.h
Removed:
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-mccp.c
trunk/src/mud-telnet-mccp.h
trunk/src/mud-telnet-msp.c
trunk/src/mud-telnet-msp.h
trunk/src/mud-telnet-mssp.c
trunk/src/mud-telnet-mssp.h
trunk/src/mud-telnet-naws.c
trunk/src/mud-telnet-naws.h
trunk/src/mud-telnet-new-environ.c
trunk/src/mud-telnet-new-environ.h
trunk/src/mud-telnet-ttype.c
trunk/src/mud-telnet-ttype.h
trunk/src/mud-telnet-zmp.c
trunk/src/mud-telnet-zmp.h
Modified:
trunk/ChangeLog
trunk/autogen.sh
trunk/configure.ac
trunk/src/Makefile.am
trunk/src/mud-connection-view.c
trunk/src/mud-telnet.c
trunk/src/mud-telnet.h
Modified: trunk/autogen.sh
==============================================================================
--- trunk/autogen.sh (original)
+++ trunk/autogen.sh Tue Mar 17 18:08:13 2009
@@ -4,18 +4,13 @@
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
-PKG_NAME="gnome-mud"
-REQUIRED_AUTOMAKE_VERSION=1.7
+REQUIRED_AUTOMAKE_VERSION=1.9
-(test -f $srcdir/configure.ac) || {
- echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
- echo " top-level $PKG_NAME directory"
- exit 1
-}
+PKG_NAME="gnome-mud"
which gnome-autogen.sh || {
- echo "You need to install gnome-common from the GNOME CVS"
+ echo "You need to install gnome-common from the GNOME SVN"
exit 1
}
-USE_GNOME2_MACROS=1 . gnome-autogen.sh
+. gnome-autogen.sh
Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac (original)
+++ trunk/configure.ac Tue Mar 17 18:08:13 2009
@@ -55,6 +55,7 @@
dnl Checks for programs.
AC_PROG_CC
+AC_PROG_LIBTOOL
AM_PROG_CC_STDC
AC_ISC_POSIX
AC_PROG_LN_S
@@ -141,6 +142,8 @@
data/icons/Makefile
doc/Makefile
src/Makefile
+ src/handlers/Makefile
+ src/zmp/Makefile
po/Makefile.in
ui/Makefile
])
Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am (original)
+++ trunk/src/Makefile.am Tue Mar 17 18:08:13 2009
@@ -1,5 +1,10 @@
+SUBDIRS = handlers zmp
+
+bin_PROGRAMS = gnome-mud
+
localedir = $(datadir)/locale
-INCLUDES = \
+
+gnome_mud_CPPFLAGS = \
-DLOCALEDIR=\"$(localedir)\" \
-DPIXMAPSDIR=\""$(datadir)/pixmaps"\" \
-DGMPIXMAPSDIR=\""$(datadir)/icons/hicolor/scalable/apps"\" \
@@ -8,11 +13,18 @@
-DDATADIR=\""$(datadir)"\" \
-DLIBDIR=\""$(libdir)"\" \
-DGLADEDIR=\""$(pkgdatadir)"\" \
- $(GMUD_CFLAGS) $(MSP_CFLAGS)
-LDADD = $(GMUD_LIBS) $(Z_LIBS) $(MSP_LIBS)
-AM_CPPFLAGS = -DPKGDATADIR=\"$(pkgdatadir)\"
+ -DPKGDATADIR=\""$(pkgdatadir)"\"
-bin_PROGRAMS = gnome-mud
+gnome_mud_CFLAGS = \
+ $(GMUD_CFLAGS) \
+ $(MSP_CFLAGS)
+
+gnome_mud_LDADD = \
+ handlers/libtelnethandlers.la \
+ zmp/libzmpcommands.la \
+ $(GMUD_LIBS) \
+ $(Z_LIBS) \
+ $(MSP_LIBS)
gnome_mud_SOURCES = \
gconf-helper.c \
@@ -46,28 +58,6 @@
mud-regex.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-mssp.c \
- mud-telnet-mssp.h \
- mud-telnet-new-environ.c \
- mud-telnet-new-environ.h \
- mud-telnet-zmp.c \
- mud-telnet-zmp.h \
mud-tray.c \
mud-tray.h \
mud-window.c \
@@ -88,10 +78,14 @@
$(BUILT_SOURCES)
gnome-mud-marshallers.h: gnome-mud-marshallers.list
- $(GLIB_GENMARSHAL) --prefix gnome_mud_cclosure --header \
- gnome-mud-marshallers.list > gnome-mud-marshallers.h
+ ( $(GLIB_GENMARSHAL) --prefix gnome_mud_cclosure --header \
+ gnome-mud-marshallers.list > gnome-mud-marshallers.h.tmp \
+ && mv gnome-mud-marshallers.h.tmp gnome-mud-marshallers.h ) \
+ || ( rm -f gnome-mud-marshallers.h.tmp && exit 1 )
gnome-mud-marshallers.c: gnome-mud-marshallers.list
- $(GLIB_GENMARSHAL) --prefix gnome_mud_cclosure --body \
- gnome-mud-marshallers.list > gnome-mud-marshallers.c
+ ( $(GLIB_GENMARSHAL) --prefix gnome_mud_cclosure --body \
+ gnome-mud-marshallers.list > gnome-mud-marshallers.c.tmp \
+ && mv gnome-mud-marshallers.c.tmp gnome-mud-marshallers.c ) \
+ || ( rm -f gnome-mud-marshallers.c.tmp && exit 1 )
Added: trunk/src/handlers/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/src/handlers/Makefile.am Tue Mar 17 18:08:13 2009
@@ -0,0 +1,45 @@
+NULL =
+
+noinst_LTLIBRARIES = libtelnethandlers.la
+
+libtelnethandlers_la_SOURCES = \
+ mud-telnet-charset.c \
+ mud-telnet-charset.h \
+ mud-telnet-echo.c \
+ mud-telnet-echo.h \
+ mud-telnet-eor.c \
+ mud-telnet-eor.h \
+ mud-telnet-handlers.h \
+ mud-telnet-handler-interface.c \
+ mud-telnet-handler-interface.h \
+ mud-telnet-mccp.c \
+ mud-telnet-mccp.h \
+ mud-telnet-msp.c \
+ mud-telnet-msp.h \
+ mud-telnet-mssp.c \
+ mud-telnet-mssp.h \
+ mud-telnet-naws.c \
+ mud-telnet-naws.h \
+ mud-telnet-new-environ.c \
+ mud-telnet-new-environ.h \
+ mud-telnet-ttype.c \
+ mud-telnet-ttype.h \
+ mud-telnet-zmp.c \
+ mud-telnet-zmp.h \
+ $(NULL)
+
+libtelnethandlers_la_CPPFLAGS = \
+ -I$(srcdir)/.. \
+ $(AM_CPPFLAGS)
+
+libtelnethandlers_la_CFLAGS = \
+ $(GMUD_CFLAGS) \
+ $(MSP_CFLAGS)
+
+libtelnethandlers_la_LDFLAGS =
+
+libtelnethandlers_la_LIBADD = \
+ $(GMUD_LIBS) \
+ $(MSP_LIBS) \
+ $(Z_LIBS)
+
Added: trunk/src/handlers/mud-telnet-charset.c
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-charset.c Tue Mar 17 18:08:13 2009
@@ -0,0 +1,378 @@
+/* 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/handlers/mud-telnet-charset.h
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-charset.h Tue Mar 17 18:08:13 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/handlers/mud-telnet-echo.c
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-echo.c Tue Mar 17 18:08:13 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/handlers/mud-telnet-echo.h
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-echo.h Tue Mar 17 18:08:13 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/handlers/mud-telnet-eor.c
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-eor.c Tue Mar 17 18:08:13 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/handlers/mud-telnet-eor.h
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-eor.h Tue Mar 17 18:08:13 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/handlers/mud-telnet-handler-interface.c
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-handler-interface.c Tue Mar 17 18:08:13 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/handlers/mud-telnet-handler-interface.h
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-handler-interface.h Tue Mar 17 18:08:13 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
+
Added: trunk/src/handlers/mud-telnet-handlers.h
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-handlers.h Tue Mar 17 18:08:13 2009
@@ -0,0 +1,51 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-handlers.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_HANDLERS_H
+#define MUD_TELNET_HANDLERS_H
+
+G_BEGIN_DECLS
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "mud-telnet-handler-interface.h"
+#include "mud-telnet-charset.h"
+#include "mud-telnet-echo.h"
+#include "mud-telnet-eor.h"
+
+#ifdef ENABLE_MCCP
+#include "mud-telnet-mccp.h"
+#endif
+
+#ifdef ENABLE_GST
+#include "mud-telnet-msp.h"
+#endif
+
+#include "mud-telnet-mssp.h"
+#include "mud-telnet-naws.h"
+#include "mud-telnet-new-environ.h"
+#include "mud-telnet-ttype.h"
+#include "mud-telnet-zmp.h"
+
+G_END_DECLS
+
+#endif // MUD_TELNET_HANDLERS_H
+
Added: trunk/src/handlers/mud-telnet-mccp.c
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-mccp.c Tue Mar 17 18:08:13 2009
@@ -0,0 +1,442 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-mccp.c
+ * Copyright (C) 2008-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
+
+#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(MudTelnetMccp *self, guchar *buffer, guint32 length)
+{
+ GString *ret = NULL;
+ gint zstatus;
+ gint i;
+ MudConnectionView *view;
+
+ g_return_if_fail(MUD_IS_TELNET_MCCP(self));
+
+ if(!self->priv->compress_out)
+ return NULL;
+
+ 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(self->priv->compress_out->avail_in < 1)
+ break;
+
+ self->priv->compress_out->avail_out = 4096;
+ self->priv->compress_out->next_out = self->priv->compress_out_buf;
+
+ /* Inflating */
+ zstatus = inflate(self->priv->compress_out, Z_SYNC_FLUSH);
+
+ if(zstatus == Z_OK)
+ {
+ ret = g_string_append_len(ret,
+ self->priv->compress_out_buf,
+ (4096 - self->priv->compress_out->avail_out));
+
+ continue;
+ }
+
+ if(zstatus == Z_STREAM_END)
+ {
+ ret = g_string_append_len(ret,
+ self->priv->compress_out_buf,
+ (4096 - self->priv->compress_out->avail_out));
+
+ if(self->priv->compress_out->avail_in > 0)
+ ret = g_string_append_len(ret,
+ self->priv->compress_out->next_in,
+ self->priv->compress_out->avail_in);
+
+ inflateEnd(self->priv->compress_out);
+
+ g_free(self->priv->compress_out);
+ g_free(self->priv->compress_out_buf);
+
+ self->priv->compress_out = NULL;
+ self->priv->compress_out_buf = NULL;
+
+ self->priv->mccp = FALSE;
+ self->priv->mccp_new = TRUE;
+
+ break;
+ }
+
+ if(zstatus == Z_BUF_ERROR)
+ {
+ break;
+ }
+
+ if(zstatus == Z_DATA_ERROR)
+ {
+ mud_connection_view_add_text(view,
+ _("\nMCCP data corrupted. Aborting connection.\n"),
+ Error);
+ mud_connection_view_disconnect (view);
+
+ g_printf("Z DATA ERROR!\n");
+
+ return NULL;
+ }
+ }
+
+ return ret;
+}
+
+#endif // ENABLE_MCCP
+
Added: trunk/src/handlers/mud-telnet-mccp.h
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-mccp.h Tue Mar 17 18:08:13 2009
@@ -0,0 +1,66 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-mccp.h
+ * Copyright (C) 2008-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_MCCP_H
+#define MUD_TELNET_MCCP_H
+
+#ifdef ENABLE_MCCP
+
+G_BEGIN_DECLS
+
+#include <glib.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
+
+#endif // ENABLE_MCCP
+
+#endif // MUD_TELNET_MCCP_H
+
Added: trunk/src/handlers/mud-telnet-msp.c
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-msp.c Tue Mar 17 18:08:13 2009
@@ -0,0 +1,1242 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-msp.c
+ * Copyright (C) 2008-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
+
+#ifdef ENABLE_GST
+
+#include <glib.h>
+#include <gnet.h>
+#include <string.h>
+#include <gst/gst.h>
+#include <ctype.h>
+
+#include "gnome-mud.h"
+#include "mud-telnet.h"
+#include "mud-telnet-handler-interface.h"
+#include "mud-telnet-msp.h"
+
+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(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);
+static gboolean mud_telnet_msp_music_bus_call (GstBus *bus,
+ 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(MudTelnetMsp *self, GString *buf, gint *len)
+{
+ gint count;
+ GString *ret = NULL;
+ gchar *temp;
+
+ g_return_if_fail(MUD_IS_TELNET_MSP(self));
+
+ mud_telnet_msp_parser_reset(self);
+
+ if(self->priv->prev_buffer)
+ {
+ buf = g_string_prepend(buf, self->priv->prev_buffer->str);
+ g_string_free(self->priv->prev_buffer, TRUE);
+ self->priv->prev_buffer = NULL;
+ }
+
+ while(self->priv->msp_parser.lex_pos_start < *len)
+ {
+ switch(self->priv->msp_parser.state)
+ {
+ case MSP_STATE_TEXT:
+ if(buf->str[self->priv->msp_parser.lex_pos_start] == '!')
+ self->priv->msp_parser.state = MSP_STATE_POSSIBLE_COMMAND;
+ else
+ {
+ 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(self->priv->msp_parser.lex_pos_start + 1 == *len)
+ continue;
+ else if(buf->str[self->priv->msp_parser.lex_pos_start + 1] != '!')
+ {
+ 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;
+ }
+
+ self->priv->msp_parser.state = MSP_STATE_COMMAND;
+ break;
+
+ case MSP_STATE_COMMAND:
+ if(self->priv->msp_parser.lex_pos_start + 8 >= *len)
+ {
+ self->priv->prev_buffer = g_string_new(NULL);
+
+ count = self->priv->msp_parser.lex_pos_start;
+
+ while(count != buf->len)
+ self->priv->prev_buffer =
+ g_string_append_c(self->priv->prev_buffer, buf->str[count++]);
+
+ self->priv->msp_parser.lex_pos_start += count;
+ continue;
+ }
+
+ 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. */
+ 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++]);
+
+ self->priv->msp_parser.state = MSP_STATE_TEXT;
+ continue;
+ }
+
+ // Skip leading (
+ self->priv->msp_parser.lex_pos_start += 8;
+ self->priv->msp_parser.state = MSP_STATE_GET_ARGS;
+ continue;
+ break;
+
+ case MSP_STATE_GET_ARGS:
+ self->priv->msp_parser.lex_pos_end = self->priv->msp_parser.lex_pos_start;
+
+ if(self->priv->msp_parser.arg_buffer == NULL)
+ self->priv->msp_parser.arg_buffer = g_string_new(NULL);
+
+ 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(self->priv->msp_parser.lex_pos_end >= *len &&
+ buf->str[self->priv->msp_parser.lex_pos_end - 1] != ')')
+ {
+ self->priv->msp_parser.lex_pos_start =
+ self->priv->msp_parser.lex_pos_end;
+ continue;
+ }
+
+ self->priv->msp_parser.state = MSP_STATE_PARSE_ARGS;
+
+ break;
+
+ case MSP_STATE_PARSE_ARGS:
+ mud_telnet_msp_parser_args(self);
+
+ 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(self->priv->msp_parser.state == MSP_STATE_TEXT)
+ {
+ ret = g_string_new(g_strdup(self->priv->msp_parser.output->str));
+ *len = self->priv->msp_parser.output->len;
+ }
+
+ g_string_free(buf, TRUE);
+ *(&buf) = NULL;
+
+ return ret;
+}
+
+void
+mud_telnet_msp_download_item_free(MudMSPDownloadItem *item)
+{
+ if(!item)
+ return;
+
+ if(item->url)
+ g_free(item->url);
+
+ if(item->file)
+ g_free(item->file);
+
+ g_free(item);
+}
+
+void
+mud_telnet_msp_stop_playing(MudTelnetMsp *self, MudMSPTypes type)
+{
+ 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;
+}
+
+/* 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(MudTelnetMsp *self)
+{
+ gint state = ARG_STATE_FILE;
+ gint i;
+ GString *buffer;
+ gchar *args;
+ gint len;
+ MudMSPCommand *command;
+ MudConnectionView *view;
+
+ g_return_if_fail(MUD_IS_TELNET_MSP(self));
+
+ 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;
+ command->C = NULL;
+ command->T = NULL;
+ command->U = NULL;
+ command->P = NULL;
+
+ g_object_get(view, "mud-name", &command->mud_name, NULL);
+ command->sfx_type = NULL;
+
+ /* Load defaults */
+ command->volume = 100;
+ command->priority = 50;
+ command->initial_repeat_count = 1;
+ command->current_repeat_count = 1;
+ command->loop = FALSE;
+ command->cont = (self->priv->msp_type == MSP_TYPE_MUSIC);
+
+ for(i = 0; i < len; ++i)
+ {
+ if(args[i] == ' ' || args[i] == '=' || args[i] == '"')
+ continue;
+
+ switch(state)
+ {
+ case ARG_STATE_FILE:
+ if(mud_telnet_msp_parser_is_param_char(args[i]) &&
+ mud_telnet_msp_parser_switch_on_param_char(&state, args, i, len))
+ {
+ command->fName = g_strdup(buffer->str);
+ g_string_free(buffer, TRUE);
+ buffer = g_string_new(NULL);
+ }
+ else
+ buffer = g_string_append_c(buffer, args[i]);
+ break;
+
+ case ARG_STATE_V:
+ if(mud_telnet_msp_parser_is_param_char(args[i]) &&
+ mud_telnet_msp_parser_switch_on_param_char(&state, args, i, len))
+ {
+ command->V = g_strdup(buffer->str);
+ g_string_free(buffer, TRUE);
+ buffer = g_string_new(NULL);
+ }
+ else
+ buffer = g_string_append_c(buffer, args[i]);
+ break;
+
+ case ARG_STATE_L:
+ if(mud_telnet_msp_parser_is_param_char(args[i]) &&
+ mud_telnet_msp_parser_switch_on_param_char(&state, args, i, len))
+ {
+ command->L = g_strdup(buffer->str);
+ g_string_free(buffer, TRUE);
+ buffer = g_string_new(NULL);
+ }
+ else
+ buffer = g_string_append_c(buffer, args[i]);
+ break;
+
+ case ARG_STATE_C:
+ if(mud_telnet_msp_parser_is_param_char(args[i]) &&
+ mud_telnet_msp_parser_switch_on_param_char(&state, args, i, len))
+ {
+ command->C = g_strdup(buffer->str);
+ g_string_free(buffer, TRUE);
+ buffer = g_string_new(NULL);
+ }
+ else
+ buffer = g_string_append_c(buffer, args[i]);
+ break;
+
+ case ARG_STATE_T:
+ if(mud_telnet_msp_parser_is_param_char(args[i]) &&
+ mud_telnet_msp_parser_switch_on_param_char(&state, args, i, len))
+ {
+ command->T = g_strdup(buffer->str);
+ g_string_free(buffer, TRUE);
+ buffer = g_string_new(NULL);
+ }
+ else
+ buffer = g_string_append_c(buffer, args[i]);
+ break;
+
+ case ARG_STATE_U:
+ if(mud_telnet_msp_parser_is_param_char(args[i]) &&
+ mud_telnet_msp_parser_switch_on_param_char(&state, args, i, len))
+ {
+ if(buffer->str[buffer->len - 1] != '/')
+ buffer = g_string_append_c(buffer, '/');
+
+ command->U = g_strdup(buffer->str);
+ g_string_free(buffer, TRUE);
+ buffer = g_string_new(NULL);
+ }
+ else
+ buffer = g_string_append_c(buffer, args[i]);
+ break;
+
+ case ARG_STATE_P:
+ if(mud_telnet_msp_parser_is_param_char(args[i]) &&
+ mud_telnet_msp_parser_switch_on_param_char(&state, args, i, len))
+ {
+ command->P = g_strdup(buffer->str);
+ g_string_free(buffer, TRUE);
+ buffer = g_string_new(NULL);
+ }
+ else
+ buffer = g_string_append_c(buffer, args[i]);
+ break;
+ }
+ }
+
+ switch(state)
+ {
+ case ARG_STATE_FILE:
+ command->fName = g_strdup(buffer->str);
+ break;
+
+ case ARG_STATE_V:
+ command->V = g_strdup(buffer->str);
+ break;
+
+ case ARG_STATE_L:
+ command->L = g_strdup(buffer->str);
+ break;
+
+ case ARG_STATE_C:
+ command->C = g_strdup(buffer->str);
+ break;
+
+ case ARG_STATE_T:
+ command->T = g_strdup(buffer->str);
+ break;
+
+ case ARG_STATE_U:
+ if(buffer->str[buffer->len - 1] != '/')
+ buffer = g_string_append_c(buffer, '/');
+
+ command->U = g_strdup(buffer->str);
+ break;
+
+ case ARG_STATE_P:
+ command->P = g_strdup(buffer->str);
+ break;
+ }
+
+ if(command->C)
+ command->cont = atoi(command->C);
+
+ if(command->T)
+ command->sfx_type = g_strdup(command->T);
+
+ if(command->V)
+ command->volume = atoi(command->V);
+
+ if(command->P)
+ command->priority = atoi(command->P);
+
+ if(command->L)
+ {
+ command->initial_repeat_count = atoi(command->L);
+
+ if(command->initial_repeat_count == 0)
+ command->initial_repeat_count = 1;
+
+ command->current_repeat_count = command->initial_repeat_count;
+
+ if(command->current_repeat_count == -1)
+ command->loop = TRUE;
+ }
+
+ mud_telnet_msp_process_command(self, command);
+
+ g_free(args);
+ g_string_free(buffer, TRUE);
+}
+
+static gboolean
+mud_telnet_msp_parser_is_param_char(gchar c)
+{
+ return (c == 'V' || c == 'L' || c == 'C' ||
+ c == 'T' || c == 'U' || c == 'P');
+}
+
+static gboolean
+mud_telnet_msp_parser_switch_on_param_char(gint *state, gchar *buf,
+ gint index, gint len)
+{
+ if(index + 1 == len)
+ return FALSE;
+
+ if(buf[index + 1] != '=')
+ return FALSE;
+
+ switch(buf[index])
+ {
+ case 'V':
+ *state = ARG_STATE_V;
+ return TRUE;
+ break;
+
+ case 'L':
+ *state = ARG_STATE_L;
+ return TRUE;
+ break;
+
+ case 'C':
+ *state = ARG_STATE_C;
+ return TRUE;
+ break;
+
+ case 'T':
+ *state = ARG_STATE_T;
+ return TRUE;
+ break;
+
+ case 'U':
+ *state = ARG_STATE_U;
+ return TRUE;
+ break;
+
+ case 'P':
+ *state = ARG_STATE_P;
+ return TRUE;
+ break;
+ }
+
+ return FALSE;
+}
+
+static void
+mud_telnet_msp_command_free(MudMSPCommand *command)
+{
+ if(command == NULL)
+ return;
+
+ if(command->fName)
+ g_free(command->fName);
+
+ if(command->mud_name)
+ g_free(command->mud_name);
+
+ if(command->sfx_type)
+ g_free(command->sfx_type);
+
+ if(command->V)
+ g_free(command->V);
+
+ if(command->L)
+ g_free(command->L);
+
+ if(command->P)
+ g_free(command->P);
+
+ if(command->C)
+ g_free(command->C);
+
+ if(command->T)
+ g_free(command->T);
+
+ if(command->U)
+ g_free(command->U);
+
+ g_free(command);
+
+}
+
+static void
+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" :
+ "Music" );
+ g_log("Telnet", G_LOG_LEVEL_INFO,
+ "Filename: %s", (command->fName != NULL) ? command->fName :
+ "<null>");
+ g_log("Telnet", G_LOG_LEVEL_INFO,
+ "V: %s", (command->V != NULL) ? command->V : "<null>");
+ g_log("Telnet", G_LOG_LEVEL_INFO,
+ "L: %s", (command->L != NULL) ? command->L : "<null>");
+ g_log("Telnet", G_LOG_LEVEL_INFO,
+ "C: %s", (command->C != NULL) ? command->C : "<null>");
+ g_log("Telnet", G_LOG_LEVEL_INFO,
+ "T: %s", (command->T != NULL) ? command->T : "<null>");
+ g_log("Telnet", G_LOG_LEVEL_INFO,
+ "U: %s", (command->U != NULL) ? command->U : "<null>");
+ g_log("Telnet", G_LOG_LEVEL_INFO,
+ "P: %s", (command->P != NULL) ? command->P : "<null>");
+ g_log("Telnet", G_LOG_LEVEL_INFO,
+ "Sfx Type: %s Volume: %d Priority: %d Repeat %d times. %s %s",
+ (command->sfx_type) ? command->sfx_type:"None", command->volume,
+ command->priority, command->initial_repeat_count, (command->loop) ?
+ "Looping" : "Not Looping",
+ (command->cont) ? "Continue" : "Stop");
+
+ if(command->fName && strcmp(command->fName, "Off") == 0)
+ {
+ if(command->U)
+ {
+ if(self->priv->base_url)
+ g_free(self->priv->base_url);
+
+ self->priv->base_url = g_strdup(command->U);
+ }
+ else
+ mud_telnet_msp_stop_playing(self, command->type);
+
+ mud_telnet_msp_command_free(command);
+
+ return;
+ }
+
+ if(self->priv->sound[command->type].current_command)
+ {
+ if(self->priv->sound[command->type].playing)
+ {
+ if(command->priority >
+ self->priv->sound[command->type].current_command->priority)
+ {
+ 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(self, command->type);
+ self->priv->sound[command->type].current_command = command;
+ mud_telnet_msp_start_playing(self, command->type);
+ }
+ }
+ else
+ {
+ self->priv->sound[command->type].current_command = command;
+ mud_telnet_msp_start_playing(self, command->type);
+ }
+}
+
+static void
+mud_telnet_msp_start_playing(MudTelnetMsp *self, MudMSPTypes type)
+{
+ g_return_if_fail(MUD_IS_TELNET_MSP(self));
+
+ if(!self->priv->sound[type].current_command)
+ return;
+
+ if(mud_telnet_msp_get_files(self, type))
+ {
+ gint num = 0;
+
+ self->priv->sound[type].playing = TRUE;
+
+ if(self->priv->sound[type].files_len != 0)
+ num = rand() % self->priv->sound[type].files_len;
+
+ 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)self->priv->sound[type].current_command->volume/100,
+ NULL);
+
+ 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 (self->priv->sound[type].bus,
+ mud_telnet_msp_sound_bus_call, self);
+ else
+ gst_bus_add_watch (self->priv->sound[type].bus,
+ mud_telnet_msp_music_bus_call, self);
+
+ gst_object_unref (self->priv->sound[type].bus);
+
+ gst_element_set_state (self->priv->sound[type].play, GST_STATE_PLAYING);
+ }
+}
+
+static gboolean
+mud_telnet_msp_get_files(MudTelnetMsp *self, MudMSPTypes type)
+{
+ gchar sound_dir[2048];
+ const gchar *file;
+ gchar **files;
+ gchar **structure;
+ GString *file_output;
+ GString *url_output;
+ 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));
+
+ 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(), mud_name);
+ if(!g_file_test(sound_dir, G_FILE_TEST_IS_DIR))
+ mkdir(sound_dir, 0777 );
+
+ 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);
+
+ for(i = 0; i < depth - 1; ++i)
+ {
+ subdir = g_string_append(subdir, structure[i]);
+ subdir = g_string_append_c(subdir, '/');
+ }
+
+ file_name = g_string_new(structure[depth - 1]);
+
+ g_strfreev(structure);
+
+ full_dir = g_string_new(sound_dir);
+ full_dir = g_string_append(full_dir, subdir->str);
+
+ 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);
+
+ file_output = g_string_new(NULL);
+
+ regex = g_pattern_spec_new(file_name->str);
+
+ dir = g_dir_open(full_dir->str, 0, NULL);
+
+ while((file = g_dir_read_name(dir)) != NULL)
+ {
+ if(g_pattern_match_string(regex, file))
+ {
+ file_output = g_string_append(file_output, "file://");
+ file_output = g_string_append(file_output, full_dir->str);
+ file_output = g_string_append_c(file_output, '/');
+ file_output = g_string_append(file_output, file);
+ file_output = g_string_append_c(file_output, '\n');
+ }
+ }
+
+ g_dir_close(dir);
+
+ // Try searching again in main directory since
+ // 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 && self->priv->sound[type].current_command->T)
+ {
+ g_string_free(full_dir, TRUE);
+ full_dir = g_string_new(sound_dir);
+ full_dir = g_string_append(full_dir, subdir->str);
+
+ dir = g_dir_open(full_dir->str, 0, NULL);
+
+ while((file = g_dir_read_name(dir)) != NULL)
+ {
+ if(g_pattern_match_string(regex, file))
+ {
+ file_output = g_string_append(file_output, "file://");
+ file_output = g_string_append(file_output, full_dir->str);
+ file_output = g_string_append_c(file_output, '/');
+ file_output = g_string_append(file_output, file);
+ file_output = g_string_append_c(file_output, '\n');
+ }
+ }
+
+ g_dir_close(dir);
+ }
+
+ g_pattern_spec_free(regex);
+
+ if(file_output->len == 0) // no matches, file doesn't exist.
+ {
+ url_output = g_string_new(NULL);
+
+ if(self->priv->base_url || self->priv->sound[type].current_command->U)
+ {
+ if(self->priv->base_url)
+ url_output = g_string_append(url_output, self->priv->base_url);
+ else
+ 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(self->priv->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(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);
+
+ self->priv->sound[type].current_command->priority = 0;
+
+ mud_connection_view_queue_download(view, url_output->str, file_output->str);
+ }
+
+ g_string_free(url_output, TRUE);
+ g_string_free(file_output, TRUE);
+ g_string_free(full_dir, TRUE);
+ g_string_free(subdir, TRUE);
+ g_string_free(file_name, TRUE);
+
+ return FALSE;
+ }
+
+ files = g_strsplit(file_output->str, "\n", 0);
+
+ if(self->priv->sound[type].files)
+ g_strfreev(self->priv->sound[type].files);
+
+ 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);
+ g_string_free(subdir, TRUE);
+ g_string_free(file_name, TRUE);
+
+ return TRUE;
+}
+
+static gboolean
+mud_telnet_msp_sound_bus_call (GstBus *bus, GstMessage *msg, gpointer data)
+{
+ MudTelnetMsp *self = MUD_TELNET_MSP(data);
+
+ switch (GST_MESSAGE_TYPE (msg))
+ {
+ case GST_MESSAGE_EOS:
+ self->priv->sound[MSP_TYPE_SOUND].playing = FALSE;
+
+ self->priv->sound[MSP_TYPE_SOUND].current_command->current_repeat_count--;
+
+ gst_element_set_state (self->priv->sound[MSP_TYPE_SOUND].play, GST_STATE_NULL);
+
+ 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(self->priv->sound[MSP_TYPE_SOUND].files_len != 0)
+ num = rand() % self->priv->sound[MSP_TYPE_SOUND].files_len;
+
+ 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 (self->priv->sound[MSP_TYPE_SOUND].play, GST_STATE_PLAYING);
+ }
+ else
+ mud_telnet_msp_stop_playing(self, MSP_TYPE_SOUND);
+ break;
+
+ case GST_MESSAGE_ERROR:
+ {
+ gchar *debug;
+ GError *err;
+
+ gst_message_parse_error (msg, &err, &debug);
+ g_free (debug);
+
+ g_warning ("Error: %s", err->message);
+ g_error_free (err);
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+mud_telnet_msp_music_bus_call (GstBus *bus, GstMessage *msg, gpointer data)
+{
+ MudTelnetMsp *self = MUD_TELNET_MSP(data);
+
+ switch (GST_MESSAGE_TYPE (msg))
+ {
+ case GST_MESSAGE_EOS:
+ self->priv->sound[MSP_TYPE_MUSIC].playing = FALSE;
+
+ self->priv->sound[MSP_TYPE_MUSIC].current_command->current_repeat_count--;
+
+ gst_element_set_state (self->priv->sound[MSP_TYPE_MUSIC].play, GST_STATE_NULL);
+
+ 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(self->priv->sound[MSP_TYPE_MUSIC].files_len != 0)
+ num = rand() % self->priv->sound[MSP_TYPE_MUSIC].files_len;
+
+ 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 (self->priv->sound[MSP_TYPE_MUSIC].play, GST_STATE_PLAYING);
+ }
+ else
+ mud_telnet_msp_stop_playing(self, MSP_TYPE_MUSIC);
+
+ break;
+
+ case GST_MESSAGE_ERROR:
+ {
+ gchar *debug;
+ GError *err;
+
+ gst_message_parse_error (msg, &err, &debug);
+ g_free (debug);
+
+ g_warning ("Error: %s", err->message);
+ g_error_free (err);
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+#endif
+
Added: trunk/src/handlers/mud-telnet-msp.h
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-msp.h Tue Mar 17 18:08:13 2009
@@ -0,0 +1,151 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-msp.h
+ * Copyright (C) 2008-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_MSP_H
+#define MUD_TELNET_MSP_H
+
+#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,
+ MSP_TYPE_MUSIC
+} MudMSPTypes;
+
+typedef enum
+{
+ MSP_STATE_TEXT,
+ MSP_STATE_POSSIBLE_COMMAND,
+ MSP_STATE_COMMAND,
+ MSP_STATE_GET_ARGS,
+ 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;
+
+ MudMSPStates state;
+
+ gint lex_pos_start;
+ gint lex_pos_end;
+
+ GString *output;
+ GString *arg_buffer;
+} MudMSPParser;
+
+typedef struct MudMSPCommand
+{
+ MudMSPTypes type;
+
+ gchar *fName;
+
+ gchar *V;
+ gchar *L;
+ gchar *P;
+ gchar *C;
+ gchar *T;
+ gchar *U;
+
+ gchar *mud_name;
+ gchar *sfx_type;
+
+ gint volume;
+ gint priority;
+ gint initial_repeat_count;
+ gint current_repeat_count;
+ gboolean loop;
+ gboolean cont;
+
+} MudMSPCommand;
+
+typedef struct MudMSPDownloadItem
+{
+ gchar *url;
+ gchar *file;
+} MudMSPDownloadItem;
+
+typedef struct MudMSPSound
+{
+ gboolean playing;
+ gchar **files;
+ gint files_len;
+
+ GstElement *play;
+ GstBus *bus;
+
+ MudMSPCommand *current_command;
+} MudMSPSound;
+
+GType mud_telnet_msp_get_type (void);
+
+void mud_telnet_msp_download_item_free(MudMSPDownloadItem *item);
+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);
+
+G_END_DECLS
+
+#endif // ENABLE_MSP
+
+#endif // MUD_TELNET_MSP_H
+
Added: trunk/src/handlers/mud-telnet-mssp.c
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-mssp.c Tue Mar 17 18:08:13 2009
@@ -0,0 +1,410 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-mssp.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-mssp.h"
+
+struct _MudTelnetMsspPrivate
+{
+ /* Interface Properties */
+ MudTelnet *telnet;
+ gboolean enabled;
+ gint option;
+
+ /* Private Instance Members */
+ GHashTable *mssp_data;
+};
+
+/* Property Identifiers */
+enum
+{
+ PROP_MUD_TELNET_MSSP_0,
+ PROP_ENABLED,
+ PROP_HANDLES_OPTION,
+ PROP_TELNET,
+ PROP_MSSP
+};
+
+enum
+{
+ PARSE_STATE_VAR,
+ PARSE_STATE_VAR_STRING,
+ PARSE_STATE_VAL,
+ PARSE_STATE_VAL_STRING
+};
+
+/* Class Functions */
+static void mud_telnet_mssp_init (MudTelnetMssp *self);
+static void mud_telnet_mssp_class_init (MudTelnetMsspClass *klass);
+static void mud_telnet_mssp_interface_init(MudTelnetHandlerInterface *iface);
+static void mud_telnet_mssp_finalize (GObject *object);
+static GObject *mud_telnet_mssp_constructor (GType gtype,
+ guint n_properties,
+ GObjectConstructParam *properties);
+static void mud_telnet_mssp_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void mud_telnet_mssp_get_property(GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+/*Interface Implementation */
+void mud_telnet_mssp_enable(MudTelnetHandler *self);
+void mud_telnet_mssp_disable(MudTelnetHandler *self);
+void mud_telnet_mssp_handle_sub_neg(MudTelnetHandler *self,
+ guchar *buf,
+ guint len);
+
+/* Private Methods */
+static void mud_telnet_mssp_destroy_key(gpointer k);
+static void mud_telnet_mssp_destroy_value(gpointer c);
+
+/* Create the Type. We implement MudTelnetHandlerInterface */
+G_DEFINE_TYPE_WITH_CODE(MudTelnetMssp, mud_telnet_mssp, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (MUD_TELNET_HANDLER_TYPE,
+ mud_telnet_mssp_interface_init));
+/* MudTelnetMssp class functions */
+static void
+mud_telnet_mssp_class_init (MudTelnetMsspClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+ /* Override base object constructor */
+ object_class->constructor = mud_telnet_mssp_constructor;
+
+ /* Override base object's finalize */
+ object_class->finalize = mud_telnet_mssp_finalize;
+
+ /* Override base object property methods */
+ object_class->set_property = mud_telnet_mssp_set_property;
+ object_class->get_property = mud_telnet_mssp_get_property;
+
+ /* Add private data to class */
+ g_type_class_add_private(klass, sizeof(MudTelnetMsspPrivate));
+
+ /* 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");
+ /* Custom Class Properties */
+ g_object_class_install_property(object_class,
+ PROP_MSSP,
+ g_param_spec_pointer("mssp-data",
+ "MSSP Data",
+ "The MSSP data provided by the mud.",
+ G_PARAM_READABLE));
+}
+
+static void
+mud_telnet_mssp_interface_init(MudTelnetHandlerInterface *iface)
+{
+ iface->Enable = mud_telnet_mssp_enable;
+ iface->Disable = mud_telnet_mssp_disable;
+ iface->HandleSubNeg = mud_telnet_mssp_handle_sub_neg;
+}
+
+static void
+mud_telnet_mssp_init (MudTelnetMssp *self)
+{
+ /* Get our private data */
+ self->priv = MUD_TELNET_MSSP_GET_PRIVATE(self);
+
+ /* Set the defaults */
+ self->priv->telnet = NULL;
+ self->priv->option = TELOPT_MSSP;
+ self->priv->enabled = FALSE;
+
+ self->priv->mssp_data = NULL;
+}
+
+static GObject *
+mud_telnet_mssp_constructor (GType gtype,
+ guint n_properties,
+ GObjectConstructParam *properties)
+{
+ MudTelnetMssp *self;
+ GObject *obj;
+ MudTelnetMsspClass *klass;
+ GObjectClass *parent_class;
+
+ /* Chain up to parent constructor */
+ klass = MUD_TELNET_MSSP_CLASS( g_type_class_peek(MUD_TYPE_TELNET_MSSP) );
+ parent_class = G_OBJECT_CLASS( g_type_class_peek_parent(klass) );
+ obj = parent_class->constructor(gtype, n_properties, properties);
+
+ self = MUD_TELNET_MSSP(obj);
+
+ if(!self->priv->telnet)
+ {
+ g_printf("ERROR: Tried to instantiate MudTelnetMssp without passing parent MudTelnet\n");
+ g_error("Tried to instantiate MudTelnetMssp without passing parent MudTelnet");
+ }
+
+ self->priv->mssp_data = g_hash_table_new_full(g_str_hash,
+ g_str_equal,
+ mud_telnet_mssp_destroy_key,
+ mud_telnet_mssp_destroy_value);
+
+ return obj;
+}
+
+static void
+mud_telnet_mssp_finalize (GObject *object)
+{
+ MudTelnetMssp *self;
+ GObjectClass *parent_class;
+
+ self = MUD_TELNET_MSSP(object);
+
+ if(self->priv->mssp_data)
+ g_hash_table_destroy(self->priv->mssp_data);
+
+ parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
+ parent_class->finalize(object);
+}
+
+static void
+mud_telnet_mssp_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MudTelnetMssp *self;
+
+ self = MUD_TELNET_MSSP(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_mssp_get_property(GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MudTelnetMssp *self;
+
+ self = MUD_TELNET_MSSP(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_MSSP:
+ g_value_set_pointer(value, self->priv->mssp_data);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+/* Interface Implementation */
+void
+mud_telnet_mssp_enable(MudTelnetHandler *handler)
+{
+ MudTelnetMssp *self;
+
+ self = MUD_TELNET_MSSP(handler);
+
+ g_return_if_fail(MUD_IS_TELNET_MSSP(self));
+
+ self->priv->enabled = TRUE;
+
+ g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "MSSP Enabled");
+}
+
+void
+mud_telnet_mssp_disable(MudTelnetHandler *handler)
+{
+ MudTelnetMssp *self;
+
+ self = MUD_TELNET_MSSP(handler);
+
+ g_return_if_fail(MUD_IS_TELNET_MSSP(self));
+
+ self->priv->enabled = FALSE;
+
+ g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "MSSP Disabled");
+}
+
+void
+mud_telnet_mssp_handle_sub_neg(MudTelnetHandler *handler,
+ guchar *buf,
+ guint len)
+{
+ MudTelnetMssp *self;
+ guint i, state;
+ GString *key, *value;
+
+ self = MUD_TELNET_MSSP(handler);
+
+ g_return_if_fail(MUD_IS_TELNET_MSSP(self));
+
+ state = PARSE_STATE_VAR;
+
+ for(i = 0; i < len - 1; ++i)
+ {
+ switch(state)
+ {
+ case PARSE_STATE_VAR:
+ key = g_string_new(NULL);
+
+ state = PARSE_STATE_VAR_STRING;
+ break;
+
+ case PARSE_STATE_VAR_STRING:
+ if( buf[i] != TEL_MSSP_VAL )
+ key = g_string_append_c(key, buf[i]);
+ else
+ {
+ state = PARSE_STATE_VAL;
+ i--;
+ }
+ break;
+
+ case PARSE_STATE_VAL:
+ value = g_string_new(NULL);
+
+ state = PARSE_STATE_VAL_STRING;
+ break;
+
+ case PARSE_STATE_VAL_STRING:
+ if( buf[i] != TEL_MSSP_VAR && buf[i] != TEL_MSSP_VAL )
+ value = g_string_append_c(value, buf[i]);
+ else
+ {
+ switch( buf[i] )
+ {
+ /* VAR's can have multiple VALs assigned to them. */
+ case TEL_MSSP_VAL:
+ g_hash_table_replace(self->priv->mssp_data,
+ g_strdup(key->str),
+ g_string_free(value, FALSE));
+
+ state = PARSE_STATE_VAL;
+ i--;
+ break;
+
+ case TEL_MSSP_VAR:
+ g_hash_table_replace(self->priv->mssp_data,
+ g_string_free(key, FALSE),
+ g_string_free(value, FALSE));
+
+ state = PARSE_STATE_VAR;
+ i--;
+ break;
+ }
+ }
+
+ if( i + 1 == len - 1) // Last value in subnegotiation.
+ g_hash_table_replace(self->priv->mssp_data,
+ g_string_free(key, FALSE),
+ g_string_free(value, FALSE));
+
+ break;
+ }
+ }
+
+ /* Log the results */
+ {
+ GList *key_list, *entry;
+
+ g_log("Telnet", G_LOG_LEVEL_MESSAGE, "%s", "MSSP Data:");
+
+ key_list = g_hash_table_get_keys(self->priv->mssp_data);
+
+ entry = key_list;
+
+ while(entry)
+ {
+ const gchar *keyv = entry->data;
+ const gchar *valv = g_hash_table_lookup(self->priv->mssp_data, keyv);
+
+ g_log("Telnet",
+ G_LOG_LEVEL_MESSAGE,
+ "\t%s = %s",
+ keyv, (valv) ? valv : "<null>");
+
+ entry = g_list_next(entry);
+ }
+
+ g_list_free(key_list);
+ }
+}
+
+/* Private Methods */
+static void
+mud_telnet_mssp_destroy_key(gpointer k)
+{
+ gchar *key = (gchar *)k;
+
+ if(key)
+ g_free(key);
+}
+
+static void
+mud_telnet_mssp_destroy_value(gpointer v)
+{
+ gchar *value = (gchar *)v;
+
+ if(value)
+ g_free(value);
+}
+
Added: trunk/src/handlers/mud-telnet-mssp.h
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-mssp.h Tue Mar 17 18:08:13 2009
@@ -0,0 +1,57 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-mssp.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_MSSP_H
+#define MUD_TELNET_MSSP_H
+
+G_BEGIN_DECLS
+
+#include <glib.h>
+
+#define MUD_TYPE_TELNET_MSSP (mud_telnet_mssp_get_type ())
+#define MUD_TELNET_MSSP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MUD_TYPE_TELNET_MSSP, MudTelnetMssp))
+#define MUD_TELNET_MSSP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MUD_TYPE_TELNET_MSSP, MudTelnetMsspClass))
+#define MUD_IS_TELNET_MSSP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), MUD_TYPE_TELNET_MSSP))
+#define MUD_IS_TELNET_MSSP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MUD_TYPE_TELNET_MSSP))
+#define MUD_TELNET_MSSP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MUD_TYPE_TELNET_MSSP, MudTelnetMsspClass))
+#define MUD_TELNET_MSSP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUD_TYPE_TELNET_MSSP, MudTelnetMsspPrivate))
+
+typedef struct _MudTelnetMssp MudTelnetMssp;
+typedef struct _MudTelnetMsspClass MudTelnetMsspClass;
+typedef struct _MudTelnetMsspPrivate MudTelnetMsspPrivate;
+
+struct _MudTelnetMsspClass
+{
+ GObjectClass parent_class;
+};
+
+struct _MudTelnetMssp
+{
+ GObject parent_instance;
+
+ /*< private >*/
+ MudTelnetMsspPrivate *priv;
+};
+
+GType mud_telnet_mssp_get_type (void);
+
+G_END_DECLS
+
+#endif // MUD_TELNET_MSSP_H
+
Added: trunk/src/handlers/mud-telnet-naws.c
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-naws.c Tue Mar 17 18:08:13 2009
@@ -0,0 +1,357 @@
+/* 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 <vte/vte.h>
+#include <gnet.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 */
+ gulong resized_signal;
+};
+
+/* 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);
+
+/* Callbacks */
+static void mud_telnet_naws_resized_cb(MudWindow *window,
+ gint width,
+ gint height,
+ MudTelnetNaws *self);
+
+/* Private Methods */
+static void mud_telnet_naws_send(MudTelnetNaws *self, gint width, gint height);
+
+/* 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;
+
+ self->priv->resized_signal = 0;
+}
+
+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;
+ MudConnectionView *view;
+ MudWindow *window;
+ GObjectClass *parent_class;
+
+ self = MUD_TELNET_NAWS(object);
+
+ g_object_get(self->priv->telnet, "parent-view", &view, NULL);
+ g_object_get(view, "window", &window, NULL);
+
+ if(self->priv->resized_signal != 0)
+ g_signal_handler_disconnect(window, self->priv->resized_signal);
+
+ 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;
+ MudWindow *window;
+ MudConnectionView *view;
+ VteTerminal *terminal;
+
+ self = MUD_TELNET_NAWS(handler);
+
+ g_return_if_fail(MUD_IS_TELNET_NAWS(self));
+
+ self->priv->enabled = TRUE;
+
+ g_object_get(self->priv->telnet, "parent-view", &view, NULL);
+
+ g_object_get(view,
+ "terminal", &terminal,
+ "window", &window,
+ NULL);
+
+ self->priv->resized_signal =
+ g_signal_connect(window,
+ "resized",
+ G_CALLBACK(mud_telnet_naws_resized_cb),
+ self);
+
+ mud_telnet_naws_send(self,
+ terminal->column_count,
+ terminal->row_count);
+
+ g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "NAWS Enabled");
+}
+
+void
+mud_telnet_naws_disable(MudTelnetHandler *handler)
+{
+ MudTelnetNaws *self;
+ MudWindow *window;
+ 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_get(view,
+ "window", &window,
+ NULL);
+
+ g_signal_handler_disconnect(window, self->priv->resized_signal);
+
+ 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;
+}
+
+/* Callbacks */
+static void
+mud_telnet_naws_resized_cb(MudWindow *window,
+ gint width,
+ gint height,
+ MudTelnetNaws *self)
+{
+ MudConnectionView *view;
+
+ g_object_get(self->priv->telnet,
+ "parent-view", &view,
+ NULL);
+
+ if(view->connection &&
+ gnet_conn_is_connected(view->connection) &&
+ self->priv->enabled)
+ mud_telnet_naws_send(self,
+ view->terminal->column_count,
+ view->terminal->row_count);
+}
+
+/* Private Methods */
+static 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/handlers/mud-telnet-naws.h
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-naws.h Tue Mar 17 18:08:13 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);
+
+
+
+G_END_DECLS
+
+#endif // MUD_TELNET_NAWS_H
+
Added: trunk/src/handlers/mud-telnet-new-environ.c
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-new-environ.c Tue Mar 17 18:08:13 2009
@@ -0,0 +1,435 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-new-environ.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-new-environ.h"
+
+struct _MudTelnetNewEnvironPrivate
+{
+ /* Interface Properties */
+ MudTelnet *telnet;
+ gboolean enabled;
+ gint option;
+
+ /* Private Instance Members */
+ GHashTable *new_environ_data;
+};
+
+/* Property Identifiers */
+enum
+{
+ PROP_MUD_TELNET_NEWENVIRON_0,
+ PROP_ENABLED,
+ PROP_HANDLES_OPTION,
+ PROP_TELNET,
+ PROP_ENVIRON
+};
+
+enum
+{
+ PARSE_STATE_VAR,
+ PARSE_STATE_VAR_STRING,
+ PARSE_STATE_VAL,
+ PARSE_STATE_VAL_STRING
+};
+
+/* Class Functions */
+static void mud_telnet_newenviron_init (MudTelnetNewEnviron *self);
+static void mud_telnet_newenviron_class_init (MudTelnetNewEnvironClass *klass);
+static void mud_telnet_newenviron_interface_init(MudTelnetHandlerInterface *iface);
+static void mud_telnet_newenviron_finalize (GObject *object);
+static GObject *mud_telnet_newenviron_constructor (GType gtype,
+ guint n_properties,
+ GObjectConstructParam *properties);
+static void mud_telnet_newenviron_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void mud_telnet_newenviron_get_property(GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+/*Interface Implementation */
+void mud_telnet_newenviron_enable(MudTelnetHandler *self);
+void mud_telnet_newenviron_disable(MudTelnetHandler *self);
+void mud_telnet_newenviron_handle_sub_neg(MudTelnetHandler *self,
+ guchar *buf,
+ guint len);
+
+/* Private Methods */
+static void mud_telnet_newenviron_destroy_key(gpointer k);
+static void mud_telnet_newenviron_destroy_value(gpointer c);
+
+/* Create the Type. We implement MudTelnetHandlerInterface */
+G_DEFINE_TYPE_WITH_CODE(MudTelnetNewEnviron, mud_telnet_newenviron, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (MUD_TELNET_HANDLER_TYPE,
+ mud_telnet_newenviron_interface_init));
+/* MudTelnetNewEnviron class functions */
+static void
+mud_telnet_newenviron_class_init (MudTelnetNewEnvironClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+ /* Override base object constructor */
+ object_class->constructor = mud_telnet_newenviron_constructor;
+
+ /* Override base object's finalize */
+ object_class->finalize = mud_telnet_newenviron_finalize;
+
+ /* Override base object property methods */
+ object_class->set_property = mud_telnet_newenviron_set_property;
+ object_class->get_property = mud_telnet_newenviron_get_property;
+
+ /* Add private data to class */
+ g_type_class_add_private(klass, sizeof(MudTelnetNewEnvironPrivate));
+
+ /* 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");
+ /* Custom Class Properties */
+ g_object_class_install_property(object_class,
+ PROP_ENVIRON,
+ g_param_spec_pointer("new-environ-data",
+ "NEW-ENVIRON Data",
+ "The Environ data provided by the mud.",
+ G_PARAM_READABLE));
+}
+
+static void
+mud_telnet_newenviron_interface_init(MudTelnetHandlerInterface *iface)
+{
+ iface->Enable = mud_telnet_newenviron_enable;
+ iface->Disable = mud_telnet_newenviron_disable;
+ iface->HandleSubNeg = mud_telnet_newenviron_handle_sub_neg;
+}
+
+static void
+mud_telnet_newenviron_init (MudTelnetNewEnviron *self)
+{
+ /* Get our private data */
+ self->priv = MUD_TELNET_NEWENVIRON_GET_PRIVATE(self);
+
+ /* Set the defaults */
+ self->priv->telnet = NULL;
+ self->priv->option = TELOPT_NEWENVIRON;
+ self->priv->enabled = FALSE;
+
+ self->priv->new_environ_data = NULL;
+}
+
+static GObject *
+mud_telnet_newenviron_constructor (GType gtype,
+ guint n_properties,
+ GObjectConstructParam *properties)
+{
+ MudTelnetNewEnviron *self;
+ GObject *obj;
+ MudTelnetNewEnvironClass *klass;
+ GObjectClass *parent_class;
+
+ /* Chain up to parent constructor */
+ klass = MUD_TELNET_NEWENVIRON_CLASS( g_type_class_peek(MUD_TYPE_TELNET_NEWENVIRON) );
+ parent_class = G_OBJECT_CLASS( g_type_class_peek_parent(klass) );
+ obj = parent_class->constructor(gtype, n_properties, properties);
+
+ self = MUD_TELNET_NEWENVIRON(obj);
+
+ if(!self->priv->telnet)
+ {
+ g_printf("ERROR: Tried to instantiate MudTelnetNewEnviron without passing parent MudTelnet\n");
+ g_error("Tried to instantiate MudTelnetNewEnviron without passing parent MudTelnet");
+ }
+
+ self->priv->new_environ_data =
+ g_hash_table_new_full(g_str_hash,
+ g_str_equal,
+ mud_telnet_newenviron_destroy_key,
+ mud_telnet_newenviron_destroy_value);
+
+ return obj;
+}
+
+static void
+mud_telnet_newenviron_finalize (GObject *object)
+{
+ MudTelnetNewEnviron *self;
+ GObjectClass *parent_class;
+
+ self = MUD_TELNET_NEWENVIRON(object);
+
+ if(self->priv->new_environ_data)
+ g_hash_table_destroy(self->priv->new_environ_data);
+
+ parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
+ parent_class->finalize(object);
+}
+
+static void
+mud_telnet_newenviron_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MudTelnetNewEnviron *self;
+
+ self = MUD_TELNET_NEWENVIRON(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_newenviron_get_property(GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MudTelnetNewEnviron *self;
+
+ self = MUD_TELNET_NEWENVIRON(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_ENVIRON:
+ g_value_set_pointer(value, self->priv->new_environ_data);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+/* Interface Implementation */
+void
+mud_telnet_newenviron_enable(MudTelnetHandler *handler)
+{
+ MudTelnetNewEnviron *self;
+
+ self = MUD_TELNET_NEWENVIRON(handler);
+
+ g_return_if_fail(MUD_IS_TELNET_NEWENVIRON(self));
+
+ self->priv->enabled = TRUE;
+
+ /* We are only interested in USERVAR */
+ mud_telnet_send_sub_req(self->priv->telnet,
+ 2,
+ TEL_NEWENVIRON_SEND,
+ TEL_NEWENVIRON_USERVAR);
+
+ g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "NEWENVIRON Enabled");
+}
+
+void
+mud_telnet_newenviron_disable(MudTelnetHandler *handler)
+{
+ MudTelnetNewEnviron *self;
+
+ self = MUD_TELNET_NEWENVIRON(handler);
+
+ g_return_if_fail(MUD_IS_TELNET_NEWENVIRON(self));
+
+ self->priv->enabled = FALSE;
+
+ g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "NEWENVIRON Disabled");
+}
+
+void
+mud_telnet_newenviron_handle_sub_neg(MudTelnetHandler *handler,
+ guchar *buf,
+ guint len)
+{
+ MudTelnetNewEnviron *self;
+ guint i, state;
+ GString *key, *value;
+
+ self = MUD_TELNET_NEWENVIRON(handler);
+
+ g_return_if_fail(MUD_IS_TELNET_NEWENVIRON(self));
+
+ /* IAC SB NEW-ENVIRON IS IAC SE is a valid response
+ * when there are no USERVARs. Nothing to parse,
+ * bail out. */
+ if(len == 1)
+ return;
+
+ state = PARSE_STATE_VAR;
+
+ /* The first byte will be either IS or INFO. Since INFO
+ * simply updates variables we do not need to make a
+ * distinction between the two in our case.*/
+ for(i = 1; i < len - 1; ++i)
+ {
+ switch(state)
+ {
+ case PARSE_STATE_VAR:
+ key = g_string_new(NULL);
+
+ state = PARSE_STATE_VAR_STRING;
+ break;
+
+ case PARSE_STATE_VAR_STRING:
+ if( buf[i] != TEL_NEWENVIRON_VALUE )
+ key = g_string_append_c(key, buf[i]);
+ else
+ {
+ if( i + 1 != len)
+ {
+ if( buf[ i + 1] != TEL_NEWENVIRON_VALUE )
+ {
+ /* No VALUE follows USERVAR/VAR. So it
+ * is undefined. */
+ g_string_free(key, TRUE);
+
+ state == PARSE_STATE_VAR;
+ }
+ else
+ {
+ state = PARSE_STATE_VAL;
+ i--;
+ }
+ }
+ }
+ break;
+
+ case PARSE_STATE_VAL:
+ value = g_string_new(NULL);
+
+ state = PARSE_STATE_VAL_STRING;
+ break;
+
+ case PARSE_STATE_VAL_STRING:
+ if( buf[i] != TEL_NEWENVIRON_VAR &&
+ buf[i] != TEL_NEWENVIRON_USERVAR )
+ value = g_string_append_c(value, buf[i]);
+ else
+ {
+ switch( buf[i] )
+ {
+ /* We treat USERVARs and VARs the same. There
+ * shouldn't be any VARs since we don't ask for
+ * them but we'll check anyway. */
+ case TEL_NEWENVIRON_USERVAR:
+ case TEL_NEWENVIRON_VAR:
+ g_hash_table_replace(self->priv->new_environ_data,
+ g_string_free(key, FALSE),
+ g_string_free(value, FALSE));
+
+ state = PARSE_STATE_VAR;
+ i--;
+ break;
+ }
+ }
+
+ if( i + 1 == len - 1) // Last value in subnegotiation.
+ g_hash_table_replace(self->priv->new_environ_data,
+ g_string_free(key, FALSE),
+ g_string_free(value, FALSE));
+
+ break;
+ }
+ }
+
+ /* Log the results */
+ {
+ GList *key_list, *entry;
+
+ g_log("Telnet", G_LOG_LEVEL_MESSAGE, "%s", "NEW-ENVIRON Data:");
+
+ key_list = g_hash_table_get_keys(self->priv->new_environ_data);
+
+ entry = key_list;
+
+ while(entry)
+ {
+ const gchar *keyv = entry->data;
+ const gchar *valv = g_hash_table_lookup(self->priv->new_environ_data, keyv);
+
+ g_log("Telnet",
+ G_LOG_LEVEL_MESSAGE,
+ "\t%s = %s",
+ keyv, (valv) ? valv : "<null>");
+
+ entry = g_list_next(entry);
+ }
+
+ g_list_free(key_list);
+ }
+}
+
+/* Private Methods */
+static void
+mud_telnet_newenviron_destroy_key(gpointer k)
+{
+ gchar *key = (gchar *)k;
+
+ if(key)
+ g_free(key);
+}
+
+static void
+mud_telnet_newenviron_destroy_value(gpointer v)
+{
+ gchar *value = (gchar *)v;
+
+ if(value)
+ g_free(value);
+}
+
Added: trunk/src/handlers/mud-telnet-new-environ.h
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-new-environ.h Tue Mar 17 18:08:13 2009
@@ -0,0 +1,57 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-new-environ.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_NEWENVIRON_H
+#define MUD_TELNET_NEWENVIRON_H
+
+G_BEGIN_DECLS
+
+#include <glib.h>
+
+#define MUD_TYPE_TELNET_NEWENVIRON (mud_telnet_newenviron_get_type ())
+#define MUD_TELNET_NEWENVIRON(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MUD_TYPE_TELNET_NEWENVIRON, MudTelnetNewEnviron))
+#define MUD_TELNET_NEWENVIRON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MUD_TYPE_TELNET_NEWENVIRON, MudTelnetNewEnvironClass))
+#define MUD_IS_TELNET_NEWENVIRON(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), MUD_TYPE_TELNET_NEWENVIRON))
+#define MUD_IS_TELNET_NEWENVIRON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MUD_TYPE_TELNET_NEWENVIRON))
+#define MUD_TELNET_NEWENVIRON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MUD_TYPE_TELNET_NEWENVIRON, MudTelnetNewEnvironClass))
+#define MUD_TELNET_NEWENVIRON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUD_TYPE_TELNET_NEWENVIRON, MudTelnetNewEnvironPrivate))
+
+typedef struct _MudTelnetNewEnviron MudTelnetNewEnviron;
+typedef struct _MudTelnetNewEnvironClass MudTelnetNewEnvironClass;
+typedef struct _MudTelnetNewEnvironPrivate MudTelnetNewEnvironPrivate;
+
+struct _MudTelnetNewEnvironClass
+{
+ GObjectClass parent_class;
+};
+
+struct _MudTelnetNewEnviron
+{
+ GObject parent_instance;
+
+ /*< private >*/
+ MudTelnetNewEnvironPrivate *priv;
+};
+
+GType mud_telnet_newenviron_get_type (void);
+
+G_END_DECLS
+
+#endif // MUD_TELNET_NEWENVIRON_H
+
Added: trunk/src/handlers/mud-telnet-ttype.c
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-ttype.c Tue Mar 17 18:08:13 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/handlers/mud-telnet-ttype.h
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-ttype.h Tue Mar 17 18:08:13 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
+
Added: trunk/src/handlers/mud-telnet-zmp.c
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-zmp.c Tue Mar 17 18:08:13 2009
@@ -0,0 +1,584 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-zmp.c
+ * Copyright (C) 2008-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 <gnet.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "gnome-mud.h"
+#include "mud-telnet.h"
+#include "mud-telnet-handler-interface.h"
+#include "mud-telnet-zmp.h"
+
+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(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);
+
+/* MudTelnetZmp class functions */
+static void
+mud_telnet_zmp_class_init (MudTelnetZmpClass *klass)
+{
+ 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");
+
+ 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_zmp_interface_init(MudTelnetHandlerInterface *iface)
+{
+ iface->Enable = mud_telnet_zmp_enable;
+ iface->Disable = mud_telnet_zmp_disable;
+ iface->HandleSubNeg = mud_telnet_zmp_handle_sub_neg;
+}
+
+static void
+mud_telnet_zmp_init (MudTelnetZmp *self)
+{
+ /* Get our private data */
+ self->priv = MUD_TELNET_ZMP_GET_PRIVATE(self);
+
+ /* Set the defaults */
+ self->priv->telnet = NULL;
+ self->priv->option = TELOPT_ZMP;
+ self->priv->enabled = FALSE;
+}
+
+static GObject *
+mud_telnet_zmp_constructor (GType gtype,
+ guint n_properties,
+ GObjectConstructParam *properties)
+{
+ 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;
+}
+
+static void
+mud_telnet_zmp_finalize (GObject *object)
+{
+ MudTelnetZmp *self;
+ GObjectClass *parent_class;
+
+ 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)
+ {
+ 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_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;
+ }
+}
+
+/* Interface Implementation */
+void
+mud_telnet_zmp_enable(MudTelnetHandler *handler)
+{
+ MudTelnetZmp *self;
+
+ 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");
+}
+
+void
+mud_telnet_zmp_disable(MudTelnetHandler *handler)
+{
+ MudTelnetZmp *self;
+
+ self = MUD_TELNET_ZMP(handler);
+
+ g_return_if_fail(MUD_IS_TELNET_ZMP(self));
+
+ /* Cannot disable ZMP once enabled per specification */
+ return;
+
+}
+
+void
+mud_telnet_zmp_handle_sub_neg(MudTelnetHandler *handler,
+ guchar *buf,
+ guint len)
+{
+ guint i;
+ gint argc;
+ gchar **argv;
+ GString *args;
+ MudZMPFunction zmp_handler = NULL;
+ MudTelnetZmp *self = MUD_TELNET_ZMP(handler);
+
+ g_return_if_fail(MUD_IS_TELNET_ZMP(self));
+
+ /* Count Strings */
+ for(i = 0; i < len; ++i)
+ if(buf[i] == '\0')
+ ++argc;
+
+ argv = g_new0(gchar *, argc);
+ argc = 0;
+ args = g_string_new(NULL);
+
+ for(i = 0; i < len; ++i)
+ {
+ if(buf[i] == '\0')
+ {
+ argv[argc++] = g_string_free(args, FALSE);
+ args = g_string_new(NULL);
+ continue;
+ }
+
+ args = g_string_append_c(args, buf[i]);
+ }
+
+ g_string_free(args, TRUE);
+
+ g_log("Telnet", G_LOG_LEVEL_MESSAGE, "Received: ZMP Command: %s", argv[0]);
+ for(i = 1; i < argc; ++i)
+ g_log("Telnet", G_LOG_LEVEL_MESSAGE, "\t%s", argv[i]);
+
+ if(mud_zmp_has_command(self, argv[0]))
+ {
+ zmp_handler = mud_zmp_get_function(self, argv[0]);
+
+ if(zmp_handler)
+ zmp_handler(self, argc, argv);
+ else
+ g_warning("NULL ZMP functioned returned.");
+ }
+ else
+ g_warning("Server sent unsupported ZMP command. Bad server, bad.");
+
+ for(i = 0; i < argc; ++i)
+ g_free(argv[i]);
+
+ g_free(argv);
+}
+
+/* Private Methods */
+static void
+mud_zmp_send_command(MudTelnetZmp *self, guint32 count, ...)
+{
+ guchar byte;
+ guint32 i;
+ guint32 j;
+ guchar null = '\0';
+ va_list va;
+ 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:");
+
+ 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_ZMP;
+ gnet_conn_write(conn, (gchar *)&byte, 1);
+
+ for (i = 0; i < count; ++i)
+ {
+ arg = (gchar *)va_arg(va, gchar *);
+
+ g_log("Telnet", G_LOG_LEVEL_DEBUG, "\t%s", arg);
+
+ for(j = 0; j < strlen(arg); ++j)
+ {
+ byte = (guchar)arg[j];
+
+ gnet_conn_write(conn, (gchar *)&byte, 1);
+
+ if (byte == (guchar)TEL_IAC)
+ gnet_conn_write(conn, (gchar *)&byte, 1);
+ }
+
+ gnet_conn_write(conn, (gchar *)&null, 1);
+ }
+
+ va_end(va);
+
+ byte = (guchar)TEL_IAC;
+ gnet_conn_write(conn, (gchar *)&byte, 1);
+ byte = (guchar)TEL_SE;
+ gnet_conn_write(conn, (gchar *)&byte, 1);
+}
+
+static void
+mud_zmp_register_core_functions(MudTelnetZmp *self)
+{
+ g_return_if_fail(MUD_IS_TELNET_ZMP(self));
+
+ 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
+mud_zmp_destroy_key(gpointer k)
+{
+ gchar *key = (gchar *)k;
+
+ if(key)
+ g_free(key);
+}
+
+static void
+mud_zmp_destroy_command(gpointer c)
+{
+ MudZMPCommand *command = (MudZMPCommand *)c;
+
+ if(command)
+ {
+ if(command->name)
+ g_free(command->name);
+
+ 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(MudTelnetZmp *self, gint argc, gchar **argv)
+{
+ 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(MudTelnetZmp *self, gint argc, gchar **argv)
+{
+ time_t 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(self, 2, "zmp.time", time_buffer);
+}
+
+static void
+ZMP_check(MudTelnetZmp *self, gint argc, gchar **argv)
+{
+ gchar *item;
+
+ g_return_if_fail(MUD_IS_TELNET_ZMP(self));
+
+ if(argc < 2)
+ return; // Malformed ZMP_Check
+
+ item = argv[1];
+
+ if(item[strlen(item) - 1] == '.') // Check for package.
+ {
+ if(mud_zmp_has_package(self, item))
+ mud_zmp_send_command(self, 2, "zmp.support", item);
+ else
+ mud_zmp_send_command(self, 2, "zmp.no-support", item);
+ }
+ else // otherwise command
+ {
+ if(mud_zmp_has_command(self, item))
+ mud_zmp_send_command(self, 2, "zmp.support", item);
+ else
+ 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;
+}
+
Added: trunk/src/handlers/mud-telnet-zmp.h
==============================================================================
--- (empty file)
+++ trunk/src/handlers/mud-telnet-zmp.h Tue Mar 17 18:08:13 2009
@@ -0,0 +1,70 @@
+/* GNOME-Mud - A simple Mud Client
+ * mud-telnet-zmp.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_ZMP_H
+#define MUD_TELNET_ZMP_H
+
+G_BEGIN_DECLS
+
+#include <glib.h>
+
+#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
+{
+ gchar *package;
+ gchar *name;
+ MudZMPFunction execute;
+} MudZMPCommand;
+
+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-connection-view.c
==============================================================================
--- trunk/src/mud-connection-view.c (original)
+++ trunk/src/mud-connection-view.c Tue Mar 17 18:08:13 2009
@@ -39,9 +39,7 @@
#include "mud-parse-base.h"
#include "mud-telnet.h"
-#ifdef ENABLE_GST
-#include "mud-telnet-msp.h"
-#endif
+#include "handlers/mud-telnet-handlers.h"
struct _MudConnectionViewPrivate
{
Modified: trunk/src/mud-telnet.c
==============================================================================
--- trunk/src/mud-telnet.c (original)
+++ trunk/src/mud-telnet.c Tue Mar 17 18:08:13 2009
@@ -33,23 +33,7 @@
#include "mud-telnet.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"
-#include "mud-telnet-mssp.h"
-#include "mud-telnet-new-environ.h"
-
-#ifdef ENABLE_GST
-#include "mud-telnet-msp.h"
-#endif
-
-#ifdef ENABLE_MCCP
-#include "mud-telnet-mccp.h"
-#endif
+#include "handlers/mud-telnet-handlers.h"
struct _MudTelnetPrivate
{
Modified: trunk/src/mud-telnet.h
==============================================================================
--- trunk/src/mud-telnet.h (original)
+++ trunk/src/mud-telnet.h Tue Mar 17 18:08:13 2009
@@ -108,7 +108,7 @@
#include <gnet.h>
#include "mud-connection-view.h"
-#include "mud-telnet-handler-interface.h"
+#include "handlers/mud-telnet-handlers.h"
enum TelnetState
{
Added: trunk/src/zmp/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/src/zmp/Makefile.am Tue Mar 17 18:08:13 2009
@@ -0,0 +1,24 @@
+NULL =
+
+noinst_LTLIBRARIES = libzmpcommands.la
+
+libzmpcommands_la_SOURCES = \
+ zmp-subwindow.c \
+ zmp-subwindow.h \
+ $(NULL)
+
+libzmpcommands_la_CPPFLAGS = \
+ -I$(srcdir)/.. \
+ $(AM_CPPFLAGS)
+
+libzmpcommands_la_CFLAGS = \
+ $(GMUD_CFLAGS) \
+ $(MSP_CFLAGS)
+
+libzmpcommands_la_LDFLAGS =
+
+libzmpcommands_la_LIBADD = \
+ $(GMUD_LIBS) \
+ $(MSP_LIBS) \
+ $(Z_LIBS)
+
Added: trunk/src/zmp/zmp-subwindow.c
==============================================================================
Added: trunk/src/zmp/zmp-subwindow.h
==============================================================================
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]