gnome-mud r675 - in trunk: . src ui
- From: lharris svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-mud r675 - in trunk: . src ui
- Date: Mon, 30 Jun 2008 09:54:58 +0000 (UTC)
Author: lharris
Date: Mon Jun 30 09:54:58 2008
New Revision: 675
URL: http://svn.gnome.org/viewvc/gnome-mud?rev=675&view=rev
Log:
Merged msp into the master branch to implement MSP
Added:
trunk/src/mud-telnet-msp.c
trunk/src/mud-telnet-msp.h
Modified:
trunk/ChangeLog
trunk/configure.ac
trunk/gnome-mud.schemas.in
trunk/src/Makefile.am
trunk/src/gconf-helper.c
trunk/src/gnome-mud.c
trunk/src/mud-connection-view.c
trunk/src/mud-connection-view.h
trunk/src/mud-preferences-window.c
trunk/src/mud-profile.c
trunk/src/mud-profile.h
trunk/src/mud-telnet-handlers.c
trunk/src/mud-telnet-handlers.h
trunk/src/mud-telnet.c
trunk/src/mud-telnet.h
trunk/src/mud-window.c
trunk/src/utils.c
trunk/ui/main.glade
trunk/ui/prefs.glade
Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac (original)
+++ trunk/configure.ac Mon Jun 30 09:54:58 2008
@@ -57,8 +57,9 @@
VTE_REQUIRED=0.11.00
PCRE_REQUIRED=6.0.0
GCONF_REQUIRED=0.20
+GSTREAMER_REQUIRED=0.10
-PKG_CHECK_MODULES(GMUD, gtk+-2.0 >= $GTK_REQUIRED vte >= $VTE_REQUIRED libglade-2.0 >= $LIBGLADE_REQUIRED libpcre >= $PCRE_REQUIRED gmodule-2.0 >= $GMODULE_REQUIRED gnet-2.0 >= $LIBGNET_REQUIRED gconf-2.0 >= $GCONF_REQUIRED)
+PKG_CHECK_MODULES(GMUD, gtk+-2.0 >= $GTK_REQUIRED vte >= $VTE_REQUIRED libglade-2.0 >= $LIBGLADE_REQUIRED libpcre >= $PCRE_REQUIRED gmodule-2.0 >= $GMODULE_REQUIRED gnet-2.0 >= $LIBGNET_REQUIRED gconf-2.0 >= $GCONF_REQUIRED gstreamer-0.10 >= $GSTREAMER_REQUIRED)
AC_SUBST(GMUD_CFLAGS)
AC_SUBST(GMUD_LIBS)
Modified: trunk/gnome-mud.schemas.in
==============================================================================
--- trunk/gnome-mud.schemas.in (original)
+++ trunk/gnome-mud.schemas.in Mon Jun 30 09:54:58 2008
@@ -185,6 +185,20 @@
</schema>
<schema>
+ <key>/schemas/apps/gnome-mud/functionality/remote_download</key>
+ <applyto>/apps/gnome-mud/functionality/remote_download</applyto>
+ <owner>gnome-mud</owner>
+ <type>bool</type>
+ <default>true</default>
+ <locale name="C">
+ <short>Remote Download</short>
+ <long>
+ Enable sound file downloading on MSP enabled MUDs
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
<key>/schemas/apps/gnome-mud/functionality/commdev</key>
<applyto>/apps/gnome-mud/functionality/commdev</applyto>
<owner>gnome-mud</owner>
Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am (original)
+++ trunk/src/Makefile.am Mon Jun 30 09:54:58 2008
@@ -49,6 +49,8 @@
mud-telnet.h \
mud-telnet-handlers.c \
mud-telnet-handlers.h \
+ mud-telnet-msp.c \
+ mud-telnet-msp.h \
mud-telnet-zmp.c \
mud-telnet-zmp.h \
mud-tray.c \
Modified: trunk/src/gconf-helper.c
==============================================================================
--- trunk/src/gconf-helper.c (original)
+++ trunk/src/gconf-helper.c Mon Jun 30 09:54:58 2008
@@ -126,6 +126,7 @@
GCONF_GET_BOOLEAN(use_proxy, functionality, UseProxy);
GCONF_GET_BOOLEAN(remote_encoding, functionality, UseRemoteEncoding);
GCONF_GET_STRING(proxy_hostname, functionality, ProxyHostname);
+ GCONF_GET_BOOLEAN(remote_download, functionality, UseRemoteDownload);
/* palette */
g_snprintf(keyname, 2048, "/apps/gnome-mud/%sui/palette", extra_path);
Modified: trunk/src/gnome-mud.c
==============================================================================
--- trunk/src/gnome-mud.c (original)
+++ trunk/src/gnome-mud.c Mon Jun 30 09:54:58 2008
@@ -28,6 +28,7 @@
#include <stdio.h>
#include <sys/stat.h>
#include <gnet.h>
+#include <gst/gst.h>
#ifdef USE_PYTHON
//#include <Python.h>
@@ -102,6 +103,9 @@
/* Initialize the Gnet library */
gnet_init();
+ /* Initialize GStreamer */
+ gst_init(&argc, &argv);
+
gtk_init(&argc, &argv);
/* Start a GConf client */
@@ -135,6 +139,10 @@
if(!g_file_test(buf, G_FILE_TEST_IS_DIR))
mkdir(buf, 0777 );
+ g_snprintf(buf, 500, "%s/.gnome-mud/audio/", g_get_home_dir());
+ if(!g_file_test(buf, G_FILE_TEST_IS_DIR))
+ mkdir(buf, 0777 );
+
gtk_about_dialog_set_url_hook(utils_activate_url, NULL, NULL);
gtk_main();
gconf_client_suggest_sync(gconf_client, &err);
Modified: trunk/src/mud-connection-view.c
==============================================================================
--- trunk/src/mud-connection-view.c (original)
+++ trunk/src/mud-connection-view.c Mon Jun 30 09:54:58 2008
@@ -39,6 +39,7 @@
#include "mud-parse-base.h"
#include "mud-telnet.h"
#include "mud-telnet-zmp.h"
+#include "mud-telnet-msp.h"
/* Hack, will refactor with plugin rewrite -lh */
extern gboolean PluginGag;
@@ -54,6 +55,9 @@
GtkWidget *scrollbar;
GtkWidget *box;
GtkWidget *popup_menu;
+ GtkWidget *progressbar;
+ GtkWidget *dl_label;
+ GtkWidget *dl_button;
MudProfile *profile;
MudLog *log;
@@ -73,6 +77,14 @@
MudTelnet *telnet;
gchar *hostname;
guint port;
+
+ gchar *mud_name;
+
+ GQueue *download_queue;
+ GConnHttp *dl_conn;
+ gboolean downloading;
+
+ GString *processed;
};
static void mud_connection_view_init (MudConnectionView *connection_view);
@@ -88,6 +100,8 @@
static void mud_connection_view_popup (MudConnectionView *view, GdkEventButton *event);
static void mud_connection_view_reread_profile (MudConnectionView *view);
static void mud_connection_view_network_event_cb(GConn *conn, GConnEvent *event, gpointer data);
+static void mud_connection_view_http_cb(GConnHttp *conn, GConnHttpEvent *event, gpointer data);
+static void mud_connection_view_cancel_dl_cb(GtkWidget *widget, MudConnectionView *view);
GType
mud_connection_view_get_type (void)
@@ -305,22 +319,46 @@
mud_connection_view_init (MudConnectionView *connection_view)
{
GtkWidget *box;
+ GtkWidget *dl_vbox;
+ GtkWidget *dl_hbox;
+ GtkWidget *term_box;
connection_view->priv = g_new0(MudConnectionViewPrivate, 1);
connection_view->priv->history = g_queue_new();
connection_view->priv->current_history_index = 0;
+ connection_view->priv->download_queue = g_queue_new();
+ connection_view->priv->dl_conn = NULL;
+ connection_view->priv->processed = NULL;
+
connection_view->priv->parse = mud_parse_base_new(connection_view);
connection_view->priv->connect_hook = FALSE;
- box = gtk_hbox_new(FALSE, 0);
+ box = gtk_vbox_new(FALSE, 0);
+ dl_vbox = gtk_vbox_new(FALSE, 0);
+ dl_hbox = gtk_hbox_new(FALSE, 0);
+ term_box = gtk_hbox_new(FALSE, 0);
+
+ connection_view->priv->dl_label = gtk_label_new("Downloading...");
+ connection_view->priv->progressbar = gtk_progress_bar_new();
+ gtk_progress_bar_set_pulse_step (GTK_PROGRESS_BAR(connection_view->priv->progressbar), 0.1);
+ connection_view->priv->dl_button = gtk_button_new_from_stock("gtk-cancel");
+ connection_view->priv->downloading = FALSE;
+
+ gtk_box_pack_start(GTK_BOX(dl_vbox), connection_view->priv->dl_label, FALSE, FALSE, 0);
+
+ gtk_box_pack_start(GTK_BOX(dl_hbox), connection_view->priv->progressbar, TRUE, TRUE, 0);
+
+ gtk_box_pack_end(GTK_BOX(dl_hbox), connection_view->priv->dl_button, FALSE, FALSE, 0);
+
+ gtk_box_pack_end(GTK_BOX(dl_vbox), dl_hbox, TRUE, TRUE, 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);
+ gtk_box_pack_start(GTK_BOX(term_box), connection_view->priv->terminal, TRUE, TRUE, 0);
g_signal_connect(G_OBJECT(connection_view->priv->terminal),
"button_press_event",
G_CALLBACK(mud_connection_view_button_press_event),
@@ -328,11 +366,22 @@
g_object_set_data(G_OBJECT(connection_view->priv->terminal),
"connection-view", connection_view);
+ g_signal_connect(connection_view->priv->dl_button, "clicked",
+ G_CALLBACK(mud_connection_view_cancel_dl_cb), connection_view);
+
connection_view->priv->scrollbar = gtk_vscrollbar_new(NULL);
gtk_range_set_adjustment(GTK_RANGE(connection_view->priv->scrollbar), VTE_TERMINAL(connection_view->priv->terminal)->adjustment);
- gtk_box_pack_start(GTK_BOX(box), connection_view->priv->scrollbar, FALSE, FALSE, 0);
+ gtk_box_pack_end(GTK_BOX(term_box), connection_view->priv->scrollbar, FALSE, FALSE, 0);
+
+ gtk_box_pack_start(GTK_BOX(box), dl_vbox, FALSE, FALSE, 0);
+ gtk_box_pack_end(GTK_BOX(box), term_box, TRUE, TRUE, 0);
gtk_widget_show_all(box);
+
+ gtk_widget_hide(connection_view->priv->progressbar);
+ gtk_widget_hide(connection_view->priv->dl_label);
+ gtk_widget_hide(connection_view->priv->dl_button);
+
g_object_set_data(G_OBJECT(box), "connection-view", connection_view);
connection_view->priv->box = box;
@@ -364,16 +413,22 @@
MudConnectionView *connection_view;
GObjectClass *parent_class;
gchar *history_item;
+ MudMSPDownloadItem *item;
connection_view = MUD_CONNECTION_VIEW(object);
while((history_item = (gchar *)g_queue_pop_head(connection_view->priv->history)) != NULL)
- if(history_item != NULL)
- g_free(history_item);
+ g_free(history_item);
if(connection_view->priv->history)
g_queue_free(connection_view->priv->history);
+ while((item = (MudMSPDownloadItem *)g_queue_pop_head(connection_view->priv->download_queue)) != NULL)
+ mud_telnet_msp_download_item_free(item);
+
+ if(connection_view->priv->download_queue)
+ g_queue_free(connection_view->priv->download_queue);
+
mud_zmp_finalize(connection_view->priv->telnet);
gnet_conn_disconnect(connection_view->connection);
@@ -396,9 +451,29 @@
void
mud_connection_view_disconnect(MudConnectionView *view)
{
+ MudMSPDownloadItem *item;
+
g_assert(view != NULL);
+ while((item = (MudMSPDownloadItem *)g_queue_pop_head(view->priv->download_queue)) != NULL)
+ mud_telnet_msp_download_item_free(item);
+
+ if(view->priv->download_queue)
+ g_queue_free(view->priv->download_queue);
+
+ view->priv->download_queue = NULL;
+
+ if(view->priv->processed)
+ g_string_free(view->priv->processed, TRUE);
+
+ view->priv->processed = NULL;
+
+ mud_zmp_finalize(view->priv->telnet);
+
gnet_conn_disconnect(view->connection);
+
+ g_object_unref(view->priv->telnet);
+
mud_connection_view_add_text(view, _("*** Connection closed.\n"), System);
}
@@ -406,11 +481,42 @@
mud_connection_view_reconnect(MudConnectionView *view)
{
gchar *buf;
+ MudMSPDownloadItem *item;
g_assert(view != NULL);
- gnet_conn_disconnect(view->connection);
- mud_connection_view_add_text(view, _("*** Connection closed.\n"), System);
+
+ if(gnet_conn_is_connected(view->connection))
+ {
+ while((item = (MudMSPDownloadItem *)g_queue_pop_head(view->priv->download_queue)) != NULL)
+ mud_telnet_msp_download_item_free(item);
+
+ if(view->priv->download_queue)
+ g_queue_free(view->priv->download_queue);
+
+ view->priv->download_queue = NULL;
+
+ if(view->priv->processed)
+ g_string_free(view->priv->processed, TRUE);
+
+ view->priv->processed = NULL;
+
+ mud_zmp_finalize(view->priv->telnet);
+
+ gnet_conn_disconnect(view->connection);
+
+ g_object_unref(view->priv->telnet);
+
+ mud_connection_view_add_text(view, _("*** Connection closed.\n"), System);
+
+ view->priv->download_queue = g_queue_new();
+
+ view->naws_enabled = FALSE;
+
+ view->priv->telnet = mud_telnet_new(view, view->connection, view->priv->mud_name);
+
+ view->local_echo = TRUE;
+ }
buf = g_strdup_printf(_("*** Making connection to %s, port %d.\n"),
view->priv->hostname, view->priv->port);
@@ -687,7 +793,7 @@
view->naws_enabled = FALSE;
- view->priv->telnet = mud_telnet_new(view, view->connection);
+ view->priv->telnet = mud_telnet_new(view, view->connection, name);
view->local_echo = TRUE;
@@ -824,23 +930,21 @@
}
static void
-mud_connection_view_network_event_cb(GConn *conn, GConnEvent *event, gpointer pview)
+ mud_connection_view_network_event_cb(GConn *conn, GConnEvent *event, gpointer pview)
{
gint gag;
gint pluggag;
- gint i;
- MudTelnetBuffer buffer;
- GString *string;
gchar *buf;
gboolean temp;
MudConnectionView *view = MUD_CONNECTION_VIEW(pview);
+ gint length;
g_assert(view != NULL);
switch(event->type)
{
case GNET_CONN_ERROR:
- mud_connection_view_add_text(view, _("*** Could not connect."), Error);
+ mud_connection_view_add_text(view, _("*** Could not connect.\n"), Error);
break;
case GNET_CONN_CONNECT:
@@ -862,43 +966,48 @@
mud_tray_update_icon(view->priv->tray, online);
}
- buffer = mud_telnet_process(view->priv->telnet, (guchar *)event->buffer, event->length);
+ view->priv->processed = mud_telnet_process(view->priv->telnet,
+ (guchar *)event->buffer, event->length, &length);
- if(buffer.len != 0)
+ if(view->priv->processed != NULL)
{
- string = g_string_new(NULL);
- for(i = 0; i < buffer.len; i++)
- g_string_append_c(string, buffer.buffer[i]);
-
- buf = string->str;
-
- temp = view->local_echo;
- view->local_echo = FALSE;
- gag = mud_parse_base_do_triggers(view->priv->parse,
- buf);
- view->local_echo = temp;
-
- mud_window_handle_plugins(view->priv->window, view->priv->id,
- buf, buffer.len, 1);
-
- pluggag = PluginGag;
- PluginGag = FALSE;
-
- if(!gag && !pluggag)
- {
-
- vte_terminal_feed(VTE_TERMINAL(view->priv->terminal),
- buf, buffer.len);
- mud_log_write_hook(view->priv->log, buf, buffer.len);
- }
+ if(view->priv->telnet->msp_parser.enabled)
+ {
+ view->priv->processed = mud_telnet_msp_parse(
+ view->priv->telnet, view->priv->processed, &length);
+ }
+
+ if(view->priv->processed != NULL)
+ {
+ mud_telnet_msp_parser_clear(view->priv->telnet);
+ buf = view->priv->processed->str;
+
+ temp = view->local_echo;
+ view->local_echo = FALSE;
+ gag = mud_parse_base_do_triggers(view->priv->parse,
+ buf);
+ view->local_echo = temp;
+
+ mud_window_handle_plugins(view->priv->window, view->priv->id,
+ buf, length, 1);
+
+ pluggag = PluginGag;
+ PluginGag = FALSE;
+
+ if(!gag && !pluggag)
+ {
+ vte_terminal_feed(VTE_TERMINAL(view->priv->terminal),
+ buf, length);
+ mud_log_write_hook(view->priv->log, buf, length);
+ }
+
+ if (view->priv->connect_hook) {
+ mud_connection_view_send (view, view->priv->connect_string);
+ view->priv->connect_hook = FALSE;
+ }
- if (view->priv->connect_hook) {
- mud_connection_view_send (view, view->priv->connect_string);
- view->priv->connect_hook = FALSE;
- }
-
- g_string_free(string, TRUE);
- buf = NULL;
+ buf = NULL;
+ }
}
gnet_conn_read(view->connection);
@@ -939,3 +1048,201 @@
VTE_TERMINAL(view->priv->terminal)->row_count);
}
}
+
+static void
+mud_connection_view_start_download(MudConnectionView *view)
+{
+ MudMSPDownloadItem *item;
+
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(view->priv->progressbar), 0.0);
+ gtk_label_set_text(GTK_LABEL(view->priv->dl_label), _("Connecting..."));
+ gtk_widget_show(view->priv->progressbar);
+ gtk_widget_show(view->priv->dl_label);
+ gtk_widget_show(view->priv->dl_button);
+
+ if(!view->priv->downloading && view->priv->dl_conn)
+ gnet_conn_http_delete(view->priv->dl_conn);
+
+ item = g_queue_peek_head(view->priv->download_queue);
+ view->priv->dl_conn = gnet_conn_http_new();
+ gnet_conn_http_set_uri(view->priv->dl_conn, item->url);
+ gnet_conn_http_set_user_agent (view->priv->dl_conn, "gnome-mud");
+
+ view->priv->downloading = TRUE;
+
+ gnet_conn_http_run_async(view->priv->dl_conn,
+ mud_connection_view_http_cb, view);
+}
+
+void
+mud_connection_view_queue_download(MudConnectionView *view, gchar *url, gchar *file)
+{
+ MudMSPDownloadItem *item;
+ guint i, size;
+ GConfClient *client;
+ gboolean download;
+
+ gchar key[2048];
+ gchar extra_path[512] = "";
+
+ client = gconf_client_get_default();
+
+ g_snprintf(key, 2048, "/apps/gnome-mud/%s%s", extra_path, "functionality/remote_download");
+ download = gconf_client_get_bool(client, key, NULL);
+
+ if(download)
+ {
+ size = g_queue_get_length(view->priv->download_queue);
+
+ for(i = 0; i < size; ++i) // Don't add items twice.
+ {
+ item = (MudMSPDownloadItem *)g_queue_peek_nth(view->priv->download_queue, i);
+
+ if(strcmp(item->url, url) == 0)
+ return;
+ }
+
+ item = NULL;
+ item = g_malloc(sizeof(MudMSPDownloadItem));
+
+ item->url = g_strdup(url);
+ item->file = g_strdup(file);
+
+ g_queue_push_tail(view->priv->download_queue, item);
+
+ item = NULL;
+
+ if(view->priv->downloading == FALSE)
+ mud_connection_view_start_download(view);
+ }
+}
+
+static void
+mud_connection_view_http_cb(GConnHttp *conn, GConnHttpEvent *event, gpointer data)
+{
+ MudConnectionView *view = (MudConnectionView *)data;
+ MudMSPDownloadItem *item;
+ gchar **uri;
+ GString *file_name;
+ GConnHttpEventData *event_data;
+
+ switch(event->type)
+ {
+ case GNET_CONN_HTTP_CONNECTED:
+ break;
+
+ case GNET_CONN_HTTP_DATA_PARTIAL:
+ event_data = (GConnHttpEventData *)event;
+
+ if(event_data->content_length == 0)
+ gtk_progress_bar_pulse(GTK_PROGRESS_BAR(view->priv->progressbar));
+ else
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(view->priv->progressbar),
+ (gdouble)((gdouble)event_data->data_received / (gdouble)event_data->content_length));
+ break;
+
+ case GNET_CONN_HTTP_DATA_COMPLETE:
+ event_data = (GConnHttpEventData *)event;
+
+ gtk_widget_hide(view->priv->progressbar);
+ gtk_widget_hide(view->priv->dl_label);
+ gtk_widget_hide(view->priv->dl_button);
+
+ item = g_queue_pop_head(view->priv->download_queue);
+
+ g_file_set_contents(item->file, event_data->buffer,
+ event_data->buffer_length, NULL);
+
+ mud_telnet_msp_download_item_free(item);
+
+ view->priv->downloading = FALSE;
+
+ if(!g_queue_is_empty(view->priv->download_queue))
+ mud_connection_view_start_download(view);
+ break;
+
+ case GNET_CONN_HTTP_TIMEOUT:
+ if(!view->priv->downloading)
+ break;
+
+ gtk_widget_hide(view->priv->progressbar);
+ gtk_widget_hide(view->priv->dl_label);
+ gtk_widget_hide(view->priv->dl_button);
+
+ g_warning(_("Connection timed out."));
+
+ item = g_queue_pop_head(view->priv->download_queue);
+ mud_telnet_msp_download_item_free(item);
+
+ view->priv->downloading = FALSE;
+
+ if(!g_queue_is_empty(view->priv->download_queue))
+ mud_connection_view_start_download(view);
+ break;
+
+ case GNET_CONN_HTTP_ERROR:
+ gtk_widget_hide(view->priv->progressbar);
+ gtk_widget_hide(view->priv->dl_label);
+ gtk_widget_hide(view->priv->dl_button);
+
+ g_warning(_("There was an internal http connection error."));
+
+ item = g_queue_pop_head(view->priv->download_queue);
+ mud_telnet_msp_download_item_free(item);
+
+ view->priv->downloading = FALSE;
+
+ if(!g_queue_is_empty(view->priv->download_queue))
+ mud_connection_view_start_download(view);
+
+ break;
+
+ case GNET_CONN_HTTP_RESOLVED:
+ break;
+
+ case GNET_CONN_HTTP_RESPONSE:
+ item = g_queue_peek_head(view->priv->download_queue);
+
+ uri = g_strsplit(item->url, "/", 0);
+
+ file_name = g_string_new(NULL);
+
+ g_string_append(file_name, _("Downloading"));
+ g_string_append_c(file_name, ' ');
+ g_string_append(file_name, uri[g_strv_length(uri) - 1]);
+ g_string_append(file_name, "...");
+
+ gtk_label_set_text(GTK_LABEL(view->priv->dl_label), file_name->str);
+
+ g_string_free(file_name, TRUE);
+ g_strfreev(uri);
+ break;
+
+ case GNET_CONN_HTTP_REDIRECT:
+ break;
+ }
+}
+
+static void
+mud_connection_view_cancel_dl_cb(GtkWidget *widget, MudConnectionView *view)
+{
+ MudMSPDownloadItem *item;
+
+ gtk_widget_hide(view->priv->progressbar);
+ gtk_widget_hide(view->priv->dl_label);
+ gtk_widget_hide(view->priv->dl_button);
+
+ if(view->priv->dl_conn)
+ {
+ gnet_conn_http_delete(view->priv->dl_conn);
+ view->priv->dl_conn = NULL;
+ }
+
+ item = g_queue_pop_head(view->priv->download_queue);
+ mud_telnet_msp_download_item_free(item);
+
+ view->priv->downloading = FALSE;
+
+ if(!g_queue_is_empty(view->priv->download_queue))
+ mud_connection_view_start_download(view);
+}
Modified: trunk/src/mud-connection-view.h
==============================================================================
--- trunk/src/mud-connection-view.h (original)
+++ trunk/src/mud-connection-view.h Mon Jun 30 09:54:58 2008
@@ -69,6 +69,7 @@
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);
+void mud_connection_view_queue_download(MudConnectionView *view, gchar *url, gchar *file);
#include "mud-profile.h"
void mud_connection_view_set_profile(MudConnectionView *view, MudProfile *profile);
Modified: trunk/src/mud-preferences-window.c
==============================================================================
--- trunk/src/mud-preferences-window.c (original)
+++ trunk/src/mud-preferences-window.c Mon Jun 30 09:54:58 2008
@@ -80,6 +80,8 @@
GtkWidget *proxy_combo;
GtkWidget *proxy_entry;
+ GtkWidget *msp_check;
+
GtkWidget *sb_lines;
GtkWidget *fp_font;
@@ -219,7 +221,7 @@
static void mud_preferences_window_proxy_check_cb(GtkWidget *widget, MudPreferencesWindow *window);
static void mud_preferences_window_proxy_combo_cb(GtkWidget *widget, MudPreferencesWindow *window);
static void mud_preferences_window_proxy_entry_cb(GtkWidget *widget, MudPreferencesWindow *window);
-
+static void mud_preferences_window_msp_check_cb(GtkWidget *widget, MudPreferencesWindow *window);
static void mud_preferences_window_update_echotext (MudPreferencesWindow *window, MudPrefs *preferences);
static void mud_preferences_window_update_keeptext (MudPreferencesWindow *window, MudPrefs *preferences);
@@ -236,6 +238,7 @@
static void mud_preferences_window_update_proxy_entry(MudPreferencesWindow *window, MudPrefs *preferences);
static void mud_preferences_window_update_encoding_check(MudPreferencesWindow *window, MudPrefs *preferences);
static void mud_preferences_window_update_encoding_combo(MudPreferencesWindow *window, MudPrefs *preferences);
+static void mud_preferences_window_update_msp_check(MudPreferencesWindow *window, MudPrefs *preferences);
void mud_preferences_window_populate_trigger_treeview(MudPreferencesWindow *window);
void mud_preferences_window_populate_alias_treeview(MudPreferencesWindow *window);
@@ -332,6 +335,7 @@
preferences->priv->proxy_check = glade_xml_get_widget(glade, "proxy_check");
preferences->priv->proxy_combo = glade_xml_get_widget(glade, "proxy_combo");
preferences->priv->proxy_entry = glade_xml_get_widget(glade, "proxy_entry");
+ preferences->priv->msp_check = glade_xml_get_widget(glade, "msp_check");
preferences->priv->fp_font = glade_xml_get_widget(glade, "fp_font");
@@ -942,6 +946,10 @@
G_CALLBACK(mud_preferences_window_proxy_entry_cb),
window);
+ g_signal_connect(G_OBJECT(window->priv->msp_check), "toggled",
+ G_CALLBACK(mud_preferences_window_msp_check_cb),
+ window);
+
g_signal_connect(G_OBJECT(window->priv->sb_lines), "changed",
G_CALLBACK(mud_preferences_window_scrollback_cb),
window);
@@ -992,6 +1000,7 @@
mud_preferences_window_update_proxy_entry(window, profile->preferences);
mud_preferences_window_update_encoding_check(window, profile->preferences);
mud_preferences_window_update_encoding_combo(window, profile->preferences);
+ mud_preferences_window_update_msp_check(window, profile->preferences);
}
static void
@@ -1068,6 +1077,15 @@
}
static void
+mud_preferences_window_msp_check_cb(GtkWidget *widget, MudPreferencesWindow *window)
+{
+ gboolean value = GTK_TOGGLE_BUTTON(widget)->active ? TRUE : FALSE;
+ RETURN_IF_CHANGING_PROFILES(window);
+
+ mud_profile_set_msp_check(window->priv->profile, value);
+}
+
+static void
mud_preferences_window_proxy_combo_cb(GtkWidget *widget, MudPreferencesWindow *window)
{
RETURN_IF_CHANGING_PROFILES(window);
@@ -1507,6 +1525,8 @@
mud_preferences_window_update_proxy_combo(window, profile->preferences);
if (mask->Encoding)
mud_preferences_window_update_encoding_combo(window, profile->preferences);
+ if (mask->UseRemoteDownload)
+ mud_preferences_window_update_msp_check(window, profile->preferences);
}
static void
@@ -1535,6 +1555,13 @@
}
static void
+mud_preferences_window_update_msp_check(MudPreferencesWindow *window, MudPrefs *preferences)
+{
+ gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(window->priv->msp_check), preferences->UseRemoteDownload);
+
+}
+
+static void
mud_preferences_window_update_proxy_combo(MudPreferencesWindow *window, MudPrefs *preferences)
{
gchar *profile_name;
Modified: trunk/src/mud-profile.c
==============================================================================
--- trunk/src/mud-profile.c (original)
+++ trunk/src/mud-profile.c Mon Jun 30 09:54:58 2008
@@ -549,6 +549,7 @@
UPDATE_STRING("encoding", Encoding, "ISO-8859-1");
UPDATE_BOOLEAN("use_proxy", UseProxy, FALSE);
UPDATE_BOOLEAN("remote_encoding", UseRemoteEncoding, FALSE);
+ UPDATE_BOOLEAN("remote_download", UseRemoteDownload, FALSE);
}
#undef UPDATE_BOOLEAN
@@ -639,6 +640,15 @@
gconf_client_set_bool(profile->priv->gconf_client, key, value, NULL);
}
+void
+mud_profile_set_msp_check (MudProfile *profile, const gint value)
+{
+ const gchar *key = mud_profile_gconf_get_key(profile, "functionality/remote_download");
+ RETURN_IF_NOTIFYING(profile);
+
+ gconf_client_set_bool(profile->priv->gconf_client, key, value, NULL);
+}
+
static void
mud_profile_set_proxy_combo_full(MudProfile *profile, gchar *version)
{
@@ -815,6 +825,7 @@
mud_profile_set_encoding_combo(to, from->preferences->Encoding);
mud_profile_set_encoding_check(to, from->preferences->UseRemoteEncoding);
mud_profile_set_proxy_check(to, from->preferences->UseProxy);
+ mud_profile_set_msp_check(to, from->preferences->UseRemoteDownload);
mud_profile_set_proxy_combo_full(to, from->preferences->ProxyVersion);
mud_profile_set_proxy_entry(to, from->preferences->ProxyHostname);
}
Modified: trunk/src/mud-profile.h
==============================================================================
--- trunk/src/mud-profile.h (original)
+++ trunk/src/mud-profile.h Mon Jun 30 09:54:58 2008
@@ -43,6 +43,7 @@
gboolean UseRemoteEncoding;
gboolean UseProxy;
+ gboolean UseRemoteDownload;
gchar *Encoding;
gchar *ProxyVersion;
gchar *ProxyHostname;
@@ -78,6 +79,7 @@
unsigned int Encoding : 1;
unsigned int ProxyVersion : 1;
unsigned int ProxyHostname : 1;
+ unsigned int UseRemoteDownload : 1;
} MudProfileMask;
struct _MudProfileClass
@@ -116,6 +118,7 @@
void mud_profile_set_proxy_check (MudProfile *profile, const gint value);
void mud_profile_set_proxy_combo(MudProfile *profile, GtkComboBox *combo);
void mud_profile_set_proxy_entry (MudProfile *profile, const gchar *value);
+void mud_profile_set_msp_check (MudProfile *profile, const gint value);
gchar *mud_profile_from_number(gint num);
gint mud_profile_num_from_name(gchar *name);
Modified: trunk/src/mud-telnet-handlers.c
==============================================================================
--- trunk/src/mud-telnet-handlers.c (original)
+++ trunk/src/mud-telnet-handlers.c Mon Jun 30 09:54:58 2008
@@ -296,3 +296,25 @@
g_string_free(args, TRUE);
}
+
+/* MSP */
+void
+MudHandler_MSP_Enable(MudTelnet *telnet, MudTelnetHandler *handler)
+{
+ handler->enabled = TRUE;
+ mud_telnet_msp_init(telnet);
+ telnet->msp_parser.enabled = TRUE;
+}
+
+void
+MudHandler_MSP_Disable(MudTelnet *telnet, MudTelnetHandler *handler)
+{
+ handler->enabled = FALSE;
+}
+
+void
+MudHandler_MSP_HandleSubNeg(MudTelnet *telnet, guchar *buf,
+ guint len, MudTelnetHandler *handler)
+{
+ return;
+}
Modified: trunk/src/mud-telnet-handlers.h
==============================================================================
--- trunk/src/mud-telnet-handlers.h (original)
+++ trunk/src/mud-telnet-handlers.h Mon Jun 30 09:54:58 2008
@@ -62,4 +62,10 @@
void MudHandler_ZMP_HandleSubNeg(MudTelnet *telnet, guchar *buf,
guint len, MudTelnetHandler *handler);
+/* MSP */
+void MudHandler_MSP_Enable(MudTelnet *telnet, MudTelnetHandler *handler);
+void MudHandler_MSP_Disable(MudTelnet *telnet, MudTelnetHandler *handler);
+void MudHandler_MSP_HandleSubNeg(MudTelnet *telnet, guchar *buf,
+ guint len, MudTelnetHandler *handler);
+
#endif // MUD_TELNET_HANDLERS_H
Added: trunk/src/mud-telnet-msp.c
==============================================================================
--- (empty file)
+++ trunk/src/mud-telnet-msp.c Mon Jun 30 09:54:58 2008
@@ -0,0 +1,891 @@
+/* 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#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-msp.h"
+
+static void mud_telnet_msp_parser_reset(MudTelnet *telnet);
+static void mud_telnet_msp_parser_args(MudTelnet *telnet);
+static void mud_telnet_msp_command_free(MudMSPCommand *command);
+static gboolean mud_telnet_msp_parser_is_param_char(gchar c);
+static gboolean mud_telnet_msp_parser_switch_on_param_char(gint *state, gchar *buf, gint index, gint len);
+static void mud_telnet_msp_process_command(MudTelnet *telnet, MudMSPCommand *command);
+static void mud_telnet_msp_stop_playing(MudTelnet *telnet, MudMSPTypes type);
+static void mud_telnet_msp_start_playing(MudTelnet *telnet, MudMSPTypes type);
+static gboolean mud_telnet_msp_get_files(MudTelnet *telnet, 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);
+
+GString *
+mud_telnet_msp_parse(MudTelnet *telnet, GString *buf, gint *len)
+{
+ gint count;
+ GString *ret = NULL;
+ gchar *temp;
+
+ mud_telnet_msp_parser_reset(telnet);
+
+ if(telnet->prev_buffer)
+ {
+ g_string_prepend(buf, telnet->prev_buffer->str);
+ g_string_free(telnet->prev_buffer, TRUE);
+ telnet->prev_buffer = NULL;
+ }
+
+ while(telnet->msp_parser.lex_pos_start < *len)
+ {
+ switch(telnet->msp_parser.state)
+ {
+ case MSP_STATE_TEXT:
+ if(buf->str[telnet->msp_parser.lex_pos_start] == '!')
+ telnet->msp_parser.state = MSP_STATE_POSSIBLE_COMMAND;
+ else
+ {
+ g_string_append_c(telnet->msp_parser.output,
+ buf->str[telnet->msp_parser.lex_pos_start++]);
+ }
+ break;
+
+ case MSP_STATE_POSSIBLE_COMMAND:
+ if(telnet->msp_parser.lex_pos_start + 1 == *len)
+ continue;
+ else if(buf->str[telnet->msp_parser.lex_pos_start + 1] != '!')
+ {
+ g_string_append_c(telnet->msp_parser.output,
+ buf->str[telnet->msp_parser.lex_pos_start++]);
+ telnet->msp_parser.state = MSP_STATE_TEXT;
+ continue;
+ }
+
+ telnet->msp_parser.state = MSP_STATE_COMMAND;
+ break;
+
+ case MSP_STATE_COMMAND:
+ if(telnet->msp_parser.lex_pos_start + 8 >= *len)
+ {
+ telnet->prev_buffer = g_string_new(NULL);
+
+ count = telnet->msp_parser.lex_pos_start;
+
+ while(count != buf->len)
+ g_string_append_c(telnet->prev_buffer, buf->str[count++]);
+
+ telnet->msp_parser.lex_pos_start += count;
+ continue;
+ }
+
+ if(buf->str[telnet->msp_parser.lex_pos_start + 2] == 'S' &&
+ buf->str[telnet->msp_parser.lex_pos_start + 3] == 'O' &&
+ buf->str[telnet->msp_parser.lex_pos_start + 4] == 'U' &&
+ buf->str[telnet->msp_parser.lex_pos_start + 5] == 'N' &&
+ buf->str[telnet->msp_parser.lex_pos_start + 6] == 'D')
+ telnet->msp_type = MSP_TYPE_SOUND;
+ else if(buf->str[telnet->msp_parser.lex_pos_start + 2] == 'M' &&
+ buf->str[telnet->msp_parser.lex_pos_start + 3] == 'U' &&
+ buf->str[telnet->msp_parser.lex_pos_start + 4] == 'S' &&
+ buf->str[telnet->msp_parser.lex_pos_start + 5] == 'I' &&
+ buf->str[telnet->msp_parser.lex_pos_start + 6] == 'C')
+ telnet->msp_type = MSP_TYPE_MUSIC;
+ else
+ {
+ /* Not an msp command, bail out. */
+ g_string_append_c(telnet->msp_parser.output, buf->str[telnet->msp_parser.lex_pos_start++]);
+ g_string_append_c(telnet->msp_parser.output, buf->str[telnet->msp_parser.lex_pos_start++]);
+
+ telnet->msp_parser.state = MSP_STATE_TEXT;
+ continue;
+ }
+
+ // Skip leading (
+ telnet->msp_parser.lex_pos_start += 8;
+ telnet->msp_parser.state = MSP_STATE_GET_ARGS;
+ continue;
+ break;
+
+ case MSP_STATE_GET_ARGS:
+ telnet->msp_parser.lex_pos_end = telnet->msp_parser.lex_pos_start;
+
+ if(telnet->msp_parser.arg_buffer == NULL)
+ telnet->msp_parser.arg_buffer = g_string_new(NULL);
+ else
+ {
+ /* This stops some craziness where g_string_append_c
+ doesn't actually update the gstring. Glib bug? */
+ temp = g_strdup(telnet->msp_parser.arg_buffer->str);
+ g_string_free(telnet->msp_parser.arg_buffer, TRUE);
+ telnet->msp_parser.arg_buffer = g_string_new(temp);
+ g_free(temp);
+ }
+
+ while(telnet->msp_parser.lex_pos_end < *len && buf->str[telnet->msp_parser.lex_pos_end] != ')')
+ g_string_append_c(telnet->msp_parser.arg_buffer, buf->str[telnet->msp_parser.lex_pos_end++]);
+
+ if(telnet->msp_parser.lex_pos_end >= *len && buf->str[telnet->msp_parser.lex_pos_end - 1] != ')')
+ {
+ telnet->msp_parser.lex_pos_start = telnet->msp_parser.lex_pos_end;
+ continue;
+ }
+
+ telnet->msp_parser.state = MSP_STATE_PARSE_ARGS;
+
+ break;
+
+ case MSP_STATE_PARSE_ARGS:
+ mud_telnet_msp_parser_args(telnet);
+
+ g_string_free(telnet->msp_parser.arg_buffer, TRUE);
+ telnet->msp_parser.arg_buffer = NULL;
+ telnet->msp_parser.lex_pos_start = telnet->msp_parser.lex_pos_end + 2;
+ telnet->msp_parser.state = MSP_STATE_TEXT;
+ break;
+ }
+ }
+
+ if(telnet->msp_parser.state == MSP_STATE_TEXT)
+ {
+ ret = g_string_new(g_strdup(telnet->msp_parser.output->str));
+ *len = telnet->msp_parser.output->len;
+ }
+
+ return ret;
+}
+
+void
+mud_telnet_msp_init(MudTelnet *telnet)
+{
+ telnet->msp_parser.enabled = TRUE;
+ telnet->msp_parser.state = MSP_STATE_TEXT;
+ telnet->msp_parser.lex_pos_start = 0;
+ telnet->msp_parser.lex_pos_end = 0;
+ telnet->msp_parser.output = g_string_new(NULL);
+ telnet->msp_parser.arg_buffer = NULL;
+}
+
+void
+mud_telnet_msp_parser_clear(MudTelnet *telnet)
+{
+ if(telnet->msp_parser.output)
+ g_string_free(telnet->msp_parser.output, TRUE);
+
+ telnet->msp_parser.lex_pos_start = 0;
+ telnet->msp_parser.lex_pos_end = 0;
+ telnet->msp_parser.output = g_string_new(NULL);
+}
+
+void
+mud_telnet_msp_download_item_free(MudMSPDownloadItem *item)
+{
+ if(!item)
+ return;
+
+ if(item->url)
+ g_free(item->url);
+
+ if(item->file)
+ g_free(item->file);
+
+ g_free(item);
+}
+
+static void
+mud_telnet_msp_parser_reset(MudTelnet *telnet)
+{
+ telnet->msp_parser.lex_pos_start = 0;
+ telnet->msp_parser.lex_pos_end = 0;
+}
+
+#define ARG_STATE_FILE 0
+#define ARG_STATE_V 1
+#define ARG_STATE_L 2
+#define ARG_STATE_C 3
+#define ARG_STATE_T 4
+#define ARG_STATE_U 5
+#define ARG_STATE_P 6
+
+static void
+mud_telnet_msp_parser_args(MudTelnet *telnet)
+{
+ gint state = ARG_STATE_FILE;
+ gint i;
+ GString *buffer = g_string_new(NULL);
+ gchar *args = g_strdup(telnet->msp_parser.arg_buffer->str);
+ gint len = strlen(args);
+ MudMSPCommand *command = g_new0(MudMSPCommand, 1);
+
+ command->type = telnet->msp_type;
+ command->fName = NULL;
+ command->V = NULL;
+ command->L = NULL;
+ command->C = NULL;
+ command->T = NULL;
+ command->U = NULL;
+ command->P = NULL;
+
+ command->mud_name = g_strdup(telnet->mud_name);
+ 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 = (telnet->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
+ 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
+ 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
+ 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
+ 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
+ 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] != '/')
+ g_string_append_c(buffer, '/');
+
+ command->U = g_strdup(buffer->str);
+ g_string_free(buffer, TRUE);
+ buffer = g_string_new(NULL);
+ }
+ else
+ 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
+ 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] != '/')
+ 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(telnet, 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(MudTelnet *telnet, MudMSPCommand *command)
+{
+ /*g_message("MSP Command Parse Results");
+ g_print("Type: %s\n", (command->type == MSP_TYPE_SOUND) ? "Sound" : "Music" );
+ g_print("Filename: %s\n", (command->fName != NULL) ? command->fName : "<null>");
+ g_print("V: %s\n", (command->V != NULL) ? command->V : "<null>");
+ g_print("L: %s\n", (command->L != NULL) ? command->L : "<null>");
+ g_print("C: %s\n", (command->C != NULL) ? command->C : "<null>");
+ g_print("T: %s\n", (command->T != NULL) ? command->T : "<null>");
+ g_print("U: %s\n", (command->U != NULL) ? command->U : "<null>");
+ g_print("P: %s\n", (command->P != NULL) ? command->P : "<null>");
+ g_print("Sfx Type: %s Volume: %d Priority: %d Repeat %d times. %s %s\n", (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(telnet->base_url)
+ g_free(telnet->base_url);
+
+
+ telnet->base_url = g_strdup(command->U);
+ }
+ else
+ mud_telnet_msp_stop_playing(telnet, command->type);
+
+ mud_telnet_msp_command_free(command);
+
+ return;
+ }
+
+ if(telnet->sound[command->type].current_command)
+ {
+ if(telnet->sound[command->type].playing)
+ {
+ if(command->priority > telnet->sound[command->type].current_command->priority)
+ {
+ mud_telnet_msp_stop_playing(telnet, command->type);
+ telnet->sound[command->type].current_command = command;
+ mud_telnet_msp_start_playing(telnet, command->type);
+ }
+ else
+ mud_telnet_msp_command_free(command);
+ }
+ else
+ {
+ mud_telnet_msp_stop_playing(telnet, command->type);
+ telnet->sound[command->type].current_command = command;
+ mud_telnet_msp_start_playing(telnet, command->type);
+ }
+ }
+ else
+ {
+ telnet->sound[command->type].current_command = command;
+ mud_telnet_msp_start_playing(telnet, command->type);
+ }
+}
+
+static void
+mud_telnet_msp_stop_playing(MudTelnet *telnet, MudMSPTypes type)
+{
+ telnet->sound[type].playing = FALSE;
+
+ if(GST_IS_ELEMENT(telnet->sound[type].play))
+ {
+ gst_element_set_state (telnet->sound[type].play, GST_STATE_NULL);
+ gst_object_unref (GST_OBJECT (telnet->sound[type].play));
+ }
+
+ if(telnet->sound[type].files)
+ {
+ g_strfreev(telnet->sound[type].files);
+ telnet->sound[type].files = NULL;
+ }
+
+ telnet->sound[type].files_len = 0;
+
+ mud_telnet_msp_command_free(telnet->sound[type].current_command);
+ telnet->sound[type].current_command = NULL;
+}
+
+static void
+mud_telnet_msp_start_playing(MudTelnet *telnet, MudMSPTypes type)
+{
+ if(!telnet->sound[type].current_command)
+ return;
+
+ if(mud_telnet_msp_get_files(telnet, type))
+ {
+ gint num = 0;
+
+ telnet->sound[type].playing = TRUE;
+
+ if(telnet->sound[type].files_len != 0)
+ num = rand() % telnet->sound[type].files_len;
+
+ telnet->sound[type].play = gst_element_factory_make ("playbin", "play");
+ g_object_set (G_OBJECT(telnet->sound[type].play),
+ "uri", telnet->sound[type].files[num], NULL);
+ g_object_set(G_OBJECT(telnet->sound[type].play),
+ "volume", (double)telnet->sound[type].current_command->volume/100, NULL);
+
+ telnet->sound[type].bus =
+ gst_pipeline_get_bus (GST_PIPELINE (telnet->sound[type].play));
+
+ if(type == MSP_TYPE_SOUND)
+ gst_bus_add_watch (telnet->sound[type].bus, mud_telnet_msp_sound_bus_call, telnet);
+ else
+ gst_bus_add_watch (telnet->sound[type].bus, mud_telnet_msp_music_bus_call, telnet);
+
+ gst_object_unref (telnet->sound[type].bus);
+
+ gst_element_set_state (telnet->sound[type].play, GST_STATE_PLAYING);
+ }
+}
+
+static gboolean
+mud_telnet_msp_get_files(MudTelnet *telnet, 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;
+ GDir *dir;
+ gint i, depth;
+ GPatternSpec *regex;
+
+ if(!telnet->sound[type].current_command)
+ return FALSE;
+
+ g_snprintf(sound_dir, 2048, "%s/.gnome-mud/audio/%s/",
+ g_get_home_dir(), telnet->sound[type].current_command->mud_name);
+ if(!g_file_test(sound_dir, G_FILE_TEST_IS_DIR))
+ mkdir(sound_dir, 0777 );
+
+ structure = g_strsplit(telnet->sound[type].current_command->fName, "/", 0);
+ depth = g_strv_length(structure);
+
+ subdir = g_string_new(NULL);
+
+ for(i = 0; i < depth - 1; ++i)
+ {
+ g_string_append(subdir, structure[i]);
+ g_string_append_c(subdir, '/');
+ }
+
+ file_name = g_string_new(structure[depth - 1]);
+
+ g_strfreev(structure);
+
+ full_dir = g_string_new(sound_dir);
+ g_string_append(full_dir, subdir->str);
+
+ if(telnet->sound[type].current_command->T)
+ g_string_append(full_dir, telnet->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))
+ {
+ g_string_append(file_output, "file://");
+ g_string_append(file_output, full_dir->str);
+ g_string_append_c(file_output, '/');
+ g_string_append(file_output, file);
+ 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 && telnet->sound[type].current_command->T)
+ {
+ g_string_free(full_dir, TRUE);
+ full_dir = g_string_new(sound_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))
+ {
+ g_string_append(file_output, "file://");
+ g_string_append(file_output, full_dir->str);
+ g_string_append_c(file_output, '/');
+ g_string_append(file_output, file);
+ 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(telnet->base_url || telnet->sound[type].current_command->U)
+ {
+ if(telnet->base_url)
+ g_string_append(url_output, telnet->base_url);
+ else
+ g_string_append(url_output, telnet->sound[type].current_command->U);
+
+ if(subdir->len != 0)
+ g_string_append(url_output, subdir->str);
+
+ if(telnet->sound[type].current_command->T)
+ {
+ g_string_append(url_output, telnet->sound[type].current_command->T);
+ g_string_append_c(url_output, '/');
+ }
+
+ g_string_append(url_output, file_name->str);
+
+ g_string_append(file_output, full_dir->str);
+ if(telnet->sound[type].current_command->T)
+ g_string_append_c(file_output, '/');
+ g_string_append(file_output, file_name->str);
+
+ telnet->sound[type].current_command->priority = 0;
+
+ mud_connection_view_queue_download(telnet->parent, 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(telnet->sound[type].files)
+ g_strfreev(telnet->sound[type].files);
+
+ telnet->sound[type].files = files;
+ telnet->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)
+{
+ MudTelnet *telnet = (MudTelnet *)data;
+
+ switch (GST_MESSAGE_TYPE (msg))
+ {
+ case GST_MESSAGE_EOS:
+ telnet->sound[MSP_TYPE_SOUND].playing = FALSE;
+
+ telnet->sound[MSP_TYPE_SOUND].current_command->current_repeat_count--;
+
+ gst_element_set_state (telnet->sound[MSP_TYPE_SOUND].play, GST_STATE_NULL);
+
+ if(telnet->sound[MSP_TYPE_SOUND].current_command->loop ||
+ telnet->sound[MSP_TYPE_SOUND].current_command->current_repeat_count != 0)
+ {
+ gint num = 0;
+
+ if(telnet->sound[MSP_TYPE_SOUND].files_len != 0)
+ num = rand() % telnet->sound[MSP_TYPE_SOUND].files_len;
+
+ g_object_set (G_OBJECT(telnet->sound[MSP_TYPE_SOUND].play),
+ "uri", telnet->sound[MSP_TYPE_SOUND].files[num], NULL);
+ g_object_set(G_OBJECT(telnet->sound[MSP_TYPE_SOUND].play),
+ "volume", (double)telnet->sound[MSP_TYPE_SOUND].current_command->volume/100.0, NULL);
+
+ gst_element_set_state (telnet->sound[MSP_TYPE_SOUND].play, GST_STATE_PLAYING);
+ }
+ else
+ mud_telnet_msp_stop_playing(telnet, 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)
+{
+ MudTelnet *telnet = (MudTelnet *)data;
+
+ switch (GST_MESSAGE_TYPE (msg))
+ {
+ case GST_MESSAGE_EOS:
+ telnet->sound[MSP_TYPE_MUSIC].playing = FALSE;
+
+ telnet->sound[MSP_TYPE_MUSIC].current_command->current_repeat_count--;
+
+ gst_element_set_state (telnet->sound[MSP_TYPE_MUSIC].play, GST_STATE_NULL);
+
+ if(telnet->sound[MSP_TYPE_MUSIC].current_command->loop ||
+ telnet->sound[MSP_TYPE_MUSIC].current_command->current_repeat_count != 0)
+ {
+ gint num = 0;
+
+ if(telnet->sound[MSP_TYPE_MUSIC].files_len != 0)
+ num = rand() % telnet->sound[MSP_TYPE_MUSIC].files_len;
+
+ g_object_set (G_OBJECT(telnet->sound[MSP_TYPE_MUSIC].play),
+ "uri", telnet->sound[MSP_TYPE_MUSIC].files[num], NULL);
+ g_object_set(G_OBJECT(telnet->sound[MSP_TYPE_MUSIC].play),
+ "volume", (double)telnet->sound[MSP_TYPE_MUSIC].current_command->volume/100.0, NULL);
+
+ gst_element_set_state (telnet->sound[MSP_TYPE_MUSIC].play, GST_STATE_PLAYING);
+ }
+ else
+ mud_telnet_msp_stop_playing(telnet, 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;
+}
Added: trunk/src/mud-telnet-msp.h
==============================================================================
--- (empty file)
+++ trunk/src/mud-telnet-msp.h Mon Jun 30 09:54:58 2008
@@ -0,0 +1,102 @@
+/* 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.
+ */
+
+#ifndef MUD_TELNET_MSP_H
+#define MUD_TELNET_MSP_H
+
+#include <glib.h>
+#include "mud-telnet.h"
+
+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 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;
+
+#include <gst/gst.h>
+typedef struct MudMSPSound
+{
+ gboolean playing;
+ gchar **files;
+ gint files_len;
+
+ GstElement *play;
+ GstBus *bus;
+
+ MudMSPCommand *current_command;
+} MudMSPSound;
+
+void mud_telnet_msp_init(MudTelnet *telnet);
+void mud_telnet_msp_parser_clear(MudTelnet *telnet);
+void mud_telnet_msp_download_item_free(MudMSPDownloadItem *item);
+GString *mud_telnet_msp_parse(MudTelnet *telnet, GString *buf, gint *len);
+
+#endif // MUD_TELNET_MSP_H
Modified: trunk/src/mud-telnet.c
==============================================================================
--- trunk/src/mud-telnet.c (original)
+++ trunk/src/mud-telnet.c Mon Jun 30 09:54:58 2008
@@ -39,7 +39,7 @@
struct _MudTelnetPrivate
{
-
+ GString *processed;
};
GType mud_telnet_get_type (void);
@@ -105,6 +105,9 @@
mud_telnet_init (MudTelnet *telnet)
{
telnet->priv = g_new0(MudTelnetPrivate, 1);
+ telnet->msp_parser.enabled = FALSE;
+ telnet->priv->processed = g_string_new(NULL);
+ telnet->prev_buffer = NULL;
}
static void
@@ -133,7 +136,7 @@
// Instantiate MudTelnet
MudTelnet*
-mud_telnet_new(MudConnectionView *parent, GConn *connection)
+mud_telnet_new(MudConnectionView *parent, GConn *connection, gchar *mud_name)
{
MudTelnet *telnet;
@@ -151,6 +154,20 @@
telnet->eor_enabled = FALSE;
+ telnet->mud_name = g_strdup(mud_name);
+
+ telnet->sound[0].files = NULL;
+ telnet->sound[0].current_command = NULL;
+ telnet->sound[0].playing = FALSE;
+ telnet->sound[0].files_len = 0;
+
+ telnet->sound[1].files = NULL;
+ telnet->sound[1].current_command = NULL;
+ telnet->sound[1].playing = FALSE;
+ telnet->sound[1].files_len = 0;
+
+ telnet->base_url = NULL;
+
return telnet;
}
@@ -217,6 +234,13 @@
telnet->handlers[5].disable = MudHandler_ZMP_Disable;
telnet->handlers[5].handle_sub_neg = MudHandler_ZMP_HandleSubNeg;
+ /* MSP */
+ telnet->handlers[6].type = HANDLER_MSP;
+ telnet->handlers[6].option_number = (guchar)TELOPT_MSP;
+ telnet->handlers[6].enabled = TRUE;
+ telnet->handlers[6].enable = MudHandler_MSP_Enable;
+ telnet->handlers[6].disable = MudHandler_MSP_Disable;
+ telnet->handlers[6].handle_sub_neg = MudHandler_MSP_HandleSubNeg;
}
gint
@@ -275,14 +299,14 @@
mud_telnet_send_sub_req(telnet, 5, (guchar)TELOPT_NAWS, w1, w0, h1, h0);
}
-MudTelnetBuffer
-mud_telnet_process(MudTelnet *telnet, guchar * buf, guint32 count)
+GString *
+mud_telnet_process(MudTelnet *telnet, guchar * buf, guint32 count, gint *len)
{
- guchar processed[32768];
size_t pos = 0;
guint32 i;
- MudTelnetBuffer ret;
g_assert(telnet != NULL);
+ GString *ret = NULL;
+ GString *buffer = g_string_new_len((gchar *)buf, count);
for (i = 0;i < count;++i)
{
@@ -292,14 +316,18 @@
if (buf[i] == (guchar)TEL_IAC)
telnet->tel_state = TEL_STATE_IAC;
else
- processed[pos++] = buf[i];
+ {
+ g_string_append_c(telnet->priv->processed, buffer->str[i]);
+ pos++;
+ }
break;
case TEL_STATE_IAC:
- switch (buf[i])
+ switch ((guchar)buffer->str[i])
{
case (guchar)TEL_IAC:
- processed[pos++] = buf[i];
+ pos++;
+ g_string_append_c(telnet->priv->processed, buffer->str[i]);
telnet->tel_state = TEL_STATE_TEXT;
break;
@@ -337,32 +365,32 @@
break;
default:
- g_warning("Illegal IAC command %d received", buf[i]);
+ g_warning("Illegal IAC command %d received", buffer->str[i]);
telnet->tel_state = TEL_STATE_TEXT;
break;
}
break;
case TEL_STATE_DO:
- mud_telnet_handle_positive_nego(telnet, buf[i],
+ mud_telnet_handle_positive_nego(telnet, (guchar)buffer->str[i],
(guchar)TEL_WILL, (guchar)TEL_WONT, FALSE);
telnet->tel_state = TEL_STATE_TEXT;
case TEL_STATE_WILL:
- mud_telnet_handle_positive_nego(telnet, buf[i],
+ mud_telnet_handle_positive_nego(telnet, (guchar)buffer->str[i],
(guchar)TEL_DO, (guchar)TEL_DONT, TRUE);
telnet->tel_state = TEL_STATE_TEXT;
break;
case TEL_STATE_DONT:
mud_telnet_handle_negative_nego(telnet,
- buf[i], (guchar)TEL_WILL, (guchar)TEL_WONT, FALSE);
+ (guchar)buffer->str[i], (guchar)TEL_WILL, (guchar)TEL_WONT, FALSE);
telnet->tel_state = TEL_STATE_TEXT;
break;
case TEL_STATE_WONT:
mud_telnet_handle_negative_nego(telnet,
- buf[i], (guchar)TEL_DO, (guchar)TEL_DONT, TRUE);
+ (guchar)buffer->str[i], (guchar)TEL_DO, (guchar)TEL_DONT, TRUE);
telnet->tel_state = TEL_STATE_TEXT;
break;
@@ -379,7 +407,7 @@
telnet->tel_state = TEL_STATE_TEXT;
}
else
- telnet->subreq_buffer[telnet->subreq_pos++] = buf[i];
+ telnet->subreq_buffer[telnet->subreq_pos++] = (guchar)buffer->str[i];
}
break;
@@ -393,17 +421,17 @@
telnet->tel_state = TEL_STATE_TEXT;
}
else
- telnet->subreq_buffer[telnet->subreq_pos++] = buf[i];
+ telnet->subreq_buffer[telnet->subreq_pos++] = (guchar)buffer->str[i];
telnet->tel_state = TEL_STATE_SB;
}
else if (buf[i] == (guchar)TEL_SE)
{
- telnet->subreq_buffer[telnet->subreq_pos++] = buf[i];
+ telnet->subreq_buffer[telnet->subreq_pos++] = (guchar)buffer->str[i];
mud_telnet_on_handle_subnego(telnet);
telnet->tel_state = TEL_STATE_TEXT;
} else {
- g_warning("Erronous byte %d after an IAC inside a subrequest", buf[i]);
+ g_warning("Erronous byte %d after an IAC inside a subrequest", buffer->str[i]);
telnet->subreq_pos = 0;
telnet->tel_state = TEL_STATE_TEXT;
}
@@ -411,8 +439,14 @@
}
}
- ret.buffer = processed;
- ret.len = pos;
+ if(telnet->tel_state == TEL_STATE_TEXT)
+ {
+ ret = g_string_new_len(g_strdup(telnet->priv->processed->str), pos);
+ g_string_free(telnet->priv->processed, TRUE);
+ telnet->priv->processed = g_string_new(NULL);
+ *len = pos;
+ }
+
return ret;
}
@@ -712,6 +746,7 @@
mud_telnet_on_enable_opt(telnet, opt_no, him);
return TRUE;
} else { // The opposite is queued
+ g_message("Refusing %d", opt_no);
mud_telnet_set_telopt_state(opt, TELOPT_STATE_WANTNO, bitshift);
mud_telnet_set_telopt_queue(opt, TELOPT_STATE_QUEUE_EMPTY, bitshift);
mud_telnet_send_iac(telnet, negative, opt_no);
Modified: trunk/src/mud-telnet.h
==============================================================================
--- trunk/src/mud-telnet.h (original)
+++ trunk/src/mud-telnet.h Mon Jun 30 09:54:58 2008
@@ -112,7 +112,8 @@
HANDLER_ECHO,
HANDLER_EOR,
HANDLER_CHARSET,
- HANDLER_ZMP
+ HANDLER_ZMP,
+ HANDLER_MSP
};
struct _MudTelnetClass
@@ -120,12 +121,6 @@
GObjectClass parent_class;
};
-struct _MudTelnetBuffer
-{
- guchar *buffer;
- size_t len;
-};
-
struct _MudTelnetHandler
{
enum TelnetHandlerType type;
@@ -141,8 +136,10 @@
};
#include <gnet.h>
-#include <mud-connection-view.h>
-#include <mud-telnet-zmp.h>
+#include "mud-connection-view.h"
+#include "mud-telnet-zmp.h"
+#include "mud-telnet-msp.h"
+
struct _MudTelnet
{
GObject parent_instance;
@@ -164,15 +161,24 @@
GHashTable *zmp_commands;
MudZMPCommand commands[2048];
+
+ MudMSPParser msp_parser;
+ MudMSPTypes msp_type;
+ MudMSPSound sound[2];
+ gchar *base_url;
+
+ GString *prev_buffer;
+
+ gchar *mud_name;
};
GType mud_telnet_get_type (void) G_GNUC_CONST;
-MudTelnet *mud_telnet_new(MudConnectionView *parent, GConn *connection);
+MudTelnet *mud_telnet_new(MudConnectionView *parent, GConn *connection, gchar *mud_name);
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);
+GString *mud_telnet_process(MudTelnet *telnet, guchar * buf, guint32 count, gint *length);
void mud_telnet_send_sub_req(MudTelnet *telnet, guint32 count, ...);
void mud_telnet_get_parent_size(MudTelnet *telnet, gint *w, gint *h);
void mud_telnet_send_raw(MudTelnet *telnet, guint32 count, ...);
Modified: trunk/src/mud-window.c
==============================================================================
--- trunk/src/mud-window.c (original)
+++ trunk/src/mud-window.c Mon Jun 30 09:54:58 2008
@@ -38,6 +38,7 @@
#include <gtk/gtktextbuffer.h>
#include <gtk/gtktextiter.h>
#include <gtk/gtkimagemenuitem.h>
+#include <gtk/gtkprogressbar.h>
#include <vte/vte.h>
#include <glib/gstring.h>
#include <string.h>
@@ -317,9 +318,12 @@
text = mud_connection_view_get_history_item(
MUD_CONNECTION_VIEW(window->priv->current_view), HISTORY_UP);
- gtk_text_buffer_set_text(buffer, text, strlen(text));
- gtk_text_buffer_get_bounds(buffer, &start, &end);
- gtk_text_buffer_select_range(buffer, &start, &end);
+ if(text)
+ {
+ gtk_text_buffer_set_text(buffer, text, strlen(text));
+ gtk_text_buffer_get_bounds(buffer, &start, &end);
+ gtk_text_buffer_select_range(buffer, &start, &end);
+ }
return TRUE;
}
@@ -329,9 +333,12 @@
text = mud_connection_view_get_history_item(
MUD_CONNECTION_VIEW(window->priv->current_view), HISTORY_DOWN);
- gtk_text_buffer_set_text(buffer, text, strlen(text));
- gtk_text_buffer_get_bounds(buffer, &start, &end);
- gtk_text_buffer_select_range(buffer, &start, &end);
+ if(text)
+ {
+ gtk_text_buffer_set_text(buffer, text, strlen(text));
+ gtk_text_buffer_get_bounds(buffer, &start, &end);
+ gtk_text_buffer_select_range(buffer, &start, &end);
+ }
return TRUE;
}
@@ -737,7 +744,7 @@
/* start glading */
glade = glade_xml_new(GLADEDIR "/main.glade", "main_window", NULL);
window->priv->window = glade_xml_get_widget(glade, "main_window");
- gtk_widget_show_all(window->priv->window);
+ //gtk_widget_show_all(window->priv->window);
/* connect quit buttons */
g_signal_connect(window->priv->window, "destroy", G_CALLBACK(mud_window_close), window);
Modified: trunk/src/utils.c
==============================================================================
--- trunk/src/utils.c (original)
+++ trunk/src/utils.c Mon Jun 30 09:54:58 2008
@@ -42,14 +42,13 @@
gchar *
strip_ansi(const gchar *orig)
{
- gchar *buf;
+ GString *buf = g_string_new(NULL);
const gchar *c;
- gint currChar = 0;
+ gchar *ret = NULL;
if (!orig)
return NULL;
- buf = g_malloc(strlen(orig) * sizeof(gchar));
for (c = orig; *c;)
{
switch (*c)
@@ -63,11 +62,15 @@
break;
default:
- buf[currChar++] = *c++;
+ g_string_append_c(buf, *c++);
}
}
- return buf;
+ ret = g_strdup(buf->str);
+
+ g_string_free(buf, TRUE);
+
+ return ret;
}
void
Modified: trunk/ui/main.glade
==============================================================================
--- trunk/ui/main.glade (original)
+++ trunk/ui/main.glade Mon Jun 30 09:54:58 2008
@@ -466,12 +466,16 @@
</child>
<child>
- <widget class="GtkVBox" id="vbox5">
+ <widget class="GtkVBox" id="content_box">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
+ <placeholder/>
+ </child>
+
+ <child>
<widget class="GtkNotebook" id="notebook">
<property name="visible">True</property>
<property name="show_tabs">False</property>
@@ -547,6 +551,7 @@
<child>
<widget class="GtkTextView" id="text_view">
+ <property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="overwrite">False</property>
Modified: trunk/ui/prefs.glade
==============================================================================
--- trunk/ui/prefs.glade (original)
+++ trunk/ui/prefs.glade Mon Jun 30 09:54:58 2008
@@ -584,6 +584,65 @@
<property name="fill">False</property>
</packing>
</child>
+
+ <child>
+ <widget class="GtkHBox" id="hbox38">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="label51">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">
+Mud Sound Protocol:
+</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="msp_check">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Enable Remote Downloading</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="tab_expand">False</property>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]