gnome-mud r670 - trunk/src
- From: lharris svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-mud r670 - trunk/src
- Date: Wed, 25 Jun 2008 08:04:06 +0000 (UTC)
Author: lharris
Date: Wed Jun 25 08:04:06 2008
New Revision: 670
URL: http://svn.gnome.org/viewvc/gnome-mud?rev=670&view=rev
Log:
Added telnet option support, fixed locale rendering.
Added:
trunk/src/mud-telnet-handlers.c
trunk/src/mud-telnet-handlers.h
Modified:
trunk/src/Makefile.am
trunk/src/gnome-mud.c
trunk/src/mud-connection-view.c
trunk/src/mud-connection-view.h
trunk/src/mud-telnet.c
trunk/src/mud-telnet.h
trunk/src/mud-window.c
Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am (original)
+++ trunk/src/Makefile.am Wed Jun 25 08:04:06 2008
@@ -47,6 +47,8 @@
mud-regex.h \
mud-telnet.c \
mud-telnet.h \
+ mud-telnet-handlers.c \
+ mud-telnet-handlers.h \
mud-tray.c \
mud-tray.h \
mud-window.c \
Modified: trunk/src/gnome-mud.c
==============================================================================
--- trunk/src/gnome-mud.c (original)
+++ trunk/src/gnome-mud.c Wed Jun 25 08:04:06 2008
@@ -90,7 +90,7 @@
bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
textdomain(GETTEXT_PACKAGE);
#endif
-
+
/* Initialize the GConf library */
if (!gconf_init(argc, argv, &err))
{
Modified: trunk/src/mud-connection-view.c
==============================================================================
--- trunk/src/mud-connection-view.c (original)
+++ trunk/src/mud-connection-view.c Wed Jun 25 08:04:06 2008
@@ -237,6 +237,8 @@
void
mud_connection_view_add_text(MudConnectionView *view, gchar *message, enum MudConnectionColorType type)
{
+ vte_terminal_set_encoding(VTE_TERMINAL(view->priv->terminal), "ISO-8859-1");
+
switch (type)
{
case Sent:
@@ -260,7 +262,7 @@
mud_connection_view_feed_text(view, "\e[0m");
}
-
+
static void
mud_connection_view_init (MudConnectionView *connection_view)
{
@@ -278,6 +280,8 @@
box = gtk_hbox_new(FALSE, 0);
connection_view->priv->terminal = vte_terminal_new();
+ vte_terminal_set_encoding(VTE_TERMINAL(connection_view->priv->terminal), "ISO-8859-1");
+
gtk_box_pack_start(GTK_BOX(box), connection_view->priv->terminal, TRUE, TRUE, 0);
g_signal_connect(G_OBJECT(connection_view->priv->terminal),
"button_press_event",
@@ -381,7 +385,11 @@
GList *commands, *command;
gchar *text;
- g_queue_push_head(view->priv->history, (gpointer)g_strdup(data));
+ if(view->local_echo) // Prevent password from being cached.
+ g_queue_push_head(view->priv->history, (gpointer)g_strdup(data));
+ else
+ g_queue_push_head(view->priv->history, (gpointer)g_strdup(" "));
+
view->priv->current_history_index = 0;
commands = mud_profile_process_commands(view->priv->profile, data);
@@ -396,7 +404,7 @@
gnet_conn_write(view->connection, text, strlen(text));
- if (view->priv->profile->preferences->EchoText)
+ if (view->priv->profile->preferences->EchoText && view->local_echo)
mud_connection_view_add_text(view, text, Sent);
g_free(text);
}
@@ -450,8 +458,18 @@
static void
mud_connection_view_set_terminal_font(MudConnectionView *view)
{
- vte_terminal_set_font_from_string(VTE_TERMINAL(view->priv->terminal),
- view->priv->profile->preferences->FontName);
+ PangoFontDescription *desc = NULL;
+ char *name;
+
+ name = view->priv->profile->preferences->FontName;
+
+ if(name)
+ desc = pango_font_description_from_string(name);
+
+ if(!desc)
+ desc = pango_font_description_from_string("Monospace 10");
+
+ vte_terminal_set_font(VTE_TERMINAL(view->priv->terminal), desc);
}
static void
@@ -510,7 +528,7 @@
popup_menu_detach);
append_menuitem(view->priv->popup_menu,
- _("Close tab or window, whatever :)"),
+ _("Close"),
NULL,
view);
@@ -623,10 +641,14 @@
gnet_conn_ref(view->connection);
gnet_conn_set_watch_error(view->connection, TRUE);
+ view->naws_enabled = FALSE;
+
view->priv->telnet = mud_telnet_new(view, view->connection);
+
+ view->local_echo = TRUE;
mud_connection_view_set_profile(view, mud_profile_new(profile));
-
+
/* Let us resize the gnome-mud window */
vte_terminal_get_padding(VTE_TERMINAL(view->priv->terminal), &xpad, &ypad);
char_width = VTE_TERMINAL(view->priv->terminal)->char_width;
@@ -654,9 +676,15 @@
buf = g_strdup_printf(_("*** Making connection to %s, port %d.\n"),
view->priv->hostname, view->priv->port);
mud_connection_view_add_text(view, buf, System);
+ g_free(buf);
+ buf = NULL;
gnet_conn_connect(view->connection);
-
+
+ buf = g_strdup_printf("Encoding: %s\n", vte_terminal_get_encoding(VTE_TERMINAL(view->priv->terminal)));
+ mud_connection_view_add_text(view, buf, System);
+ g_free(buf);
+
return view;
}
@@ -791,7 +819,6 @@
if (view->priv->connect_hook) {
mud_connection_view_send (view, view->priv->connect_string);
- g_free(view->priv->connect_string);
view->priv->connect_hook = FALSE;
}
@@ -813,3 +840,31 @@
}
}
+void
+mud_connection_view_get_term_size(MudConnectionView *view, gint *w, gint *h)
+{
+ VteTerminal *term = VTE_TERMINAL(view->priv->terminal);
+ *w = term->column_count;
+ *h = term->row_count;
+}
+
+void
+mud_connection_view_set_naws(MudConnectionView *view, gint enabled)
+{
+ view->naws_enabled = enabled;
+}
+
+void
+mud_connection_view_send_naws(MudConnectionView *view)
+{
+ if(view && view->naws_enabled)
+ {
+ mud_telnet_send_naws(view->priv->telnet,
+ VTE_TERMINAL(view->priv->terminal)->column_count,
+ VTE_TERMINAL(view->priv->terminal)->row_count);
+
+ g_message("Sending NAWS %d/%d", (gint)VTE_TERMINAL(view->priv->terminal)->column_count
+ ,(gint)VTE_TERMINAL(view->priv->terminal)->row_count);
+ }
+}
+
Modified: trunk/src/mud-connection-view.h
==============================================================================
--- trunk/src/mud-connection-view.h (original)
+++ trunk/src/mud-connection-view.h Wed Jun 25 08:04:06 2008
@@ -25,6 +25,10 @@
MudConnectionViewPrivate *priv;
GConn *connection;
+
+ gint naws_enabled;
+
+ gint local_echo;
};
struct _MudConnectionViewClass
@@ -59,6 +63,9 @@
void mud_connection_view_add_text(MudConnectionView *view, gchar *message, enum MudConnectionColorType type);
gchar *mud_connection_view_get_history_item(MudConnectionView *view, enum
MudConnectionHistoryDirection direction);
+void mud_connection_view_get_term_size(MudConnectionView *view, gint *w, gint *h);
+void mud_connection_view_set_naws(MudConnectionView *view, gint enabled);
+void mud_connection_view_send_naws(MudConnectionView *view);
#include "mud-profile.h"
void mud_connection_view_set_profile(MudConnectionView *view, MudProfile *profile);
Added: trunk/src/mud-telnet-handlers.c
==============================================================================
--- (empty file)
+++ trunk/src/mud-telnet-handlers.c Wed Jun 25 08:04:06 2008
@@ -0,0 +1,133 @@
+/* GNOME-Mud - A simple Mud CLient
+ * Copyright (C) 1998-2006 Robin Ericsson <lobbin localhost nu>
+ *
+ * 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.
+ */
+
+/* Code originally from wxMUD. Converted to a GObject by Les Harris.
+ * wxMUD - an open source cross-platform MUD client.
+ * Copyright (C) 2003-2008 Mart Raudsepp and Gabriel Levin
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+#include <gnet.h>
+
+#include "gnome-mud.h"
+#include "mud-telnet.h"
+#include "mud-telnet-handlers.h"
+
+/* TTYPE */
+
+void
+MudHandler_TType_Enable(MudTelnet *telnet, MudTelnetHandler *handler)
+{
+ handler->enabled = TRUE;
+}
+
+void
+MudHandler_TType_Disable(MudTelnet *telnet, MudTelnetHandler *handler)
+{
+ handler->enabled = FALSE;
+}
+
+void
+MudHandler_TType_HandleSubNeg(MudTelnet *telnet, guchar *buf,
+ guint len, MudTelnetHandler *handler)
+{
+ if (len == 1 && buf[0] == TEL_TTYPE_SEND)
+ {
+ mud_telnet_send_sub_req(telnet, 11, (guchar)TELOPT_TTYPE,
+ (guchar)TEL_TTYPE_IS,
+ 'g','n','o','m','e','-','m','u','d');
+ }
+}
+
+/* NAWS */
+void
+MudHandler_NAWS_Enable(MudTelnet *telnet, MudTelnetHandler *handler)
+{
+ gint w, h;
+
+ mud_telnet_get_parent_size(telnet, &w, &h);
+ mud_telnet_set_parent_naws(telnet, TRUE);
+
+ handler->enabled = TRUE;
+
+ mud_telnet_send_naws(telnet, w, h);
+}
+
+void
+MudHandler_NAWS_Disable(MudTelnet *telnet, MudTelnetHandler *handler)
+{
+ handler->enabled = FALSE;
+ mud_telnet_set_parent_naws(telnet, FALSE);
+
+ g_message("Disabled NAWS.");
+}
+
+void
+MudHandler_NAWS_HandleSubNeg(MudTelnet *telnet, guchar *buf,
+ guint len, MudTelnetHandler *handler)
+{
+ return;
+}
+
+/* ECHO */
+void
+MudHandler_ECHO_Enable(MudTelnet *telnet, MudTelnetHandler *handler)
+{
+ mud_telnet_set_local_echo(telnet, FALSE);
+ g_message("Enabled Serverside ECHO");
+}
+
+void
+MudHandler_ECHO_Disable(MudTelnet *telnet, MudTelnetHandler *handler)
+{
+ mud_telnet_set_local_echo(telnet, TRUE);
+ g_message("Disabled Serverside ECHO.");
+}
+
+void
+MudHandler_ECHO_HandleSubNeg(MudTelnet *telnet, guchar *buf,
+ guint len, MudTelnetHandler *handler)
+{
+ return;
+}
+
+/* EOR */
+void
+MudHandler_EOR_Enable(MudTelnet *telnet, MudTelnetHandler *handler)
+{
+ telnet->eor_enabled = TRUE;
+ g_message("Enabled EOR");
+}
+
+void
+MudHandler_EOR_Disable(MudTelnet *telnet, MudTelnetHandler *handler)
+{
+ telnet->eor_enabled = FALSE;
+ g_message("Disabled EOR");
+}
+
+void
+MudHandler_EOR_HandleSubNeg(MudTelnet *telnet, guchar *buf,
+ guint len, MudTelnetHandler *handler)
+{
+ return;
+}
Added: trunk/src/mud-telnet-handlers.h
==============================================================================
--- (empty file)
+++ trunk/src/mud-telnet-handlers.h Wed Jun 25 08:04:06 2008
@@ -0,0 +1,54 @@
+/* GNOME-Mud - A simple Mud CLient
+ * Copyright (C) 1998-2006 Robin Ericsson <lobbin localhost nu>
+ *
+ * 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.
+ */
+
+/* Code originally from wxMUD. Converted to a GObject by Les Harris.
+ * wxMUD - an open source cross-platform MUD client.
+ * Copyright (C) 2003-2008 Mart Raudsepp and Gabriel Levin
+ */
+
+#ifndef MUD_TELNET_HANDLERS_H
+#define MUD_TELNET_HANDLERS_H
+
+#include "mud-telnet.h"
+
+/* TTYPE */
+void MudHandler_TType_Enable(MudTelnet *telnet, MudTelnetHandler *handler);
+void MudHandler_TType_Disable(MudTelnet *telnet, MudTelnetHandler *handler);
+void MudHandler_TType_HandleSubNeg(MudTelnet *telnet, guchar *buf,
+ guint len, MudTelnetHandler *handler);
+
+/* NAWS */
+void MudHandler_NAWS_Enable(MudTelnet *telnet, MudTelnetHandler *handler);
+void MudHandler_NAWS_Disable(MudTelnet *telnet, MudTelnetHandler *handler);
+void MudHandler_NAWS_HandleSubNeg(MudTelnet *telnet, guchar *buf,
+ guint len, MudTelnetHandler *handler);
+
+/* ECHO */
+void MudHandler_ECHO_Enable(MudTelnet *telnet, MudTelnetHandler *handler);
+void MudHandler_ECHO_Disable(MudTelnet *telnet, MudTelnetHandler *handler);
+void MudHandler_ECHO_HandleSubNeg(MudTelnet *telnet, guchar *buf,
+ guint len, MudTelnetHandler *handler);
+
+/* EOR */
+void MudHandler_EOR_Enable(MudTelnet *telnet, MudTelnetHandler *handler);
+void MudHandler_EOR_Disable(MudTelnet *telnet, MudTelnetHandler *handler);
+void MudHandler_EOR_HandleSubNeg(MudTelnet *telnet, guchar *buf,
+ guint len, MudTelnetHandler *handler);
+
+#endif // MUD_TELNET_HANDLERS_H
+
Modified: trunk/src/mud-telnet.c
==============================================================================
--- trunk/src/mud-telnet.c (original)
+++ trunk/src/mud-telnet.c Wed Jun 25 08:04:06 2008
@@ -32,6 +32,7 @@
#include "gnome-mud.h"
#include "mud-telnet.h"
+#include "mud-telnet-handlers.h"
#define TELNET_TRACE_MASK _("telnet")
@@ -55,6 +56,7 @@
static gint mud_telnet_get_telopt_queue(guchar *storage, const guint bitshift);
static void mud_telnet_set_telopt_state(guchar *storage,
const enum TelnetOptionState state, const guint bitshift);
+static gint mud_telnet_get_index_by_option(MudTelnet *telnet, guchar option_number);
static void mud_telnet_set_telopt_queue(guchar *storage,
gint bit_on, const guint bitshift);
static gint mud_telnet_handle_positive_nego(MudTelnet *telnet,
@@ -102,7 +104,6 @@
mud_telnet_init (MudTelnet *telnet)
{
telnet->priv = g_new0(MudTelnetPrivate, 1);
-
}
static void
@@ -139,56 +140,111 @@
telnet->parent = parent;
telnet->conn = connection;
- // FIXME
+ telnet->tel_state = TEL_STATE_TEXT;
memset(telnet->telopt_states, 0, sizeof(telnet->telopt_states));
-/* memset(m_handlers, 0, sizeof(m_handlers));
- */
+ memset(telnet->handlers, 0, sizeof(telnet->handlers));
+
+ mud_telnet_register_handlers(telnet);
+ telnet->eor_enabled = FALSE;
+
return telnet;
}
-gint
-mud_telnet_register_handler(MudTelnet *telnet, guint8 option_number, const gchar *classname)
+void
+mud_telnet_register_handlers(MudTelnet *telnet)
{
-
- // FIXME
- /*
- TeloptHandlersMap::const_iterator iter = telopt_handler_names.find(option_number);
- if (iter == telopt_handler_names.end())
- {
- // FIXME: Leaks?
- telopt_handler_names[option_number] = wxString(classname);
- //wxPrintf(wxT("class '%s' registered as handling option %u\n"), classname, option_number);
- return TRUE;
- }
- else
- // Already registered.
- // FIXME: Should we consider re-registering and handling properly the already existing
- // FIXME: handler instances in m_handlers[option_number]?
- return FALSE;
- */
-
- return FALSE;
+ gint i;
+
+ for(i = 0; i < TEL_HANDLERS_SIZE; ++i)
+ {
+ telnet->handlers[i].type = HANDLER_NONE;
+ telnet->handlers[i].enabled = FALSE;
+ telnet->handlers[i].instance = NULL;
+ telnet->handlers[i].enable = NULL;
+ telnet->handlers[i].disable = NULL;
+ telnet->handlers[i].handle_sub_neg = NULL;
+ }
+
+ /* TTYPE */
+ telnet->handlers[0].type = HANDLER_TTYPE;
+ telnet->handlers[0].option_number = (guchar)TELOPT_TTYPE;
+ telnet->handlers[0].enabled = TRUE;
+ telnet->handlers[0].enable = MudHandler_TType_Enable;
+ telnet->handlers[0].disable = MudHandler_TType_Disable;
+ telnet->handlers[0].handle_sub_neg = MudHandler_TType_HandleSubNeg;
+
+ /* NAWS */
+ telnet->handlers[1].type = HANDLER_NAWS;
+ telnet->handlers[1].option_number = (guchar)TELOPT_NAWS;
+ telnet->handlers[1].enabled = TRUE;
+ telnet->handlers[1].enable = MudHandler_NAWS_Enable;
+ telnet->handlers[1].disable = MudHandler_NAWS_Disable;
+ telnet->handlers[1].handle_sub_neg = MudHandler_NAWS_HandleSubNeg;
+
+ /* ECHO */
+ telnet->handlers[2].type = HANDLER_ECHO;
+ telnet->handlers[2].option_number = (guchar)TELOPT_ECHO;
+ telnet->handlers[2].enabled = TRUE;
+ telnet->handlers[2].enable = MudHandler_ECHO_Enable;
+ telnet->handlers[2].disable = MudHandler_ECHO_Disable;
+ telnet->handlers[2].handle_sub_neg = MudHandler_ECHO_HandleSubNeg;
+
+ /* EOR */
+ telnet->handlers[3].type = HANDLER_EOR;
+ telnet->handlers[3].option_number = (guchar)TELOPT_EOR;
+ telnet->handlers[3].enabled = TRUE;
+ telnet->handlers[3].enable = MudHandler_EOR_Enable;
+ telnet->handlers[3].disable = MudHandler_EOR_Disable;
+ telnet->handlers[3].handle_sub_neg = MudHandler_EOR_HandleSubNeg;
}
gint
mud_telnet_isenabled(MudTelnet *telnet, guint8 option_number, gint him)
{
- // FIXME!!
- /*TeloptHandlersMap::const_iterator iter = telopt_handler_names.find(option_number);
+ gint i;
+
+ for(i = 0; i < TEL_HANDLERS_SIZE; ++i)
+ if(telnet->handlers[i].type != HANDLER_NONE)
+ if(option_number == telnet->handlers[i].option_number)
+ return telnet->handlers[i].enabled;
+
+ return FALSE;
+}
- if (iter != telopt_handler_names.end() && (*iter).second)
- {
- if (!m_handlers[option_number])
- m_handlers[option_number] = (TelnetHandler*)wxCreateDynamicObject((*iter).second);
+void
+mud_telnet_get_parent_size(MudTelnet *telnet, gint *w, gint *h)
+{
+ mud_connection_view_get_term_size(telnet->parent, w, h);
+}
- return m_handlers[option_number]->IsEnabled();
- }
- else
- return FALSE;*/
-
- return FALSE;
+void
+mud_telnet_set_parent_naws(MudTelnet *telnet, gint enabled)
+{
+ mud_connection_view_set_naws(telnet->parent, enabled);
+}
+
+void
+mud_telnet_set_local_echo(MudTelnet *telnet, gint enabled)
+{
+ telnet->parent->local_echo = enabled;
+}
+
+void
+mud_telnet_send_naws(MudTelnet *telnet, gint width, gint height)
+{
+ guchar w1, h1, w0, h0;
+
+ w1 = (width >> 8) & 0xff;
+ w0 = width & 0xff;
+
+ h1 = (height >> 8) & 0xff;
+ h0 = height & 0xff;
+
+ mud_telnet_send_sub_req(telnet, 5, (guchar)TELOPT_NAWS, w1, w0, h1, h0);
+
+ g_message("Sending NAWS: %d %d %d %d", w1, w0, h1, h0);
}
MudTelnetBuffer
@@ -205,7 +261,6 @@
switch (telnet->tel_state)
{
case TEL_STATE_TEXT:
- g_message("Text state\n");
if (buf[i] == (guchar)TEL_IAC)
telnet->tel_state = TEL_STATE_IAC;
else
@@ -213,88 +268,103 @@
break;
case TEL_STATE_IAC:
- g_message("IAC\n");
+ g_message("IAC");
switch (buf[i])
{
case (guchar)TEL_IAC:
- g_message("\tIAC\n");
+ g_message("\tIAC");
processed[pos++] = buf[i];
telnet->tel_state = TEL_STATE_TEXT;
break;
case (guchar)TEL_DO:
- g_message("\tDO\n");
+ g_message("\tDO");
telnet->tel_state = TEL_STATE_DO;
break;
case (guchar)TEL_DONT:
- g_message("\tDONT\n");
+ g_message("\tDONT");
telnet->tel_state = TEL_STATE_DONT;
break;
case (guchar)TEL_WILL:
- g_message("\tWILL\n");
+ g_message("\tWILL");
telnet->tel_state = TEL_STATE_WILL;
break;
+
+ case (guchar)TEL_NOP:
+ g_message("\tNOP");
+ telnet->tel_state = TEL_STATE_TEXT;
+ break;
+
+ case (guchar)TEL_GA:
+ g_message("\tGA");
+ telnet->tel_state = TEL_STATE_TEXT;
+ break;
+
+ case (guchar)TEL_EOR_BYTE:
+ g_message("\tEOR");
+ telnet->tel_state = TEL_STATE_TEXT;
+ break;
case (guchar)TEL_WONT:
- g_message("\tWONT\n");
+ g_message("\tWONT");
telnet->tel_state = TEL_STATE_WONT;
break;
case (guchar)TEL_SB:
- g_message("Receiving subrequest\n");
+ g_message("Receiving subrequest");
telnet->tel_state = TEL_STATE_SB;
telnet->subreq_pos = 0;
break;
default:
- g_warning("Illegal IAC command %d received\n", buf[i]);
+ g_warning("Illegal IAC command %d received", buf[i]);
telnet->tel_state = TEL_STATE_TEXT;
break;
}
break;
case TEL_STATE_DO:
- g_message("STATE_DO\n");
+ g_message("STATE_DO");
mud_telnet_handle_positive_nego(telnet, buf[i],
(guchar)TEL_WILL, (guchar)TEL_WONT, FALSE);
telnet->tel_state = TEL_STATE_TEXT;
case TEL_STATE_WILL:
- g_message("STATE_WILL\n");
+ g_message("STATE_WILL");
mud_telnet_handle_positive_nego(telnet, buf[i],
(guchar)TEL_DO, (guchar)TEL_DONT, TRUE);
telnet->tel_state = TEL_STATE_TEXT;
break;
case TEL_STATE_DONT:
- g_message("STATE_DONT\n");
+ g_message("STATE_DONT");
mud_telnet_handle_negative_nego(telnet,
buf[i], (guchar)TEL_WILL, (guchar)TEL_WONT, FALSE);
telnet->tel_state = TEL_STATE_TEXT;
break;
case TEL_STATE_WONT:
- g_message("STATE_WONT\n");
+ g_message("STATE_WONT: Won't do telopt: %d", buf[i]);
mud_telnet_handle_negative_nego(telnet,
buf[i], (guchar)TEL_DO, (guchar)TEL_DONT, TRUE);
telnet->tel_state = TEL_STATE_TEXT;
break;
case TEL_STATE_SB:
- g_message("STATE_SB\n");
+ g_message("STATE_SB");
if (buf[i] == (guchar)TEL_IAC)
telnet->tel_state = TEL_STATE_SB_IAC;
else
{
if (telnet->subreq_pos == 0)
- g_message("Subrequest for option %d\n", buf[i]);
+ g_message("Subrequest for option %d", buf[i]);
// FIXME: Handle overflow
if (telnet->subreq_pos >= TEL_SUBREQ_BUFFER_SIZE)
{
- g_warning("Subrequest buffer full. Oddities in output will happen. Sorry.\n");
+ g_warning("Subrequest buffer full. Oddities in output will happen. Sorry.");
telnet->subreq_pos = 0;
telnet->tel_state = TEL_STATE_TEXT;
}
@@ -304,12 +374,12 @@
break;
case TEL_STATE_SB_IAC:
- g_message("STATE_SB_IAC\n");
+ g_message("STATE_SB_IAC");
if (buf[i] == (guchar)TEL_IAC)
{
if (telnet->subreq_pos >= TEL_SUBREQ_BUFFER_SIZE)
{
- g_warning("Subrequest buffer full. Oddities in output will happen. Sorry.\n");
+ g_warning("Subrequest buffer full. Oddities in output will happen. Sorry.");
telnet->subreq_pos = 0;
telnet->tel_state = TEL_STATE_TEXT;
}
@@ -320,17 +390,17 @@
}
else if (buf[i] == (guchar)TEL_SE)
{
- g_message("STATE_TEL_SE\n");
- g_message("Subrequest for option %d succesfully received with length %d\n",
+ g_message("STATE_TEL_SE");
+ g_message("Subrequest for option %d succesfully received with length %d",
telnet->subreq_buffer[0], telnet->subreq_pos-1);
- g_message("Subreq buffer content: %d %d %d %d\n",
+ g_message("Subreq buffer content: %d %d %d %d",
telnet->subreq_buffer[0], telnet->subreq_buffer[1],
telnet->subreq_buffer[2], telnet->subreq_buffer[3]);
mud_telnet_on_handle_subnego(telnet);
telnet->tel_state = TEL_STATE_TEXT;
} else {
- g_warning("Erronous byte %d after an IAC inside a subrequest\n", buf[i]);
+ g_warning("Erronous byte %d after an IAC inside a subrequest", buf[i]);
telnet->subreq_pos = 0;
telnet->tel_state = TEL_STATE_TEXT;
}
@@ -443,6 +513,26 @@
gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
}
+void
+mud_telnet_send_raw(MudTelnet *telnet, guint32 count, ...)
+{
+ guchar byte;
+ guint32 i;
+ va_list va;
+ va_start(va, count);
+
+ for (i = 0; i < count; ++i)
+ {
+ byte = (guchar)va_arg(va, gint);
+ gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
+
+ if (byte == (guchar)TEL_IAC)
+ gnet_conn_write(telnet->conn, (gchar *)&byte, 1);
+ }
+
+ va_end(va);
+}
+
/*** Private Methods ***/
static void
mud_telnet_send_iac(MudTelnet *telnet, guchar ch1, guchar ch2)
@@ -452,41 +542,55 @@
buf[1] = ch1;
buf[2] = ch2;
- // Replace with gnet equivalent
gnet_conn_write(telnet->conn, (gchar *)buf, 3);
}
static void
mud_telnet_on_handle_subnego(MudTelnet *telnet)
{
+ int index;
+
if (telnet->subreq_pos < 1)
return;
-
- /*if (mud_telnet_is_enabled(telnet, subreq_buffer[0], FALSE))
- m_handlers[subreq_buffer[0]]->HandleSubNego(this, subreq_buffer + 1, subreq_pos - 1);
- */
+
+ if((index = mud_telnet_get_index_by_option(telnet, telnet->subreq_buffer[0])) == -1)
+ {
+ g_warning("Invalid Telnet Option passed: %d", telnet->subreq_buffer[0]);
+ return;
+ }
+
+ if (mud_telnet_isenabled(telnet, telnet->subreq_buffer[0], FALSE))
+ telnet->handlers[index].handle_sub_neg(telnet, telnet->subreq_buffer + 1,
+ telnet->subreq_pos - 1, &telnet->handlers[index]);
}
static void
mud_telnet_on_enable_opt(MudTelnet *telnet, const guchar opt_no, gint him)
{
- if (telnet->subreq_pos < 1)
- return;
-
- /*if (mud_telnet_is_enabled(telnet, subreq_buffer[0], FALSE))
- m_handlers[subreq_buffer[0]]->HandleSubNego(this, subreq_buffer + 1, subreq_pos - 1);
- */
+ int index;
+
+ g_message("Trying to enable option %d", opt_no);
+ if((index = mud_telnet_get_index_by_option(telnet, opt_no)) == -1)
+ {
+ g_warning("Invalid Telnet Option passed: %d", opt_no);
+ return;
+ }
+
+ telnet->handlers[index].enable(telnet, &telnet->handlers[index]);
}
static void
mud_telnet_on_disable_opt(MudTelnet *telnet, const guchar opt_no, gint him)
{
- if (telnet->subreq_pos < 1)
- return;
+ int index;
+
+ if((index = mud_telnet_get_index_by_option(telnet, opt_no)) == -1)
+ {
+ g_warning("Invalid Telnet Option passed: %d", opt_no);
+ return;
+ }
- /*if (mud_telnet_is_enabled(telnet, subreq_buffer[0], FALSE))
- m_handlers[subreq_buffer[0]]->HandleSubNego(this, subreq_buffer + 1, subreq_pos - 1);
- */
+ telnet->handlers[index].disable(telnet, &telnet->handlers[index]);
}
static guchar
@@ -525,7 +629,7 @@
{
const guint bitshift = him ? 4 : 0;
guchar * opt = &(telnet->telopt_states[opt_no]);
-
+
switch (mud_telnet_get_telopt_state(opt, bitshift))
{
case TELOPT_STATE_NO:
@@ -540,7 +644,7 @@
mud_telnet_on_enable_opt(telnet, opt_no, him);
return TRUE;
} else {
- // printf("Server, you DONT do %d\n", opt_no);
+ //printf("Server, you DONT do %d\n", opt_no);
mud_telnet_send_iac(telnet, negative, opt_no);
return FALSE;
}
@@ -568,6 +672,7 @@
if (mud_telnet_get_telopt_queue(opt, bitshift) == TELOPT_STATE_QUEUE_EMPTY)
{
mud_telnet_set_telopt_state(opt, TELOPT_STATE_YES, bitshift);
+ mud_telnet_send_iac(telnet, affirmative, opt_no);
mud_telnet_on_enable_opt(telnet, opt_no, him);
return TRUE;
} else { // The opposite is queued
@@ -592,7 +697,7 @@
{
const guint bitshift = him ? 4 : 0;
guchar * opt = &(telnet->telopt_states[opt_no]);
-
+
switch (mud_telnet_get_telopt_state(opt, bitshift))
{
case TELOPT_STATE_NO:
@@ -601,7 +706,7 @@
case TELOPT_STATE_YES:
mud_telnet_set_telopt_state(opt, TELOPT_STATE_NO, bitshift);
- //printf("Ok, server, I ACK that you DONT do %d\n", opt_no);
+ //printf("Ok, server, I ACK that you DONT do %d\n", opt_no);
mud_telnet_send_iac(telnet, negative, opt_no);
mud_telnet_on_disable_opt(telnet, opt_no, him);
return TRUE;
@@ -615,7 +720,7 @@
mud_telnet_set_telopt_state(opt, TELOPT_STATE_WANTYES, bitshift);
mud_telnet_set_telopt_queue(opt, TELOPT_STATE_QUEUE_EMPTY, bitshift);
//printf("Ok, server, you are making me angry. DO %d", opt_no);
- mud_telnet_send_iac(telnet, affirmative, opt_no);
+ mud_telnet_send_iac(telnet, affirmative, opt_no);
mud_telnet_on_enable_opt(telnet, opt_no, him); // FIXME: Is this correct?
return TRUE;
}
@@ -636,3 +741,16 @@
}
}
+static gint
+mud_telnet_get_index_by_option(MudTelnet *telnet, guchar option_number)
+{
+ gint i;
+
+ for(i = 0; i < TEL_HANDLERS_SIZE; i++)
+ if(telnet->handlers[i].type != HANDLER_NONE)
+ if(telnet->handlers[i].option_number == option_number)
+ return i;
+
+ return -1;
+}
+
Modified: trunk/src/mud-telnet.h
==============================================================================
--- trunk/src/mud-telnet.h (original)
+++ trunk/src/mud-telnet.h Wed Jun 25 08:04:06 2008
@@ -34,7 +34,7 @@
#define MUD_TELNET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MUD_TYPE_TELNET, MudTelnetClass))
#define TEL_SE 240 // End of subnegotiation parameters
-//#define TEL_NOP 241 // No operation - not yet supported
+#define TEL_NOP 241 // No operation
#define TEL_GA 249 // Go ahead
#define TEL_SB 250 // Indicates that what follows is subnegotiation of the indicated option
#define TEL_WILL 251 // I will use option
@@ -49,6 +49,7 @@
# define TEL_TTYPE_IS 0 // Terminal type IS ...
# define TEL_TTYPE_SEND 1 // SEND me terminal type
#define TELOPT_EOR 25 // End of record - RFC 885
+# define TEL_EOR_BYTE 239 // End of record byte.
#define TELOPT_NAWS 31 // Window size - RFC 1073
#define TELOPT_CHARSET 42 // Charset - RFC 2066
#define TELOPT_MCCP 85 // MCCP
@@ -61,6 +62,7 @@
// FIXME: What size should we use?
#define TEL_SUBREQ_BUFFER_SIZE 256
+#define TEL_HANDLERS_SIZE 256
#define TELOPT_STATE_QUEUE_EMPTY FALSE
#define TELOPT_STATE_QUEUE_OPPOSITE TRUE
@@ -68,6 +70,12 @@
typedef struct _MudTelnetClass MudTelnetClass;
typedef struct _MudTelnetPrivate MudTelnetPrivate;
typedef struct _MudTelnetBuffer MudTelnetBuffer;
+typedef struct _MudTelnetHandler MudTelnetHandler;
+
+typedef void(*MudTelnetOnEnableFunc)(MudTelnet *telnet, MudTelnetHandler *handler);
+typedef void(*MudTelnetOnDisableFunc)(MudTelnet *telnet, MudTelnetHandler *handler);
+typedef void(*MudTelnetOnHandleSubNegFunc)(MudTelnet *telnet,
+ guchar *buf, guint len, MudTelnetHandler *handler);
enum TelnetState
{
@@ -89,6 +97,15 @@
TELOPT_STATE_YES = 3, // bits 11
};
+enum TelnetHandlerType
+{
+ HANDLER_NONE,
+ HANDLER_TTYPE,
+ HANDLER_NAWS,
+ HANDLER_ECHO,
+ HANDLER_EOR
+};
+
struct _MudTelnetClass
{
GObjectClass parent_class;
@@ -100,6 +117,20 @@
size_t len;
};
+struct _MudTelnetHandler
+{
+ enum TelnetHandlerType type;
+ guchar option_number;
+
+ gint enabled;
+
+ MudTelnet *instance;
+
+ MudTelnetOnEnableFunc enable;
+ MudTelnetOnDisableFunc disable;
+ MudTelnetOnHandleSubNegFunc handle_sub_neg;
+};
+
#include <gnet.h>
#include <mud-connection-view.h>
struct _MudTelnet
@@ -113,25 +144,27 @@
guint32 subreq_pos;
guchar telopt_states[256];
+ gint eor_enabled;
GConn *conn;
MudConnectionView *parent;
- /**
- Pointers to option handler instances. NULL if none is created yet.
- */
- //TelnetHandler * m_handlers[256];
+ MudTelnetHandler handlers[TEL_HANDLERS_SIZE];
};
GType mud_telnet_get_type (void) G_GNUC_CONST;
MudTelnet *mud_telnet_new(MudConnectionView *parent, GConn *connection);
-gint mud_telnet_register_handler(MudTelnet *telnet,
- guint8 option_number, const gchar *classname);
+void mud_telnet_register_handlers(MudTelnet *telnet);
gint mud_telnet_isenabled(MudTelnet *telnet, guint8 option_number, gint him);
MudTelnetBuffer mud_telnet_process(MudTelnet *telnet, guchar * buf, guint32 count);
void mud_telnet_send_sub_req(MudTelnet *telnet, guint32 count, ...);
+void mud_telnet_get_parent_size(MudTelnet *telnet, gint *w, gint *h);
+void mud_telnet_send_raw(MudTelnet *telnet, guint32 count, ...);
+void mud_telnet_set_parent_naws(MudTelnet *telnet, gint enabled);
+void mud_telnet_send_naws(MudTelnet *telnet, gint w, gint h);
+void mud_telnet_set_local_echo(MudTelnet *telnet, gint enabled);
G_END_DECLS
Modified: trunk/src/mud-window.c
==============================================================================
--- trunk/src/mud-window.c (original)
+++ trunk/src/mud-window.c Wed Jun 25 08:04:06 2008
@@ -453,6 +453,9 @@
gtk_widget_grab_focus(window->priv->textview);
+ // FIXME: Should send naws to all views.
+ mud_connection_view_send_naws(MUD_CONNECTION_VIEW(window->priv->current_view));
+
return FALSE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]