[gnome-mud] Git now current with svn.
- From: Les Harris <lharris src gnome org>
- To: svn-commits-list gnome org
- Subject: [gnome-mud] Git now current with svn.
- Date: Sun, 19 Apr 2009 20:17:58 -0400 (EDT)
commit 9b6c50e60df782ed9f7309451b78a9d83d6f5042
Author: Les Harris <lharris gnome org>
Date: Sun Apr 19 17:17:50 2009 -0700
Git now current with svn.
---
src/gnome-mud-marshallers.list | 1 +
src/gnome-mud.c | 18 ++-
src/handlers/mud-telnet-handlers.h | 1 +
src/handlers/mud-telnet-msp.c | 114 ++++---------
src/handlers/mud-telnet-msp.h | 4 +-
src/handlers/mud-telnet-naws.c | 18 ++-
src/handlers/mud-telnet-naws.h | 2 +-
src/mud-connection-view.c | 282 +++++++++++++++++++++----------
src/mud-connection-view.h | 4 +
src/mud-line-buffer.c | 141 +++++++++++++---
src/mud-line-buffer.h | 43 ++++--
src/mud-log.c | 11 +-
src/mud-log.h | 2 +-
src/mud-subwindow.c | 54 +++++-
src/mud-subwindow.h | 1 +
src/mud-telnet.c | 19 ++-
src/mud-telnet.h | 31 ++++
src/mud-trigger.c | 330 ++++++++++++++++++++++++++----------
src/mud-trigger.h | 7 +-
src/mud-window.c | 27 +++-
src/zmp/zmp-subwindow.c | 27 +++
21 files changed, 809 insertions(+), 328 deletions(-)
diff --git a/src/gnome-mud-marshallers.list b/src/gnome-mud-marshallers.list
index d023d1a..0c8d9c3 100644
--- a/src/gnome-mud-marshallers.list
+++ b/src/gnome-mud-marshallers.list
@@ -1,3 +1,4 @@
VOID:INT,INT
VOID:UINT,UINT
VOID:STRING,UINT
+VOID:POINTER,UINT
diff --git a/src/gnome-mud.c b/src/gnome-mud.c
index 8bf20da..bf88bdb 100644
--- a/src/gnome-mud.c
+++ b/src/gnome-mud.c
@@ -121,22 +121,30 @@ main (gint argc, char *argv[])
window = g_object_new(MUD_TYPE_WINDOW, NULL);
{
+ MudLineBufferLine *line = g_new0(MudLineBufferLine, 1);
MudTrigger *trigger = g_object_new(MUD_TYPE_TRIGGER,
"trigger-key", "test",
"profile-key", "test",
- "lines", 3,
+ "lines", 1,
"action-type", MUD_TRIGGER_ACTION_TEXT,
- "action", "\n=== %0 ===\n=== %1 ===\n",
+ "action", "=== %0 ===\n\t%1\n\t%2",
NULL);
- gchar *test_line = g_strdup("Foo says, \"Bar\"\n");
+ line->line = g_strdup("Foo says, \"foobazbar\"");
- mud_trigger_add_data(trigger, test_line, strlen(test_line));
+ mud_trigger_execute(trigger, line, strlen(line->line));
- g_free(test_line);
+ g_free(line->line);
+ g_free(line);
g_object_unref(trigger);
}
+ {
+ g_printf("%c%c%d%c%d%c%d%c", '\x1B', '[', 1 , ';', 36, ';', 40, 'm');
+ g_printf("%s", "test");
+ g_printf("%c%c%d%c\n", '\x1B', '[', 0, 'm');
+ }
+
gtk_main();
gconf_client_suggest_sync(client, &err);
diff --git a/src/handlers/mud-telnet-handlers.h b/src/handlers/mud-telnet-handlers.h
index 6e0f916..7dc87d8 100644
--- a/src/handlers/mud-telnet-handlers.h
+++ b/src/handlers/mud-telnet-handlers.h
@@ -44,6 +44,7 @@ G_BEGIN_DECLS
#include "mud-telnet-new-environ.h"
#include "mud-telnet-ttype.h"
#include "mud-telnet-zmp.h"
+#include "mud-telnet-aardwolf.h"
G_END_DECLS
diff --git a/src/handlers/mud-telnet-msp.c b/src/handlers/mud-telnet-msp.c
index ce2862e..80971d3 100644
--- a/src/handlers/mud-telnet-msp.c
+++ b/src/handlers/mud-telnet-msp.c
@@ -34,6 +34,7 @@
#include "mud-telnet.h"
#include "mud-telnet-handler-interface.h"
#include "mud-telnet-msp.h"
+#include "mud-line-buffer.h"
struct _MudTelnetMspPrivate
{
@@ -365,93 +366,51 @@ mud_telnet_msp_parser_clear(MudTelnetMsp *self)
self->priv->msp_parser.output = g_string_new(NULL);
}
-GString *
-mud_telnet_msp_parse(MudTelnetMsp *self, GString *buf, gint *len)
+void
+mud_telnet_msp_parse(MudTelnetMsp *self, MudLineBufferLine *line)
{
- gint count;
- GString *ret = NULL;
+ guint len = strlen(line->line);
+ gchar *buf = line->line;
- if(!MUD_IS_TELNET_MSP(self))
- return NULL;
+ g_return_if_fail(MUD_IS_TELNET_MSP(self));
mud_telnet_msp_parser_reset(self);
- if(self->priv->prev_buffer)
- {
- buf = g_string_prepend(buf, self->priv->prev_buffer->str);
- g_string_free(self->priv->prev_buffer, TRUE);
- self->priv->prev_buffer = NULL;
- }
-
- while(self->priv->msp_parser.lex_pos_start < *len)
+ while(self->priv->msp_parser.lex_pos_start < len)
{
switch(self->priv->msp_parser.state)
{
case MSP_STATE_TEXT:
- if(buf->str[self->priv->msp_parser.lex_pos_start] == '!')
+ if(buf[self->priv->msp_parser.lex_pos_start] == '!')
self->priv->msp_parser.state = MSP_STATE_POSSIBLE_COMMAND;
else
- {
- self->priv->msp_parser.output =
- g_string_append_c(self->priv->msp_parser.output,
- buf->str[self->priv->msp_parser.lex_pos_start++]);
- }
+ self->priv->msp_parser.lex_pos_start++;
break;
case MSP_STATE_POSSIBLE_COMMAND:
- if(self->priv->msp_parser.lex_pos_start + 1 == *len)
- continue;
- else if(buf->str[self->priv->msp_parser.lex_pos_start + 1] != '!')
- {
- self->priv->msp_parser.output =
- g_string_append_c(self->priv->msp_parser.output,
- buf->str[self->priv->msp_parser.lex_pos_start++]);
- self->priv->msp_parser.state = MSP_STATE_TEXT;
- continue;
- }
+ if(buf[self->priv->msp_parser.lex_pos_start + 1] != '!')
+ return;
self->priv->msp_parser.state = MSP_STATE_COMMAND;
break;
case MSP_STATE_COMMAND:
- if(self->priv->msp_parser.lex_pos_start + 8 >= *len)
- {
- self->priv->prev_buffer = g_string_new(NULL);
-
- count = self->priv->msp_parser.lex_pos_start;
-
- while(count != buf->len)
- self->priv->prev_buffer =
- g_string_append_c(self->priv->prev_buffer, buf->str[count++]);
-
- self->priv->msp_parser.lex_pos_start += count;
- continue;
- }
-
- if(buf->str[self->priv->msp_parser.lex_pos_start + 2] == 'S' &&
- buf->str[self->priv->msp_parser.lex_pos_start + 3] == 'O' &&
- buf->str[self->priv->msp_parser.lex_pos_start + 4] == 'U' &&
- buf->str[self->priv->msp_parser.lex_pos_start + 5] == 'N' &&
- buf->str[self->priv->msp_parser.lex_pos_start + 6] == 'D')
+ if(buf[self->priv->msp_parser.lex_pos_start + 2] == 'S' &&
+ buf[self->priv->msp_parser.lex_pos_start + 3] == 'O' &&
+ buf[self->priv->msp_parser.lex_pos_start + 4] == 'U' &&
+ buf[self->priv->msp_parser.lex_pos_start + 5] == 'N' &&
+ buf[self->priv->msp_parser.lex_pos_start + 6] == 'D')
self->priv->msp_type = MSP_TYPE_SOUND;
- else if(buf->str[self->priv->msp_parser.lex_pos_start + 2] == 'M' &&
- buf->str[self->priv->msp_parser.lex_pos_start + 3] == 'U' &&
- buf->str[self->priv->msp_parser.lex_pos_start + 4] == 'S' &&
- buf->str[self->priv->msp_parser.lex_pos_start + 5] == 'I' &&
- buf->str[self->priv->msp_parser.lex_pos_start + 6] == 'C')
+ else if(buf[self->priv->msp_parser.lex_pos_start + 2] == 'M' &&
+ buf[self->priv->msp_parser.lex_pos_start + 3] == 'U' &&
+ buf[self->priv->msp_parser.lex_pos_start + 4] == 'S' &&
+ buf[self->priv->msp_parser.lex_pos_start + 5] == 'I' &&
+ buf[self->priv->msp_parser.lex_pos_start + 6] == 'C')
self->priv->msp_type = MSP_TYPE_MUSIC;
else
{
/* Not an msp command, bail out. */
- self->priv->msp_parser.output =
- g_string_append_c(self->priv->msp_parser.output,
- buf->str[self->priv->msp_parser.lex_pos_start++]);
- self->priv->msp_parser.output =
- g_string_append_c(self->priv->msp_parser.output,
- buf->str[self->priv->msp_parser.lex_pos_start++]);
-
- self->priv->msp_parser.state = MSP_STATE_TEXT;
- continue;
+ return;
}
// Skip leading (
@@ -461,19 +420,20 @@ mud_telnet_msp_parse(MudTelnetMsp *self, GString *buf, gint *len)
break;
case MSP_STATE_GET_ARGS:
- self->priv->msp_parser.lex_pos_end = self->priv->msp_parser.lex_pos_start;
+ self->priv->msp_parser.lex_pos_end =
+ self->priv->msp_parser.lex_pos_start;
if(self->priv->msp_parser.arg_buffer == NULL)
self->priv->msp_parser.arg_buffer = g_string_new(NULL);
- while(self->priv->msp_parser.lex_pos_end < *len &&
- buf->str[self->priv->msp_parser.lex_pos_end] != ')')
+ while(self->priv->msp_parser.lex_pos_end < len &&
+ buf[self->priv->msp_parser.lex_pos_end] != ')')
self->priv->msp_parser.arg_buffer =
g_string_append_c(self->priv->msp_parser.arg_buffer,
- buf->str[self->priv->msp_parser.lex_pos_end++]);
+ buf[self->priv->msp_parser.lex_pos_end++]);
- if(self->priv->msp_parser.lex_pos_end >= *len &&
- buf->str[self->priv->msp_parser.lex_pos_end - 1] != ')')
+ if(self->priv->msp_parser.lex_pos_end >= len &&
+ buf[self->priv->msp_parser.lex_pos_end - 1] != ')')
{
self->priv->msp_parser.lex_pos_start =
self->priv->msp_parser.lex_pos_end;
@@ -492,20 +452,12 @@ mud_telnet_msp_parse(MudTelnetMsp *self, GString *buf, gint *len)
self->priv->msp_parser.lex_pos_start =
self->priv->msp_parser.lex_pos_end + 1;
self->priv->msp_parser.state = MSP_STATE_TEXT;
- break;
- }
- }
- if(self->priv->msp_parser.state == MSP_STATE_TEXT)
- {
- ret = g_string_new(g_strdup(self->priv->msp_parser.output->str));
- *len = self->priv->msp_parser.output->len;
- }
+ line->gag = TRUE;
- g_string_free(buf, TRUE);
- *(&buf) = NULL;
-
- return ret;
+ return;
+ }
+ }
}
void
diff --git a/src/handlers/mud-telnet-msp.h b/src/handlers/mud-telnet-msp.h
index b8dbf1c..c47225b 100644
--- a/src/handlers/mud-telnet-msp.h
+++ b/src/handlers/mud-telnet-msp.h
@@ -41,6 +41,8 @@ typedef struct _MudTelnetMsp MudTelnetMsp;
typedef struct _MudTelnetMspClass MudTelnetMspClass;
typedef struct _MudTelnetMspPrivate MudTelnetMspPrivate;
+#include "mud-line-buffer.h"
+
struct _MudTelnetMspClass
{
GObjectClass parent_class;
@@ -139,7 +141,7 @@ typedef struct MudMSPSound
GType mud_telnet_msp_get_type (void);
void mud_telnet_msp_download_item_free(MudMSPDownloadItem *item);
-GString *mud_telnet_msp_parse(MudTelnetMsp *self, GString *buf, gint *len);
+void mud_telnet_msp_parse(MudTelnetMsp *self, MudLineBufferLine *line);
void mud_telnet_msp_stop_playing(MudTelnetMsp *self, MudMSPTypes type);
void mud_telnet_msp_parser_clear(MudTelnetMsp *self);
diff --git a/src/handlers/mud-telnet-naws.c b/src/handlers/mud-telnet-naws.c
index 36d3504..4b5ccf5 100644
--- a/src/handlers/mud-telnet-naws.c
+++ b/src/handlers/mud-telnet-naws.c
@@ -187,10 +187,10 @@ mud_telnet_naws_finalize (GObject *object)
self = MUD_TELNET_NAWS(object);
- if(self->priv->resized_signal != 0)
+ if(self->priv->resized_signal != 0 && IS_MUD_WINDOW(self->priv->window))
g_signal_handler_disconnect(self->priv->window, self->priv->resized_signal);
- if(self->priv->delete_signal != 0)
+ if(self->priv->delete_signal != 0 && GTK_IS_WIDGET(self->priv->main_window))
g_signal_handler_disconnect(self->priv->main_window, self->priv->delete_signal);
parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
@@ -389,3 +389,17 @@ mud_telnet_naws_delete_event_cb(GtkWidget *widget,
return FALSE;
}
+void
+mud_telnet_naws_disconnect_signals(MudTelnetNaws *self)
+{
+
+ if(self->priv->resized_signal != 0)
+ g_signal_handler_disconnect(self->priv->window, self->priv->resized_signal);
+
+ if(self->priv->delete_signal != 0)
+ g_signal_handler_disconnect(self->priv->main_window, self->priv->delete_signal);
+
+ self->priv->resized_signal = 0;
+ self->priv->delete_signal = 0;
+}
+
diff --git a/src/handlers/mud-telnet-naws.h b/src/handlers/mud-telnet-naws.h
index c125b99..1dc8426 100644
--- a/src/handlers/mud-telnet-naws.h
+++ b/src/handlers/mud-telnet-naws.h
@@ -51,7 +51,7 @@ struct _MudTelnetNaws
GType mud_telnet_naws_get_type (void);
-
+void mud_telnet_naws_disconnect_signals(MudTelnetNaws *self);
G_END_DECLS
diff --git a/src/mud-connection-view.c b/src/mud-connection-view.c
index 044b6d2..1e72b93 100644
--- a/src/mud-connection-view.c
+++ b/src/mud-connection-view.c
@@ -39,6 +39,7 @@
#include "mud-log.h"
#include "mud-parse-base.h"
#include "mud-telnet.h"
+#include "mud-line-buffer.h"
#include "mud-subwindow.h"
#include "utils.h"
@@ -63,6 +64,8 @@ struct _MudConnectionViewPrivate
gchar *current_output;
GList *subwindows;
+ MudLineBuffer *line_buffer;
+
#ifdef ENABLE_GST
GQueue *download_queue;
GConnHttp *dl_conn;
@@ -134,6 +137,14 @@ static void mud_connection_view_close_current_cb(GtkWidget *menu_item,
static void mud_connection_view_profile_changed_cb(MudProfile *profile,
MudProfileMask *mask,
MudConnectionView *view);
+static void mud_connection_view_line_added_cb(MudLineBuffer *buffer,
+ MudLineBufferLine *line,
+ guint length,
+ MudConnectionView *view);
+static void mud_connection_view_partial_line_cb(MudLineBuffer *buffer,
+ const gchar *line,
+ guint length,
+ MudConnectionView *view);
/* Private Methods */
@@ -388,6 +399,9 @@ mud_connection_view_init (MudConnectionView *self)
self->priv->subwindows = NULL;
self->priv->current_output = g_strdup("main");
+
+ self->priv->line_buffer = g_object_new(MUD_TYPE_LINE_BUFFER,
+ NULL);
}
static GObject *
@@ -521,6 +535,11 @@ mud_connection_view_constructor (GType gtype,
/* Setup VTE */
vte_terminal_set_encoding(self->terminal, "ISO-8859-1");
vte_terminal_set_emulation(self->terminal, "xterm");
+ vte_terminal_set_cursor_shape(self->terminal,
+ VTE_CURSOR_SHAPE_UNDERLINE);
+
+ vte_terminal_set_cursor_blink_mode(self->terminal,
+ VTE_CURSOR_BLINK_OFF);
g_object_get(self->window,
"window", &main_window,
@@ -606,6 +625,16 @@ mud_connection_view_constructor (GType gtype,
gtk_widget_hide(self->priv->dl_button);
#endif
+ g_signal_connect(self->priv->line_buffer,
+ "line-added",
+ G_CALLBACK(mud_connection_view_line_added_cb),
+ self);
+
+ g_signal_connect(self->priv->line_buffer,
+ "partial-line-received",
+ G_CALLBACK(mud_connection_view_partial_line_cb),
+ self);
+
gnet_conn_connect(self->connection);
return obj;
@@ -666,8 +695,13 @@ mud_connection_view_finalize (GObject *object)
g_object_unref(connection_view->telnet);
g_object_unref(connection_view->log);
+
g_object_unref(connection_view->parse);
- g_object_unref(connection_view->profile);
+
+ if(connection_view->profile)
+ g_object_unref(connection_view->profile);
+
+ g_object_unref(connection_view->priv->line_buffer);
entry = g_list_first(connection_view->priv->subwindows);
@@ -1093,16 +1127,11 @@ mud_connection_view_popup(MudConnectionView *view, GdkEventButton *event)
static void
mud_connection_view_network_event_cb(GConn *conn, GConnEvent *event, gpointer pview)
{
- gint gag;
- gchar *buf;
- gboolean temp;
- MudConnectionView *view = MUD_CONNECTION_VIEW(pview);
gint length;
+ MudConnectionView *view = MUD_CONNECTION_VIEW(pview);
#ifdef ENABLE_GST
MudMSPDownloadItem *item;
- MudTelnetMsp *msp_handler;
- gboolean msp_parser_enabled;
#endif
g_assert(view != NULL);
@@ -1159,88 +1188,21 @@ mud_connection_view_network_event_cb(GConn *conn, GConnEvent *event, gpointer pv
}
view->priv->processed =
- mud_telnet_process(view->telnet, (guchar *)event->buffer,
- event->length, &length);
+ mud_telnet_process(view->telnet,
+ (guchar *)event->buffer,
+ event->length,
+ &length);
- if(view->priv->processed != NULL)
+ if(view->priv->processed)
{
-#ifdef ENABLE_GST
- msp_handler =
- MUD_TELNET_MSP(mud_telnet_get_handler(view->telnet,
- TELOPT_MSP));
-
- g_object_get(msp_handler,
- "enabled", &msp_parser_enabled,
- NULL);
+ mud_line_buffer_add_data(view->priv->line_buffer,
+ view->priv->processed->str,
+ view->priv->processed->len);
- if(msp_parser_enabled)
- {
- view->priv->processed =
- mud_telnet_msp_parse(msp_handler,
- view->priv->processed,
- &length);
- }
-#endif
- if(view->priv->processed != NULL)
- {
-#ifdef ENABLE_GST
- if(msp_parser_enabled)
- mud_telnet_msp_parser_clear(msp_handler);
-#endif
- buf = view->priv->processed->str;
-
- temp = view->local_echo;
- view->local_echo = FALSE;
- gag = mud_parse_base_do_triggers(view->parse,
- buf);
- view->local_echo = temp;
-
- if(!gag)
- {
- if(g_str_equal(view->priv->current_output, "main"))
- {
- vte_terminal_feed(view->terminal,
- buf,
- length);
-
- mud_window_toggle_tab_icon(view->window, view);
- }
- else
- {
- MudSubwindow *sub =
- mud_connection_view_get_subwindow(view,
- view->priv->current_output);
-
- if(sub)
- mud_subwindow_feed(sub, buf, length);
- else
- {
- vte_terminal_feed(view->terminal,
- buf,
- length);
-
- mud_window_toggle_tab_icon(view->window, view);
- }
-
- }
-
- if(view->logging)
- mud_log_write_hook(view->log, buf, length);
- }
-
- if (view->connect_hook) {
- mud_connection_view_send (view, view->connect_string);
- view->connect_hook = FALSE;
- }
+ g_string_free(view->priv->processed, TRUE);
+ view->priv->processed = NULL;
- if(view->priv->processed != NULL)
- {
- g_string_free(view->priv->processed, TRUE);
- view->priv->processed = NULL;
- }
-
- buf = NULL;
- }
+ mud_line_buffer_flush(view->priv->line_buffer);
}
gnet_conn_read(view->connection);
@@ -1257,6 +1219,121 @@ mud_connection_view_network_event_cb(GConn *conn, GConnEvent *event, gpointer pv
}
}
+static void
+mud_connection_view_line_added_cb(MudLineBuffer *buffer,
+ MudLineBufferLine *line,
+ guint length,
+ MudConnectionView *view)
+{
+#ifdef ENABLE_GST
+ MudTelnetMsp *msp_handler;
+ gboolean msp_parser_enabled;
+
+ msp_handler =
+ MUD_TELNET_MSP(mud_telnet_get_handler(view->telnet,
+ TELOPT_MSP));
+
+ g_object_get(msp_handler,
+ "enabled", &msp_parser_enabled,
+ NULL);
+
+ if(msp_parser_enabled)
+ {
+ mud_telnet_msp_parse(msp_handler,
+ line);
+
+ mud_telnet_msp_parser_clear(msp_handler);
+
+ if(line->gag)
+ return;
+ }
+#endif
+
+ // TODO: Trigger & script code.
+
+ if(!line->gag)
+ {
+ if(g_str_equal(view->priv->current_output, "main"))
+ {
+ vte_terminal_feed(view->terminal,
+ line->line,
+ length);
+
+ mud_window_toggle_tab_icon(view->window, view);
+ }
+ else
+ {
+ MudSubwindow *sub =
+ mud_connection_view_get_subwindow(view,
+ view->priv->current_output);
+
+ if(sub)
+ mud_subwindow_feed(sub, line->line, length);
+ else
+ {
+ vte_terminal_feed(view->terminal,
+ line->line,
+ length);
+
+ mud_window_toggle_tab_icon(view->window, view);
+ }
+ }
+
+ if (view->connect_hook)
+ {
+ mud_connection_view_send (view, view->connect_string);
+ view->connect_hook = FALSE;
+ }
+ }
+
+ if(view->logging)
+ mud_log_write_hook(view->log, line->line, length);
+}
+
+static void
+mud_connection_view_partial_line_cb(MudLineBuffer *buffer,
+ const gchar *line,
+ guint length,
+ MudConnectionView *view)
+{
+ //TODO: Pass through trigger and script code.
+
+ if(!mud_line_buffer_partial_clear(buffer))
+ {
+ mud_line_buffer_clear_partial_line(buffer);
+
+ if(g_str_equal(view->priv->current_output, "main"))
+ {
+ vte_terminal_feed(view->terminal,
+ line,
+ length);
+
+ mud_window_toggle_tab_icon(view->window, view);
+ }
+ else
+ {
+ MudSubwindow *sub =
+ mud_connection_view_get_subwindow(view,
+ view->priv->current_output);
+
+ if(sub)
+ mud_subwindow_feed(sub, line, length);
+ else
+ {
+ vte_terminal_feed(view->terminal,
+ line,
+ length);
+
+ mud_window_toggle_tab_icon(view->window, view);
+ }
+
+ }
+
+ }
+
+ if(view->logging)
+ mud_log_write_hook(view->log, line, length);
+}
static void
popup_menu_detach(GtkWidget *widget, GtkMenu *menu)
@@ -1399,6 +1476,9 @@ mud_connection_view_set_terminal_colors(MudConnectionView *view)
&view->profile->preferences->Foreground,
&view->profile->preferences->Background,
view->profile->preferences->Colors, C_MAX);
+
+ vte_terminal_set_color_cursor(view->terminal,
+ &view->profile->preferences->Background);
}
static void
@@ -1531,6 +1611,22 @@ mud_connection_view_enable_subwindow_input(MudConnectionView *view,
}
}
+void
+mud_connection_view_enable_subwindow_scroll(MudConnectionView *view,
+ const gchar *identifier,
+ gboolean enable)
+{
+ g_return_if_fail(IS_MUD_CONNECTION_VIEW(view));
+
+ if(mud_connection_view_has_subwindow(view, identifier))
+ {
+ MudSubwindow *sub =
+ mud_connection_view_get_subwindow(view, identifier);
+
+ mud_subwindow_enable_scroll(sub, enable);
+ }
+}
+
void
mud_connection_view_show_subwindow(MudConnectionView *view,
@@ -2049,10 +2145,13 @@ mud_connection_view_start_logging(MudConnectionView *view)
{
g_return_if_fail(IS_MUD_CONNECTION_VIEW(view));
- mud_log_open(view->log);
+ if(!view->logging)
+ {
+ mud_log_open(view->log);
- if(mud_log_islogging(view->log))
- view->logging = TRUE;
+ if(mud_log_islogging(view->log))
+ view->logging = TRUE;
+ }
}
void
@@ -2060,8 +2159,11 @@ mud_connection_view_stop_logging(MudConnectionView *view)
{
g_return_if_fail(IS_MUD_CONNECTION_VIEW(view));
- view->logging = FALSE;
- mud_log_close(view->log);
+ if(view->logging)
+ {
+ view->logging = FALSE;
+ mud_log_close(view->log);
+ }
}
void
diff --git a/src/mud-connection-view.h b/src/mud-connection-view.h
index 052bfa6..2ccb733 100644
--- a/src/mud-connection-view.h
+++ b/src/mud-connection-view.h
@@ -122,6 +122,10 @@ void mud_connection_view_enable_subwindow_input(MudConnectionView *view,
const gchar *identifier,
gboolean enable);
+void mud_connection_view_enable_subwindow_scroll(MudConnectionView *view,
+ const gchar *identifier,
+ gboolean enable);
+
void mud_connection_view_show_subwindow(MudConnectionView *view,
const gchar *identifier);
diff --git a/src/mud-line-buffer.c b/src/mud-line-buffer.c
index 832ea28..4dc9419 100644
--- a/src/mud-line-buffer.c
+++ b/src/mud-line-buffer.c
@@ -116,7 +116,7 @@ mud_line_buffer_class_init (MudLineBufferClass *klass)
"Total possible number of lines in buffer.",
0,
G_MAXULONG,
- 20,
+ G_MAXULONG,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
/* Register Signals */
@@ -127,10 +127,10 @@ mud_line_buffer_class_init (MudLineBufferClass *klass)
0,
NULL,
NULL,
- gnome_mud_cclosure_VOID__STRING_UINT,
+ gnome_mud_cclosure_VOID__POINTER_UINT,
G_TYPE_NONE,
2,
- G_TYPE_STRING,
+ G_TYPE_POINTER,
G_TYPE_UINT);
mud_line_buffer_signal[LINE_REMOVED] =
@@ -273,11 +273,15 @@ mud_line_buffer_add_data(MudLineBuffer *self,
g_return_if_fail(MUD_IS_LINE_BUFFER(self));
data_buffer = g_string_new_len(data, length);
- data_buffer = g_string_prepend(data_buffer,
- self->priv->incoming_buffer->str);
- g_string_free(self->priv->incoming_buffer, TRUE);
- self->priv->incoming_buffer = g_string_new(NULL);
+ if(self->priv->incoming_buffer)
+ {
+ data_buffer = g_string_prepend(data_buffer,
+ self->priv->incoming_buffer->str);
+
+ g_string_free(self->priv->incoming_buffer, TRUE);
+ self->priv->incoming_buffer = g_string_new(NULL);
+ }
line = g_string_new(NULL);
@@ -287,21 +291,29 @@ mud_line_buffer_add_data(MudLineBuffer *self,
if(data_buffer->str[i] == '\n')
{
+ MudLineBufferLine *new_line = g_new0(MudLineBufferLine, 1);
+
++self->priv->length;
+ new_line->gag = FALSE;
+ new_line->line = g_strdup(line->str);
+
self->priv->line_buffer =
g_list_append(self->priv->line_buffer,
- g_strdup(line->str));
+ new_line);
if(self->priv->length == self->priv->maximum_line_count + 1)
{
- gchar *kill_line =
+ MudLineBufferLine *kill_line =
(g_list_first(self->priv->line_buffer))->data;
self->priv->line_buffer = g_list_remove(self->priv->line_buffer,
kill_line);
if(kill_line)
+ {
+ g_free(kill_line->line);
g_free(kill_line);
+ }
--self->priv->length;
@@ -313,7 +325,7 @@ mud_line_buffer_add_data(MudLineBuffer *self,
g_signal_emit(self,
mud_line_buffer_signal[LINE_ADDED],
0,
- line->str,
+ new_line,
line->len);
g_string_free(line, TRUE);
@@ -346,7 +358,9 @@ mud_line_buffer_flush(MudLineBuffer *self)
g_list_foreach(self->priv->line_buffer, mud_line_buffer_free_line, NULL);
g_list_free(self->priv->line_buffer);
- g_string_free(self->priv->incoming_buffer, TRUE);
+
+ if(self->priv->incoming_buffer)
+ g_string_free(self->priv->incoming_buffer, TRUE);
self->priv->length = 0;
self->priv->line_buffer = NULL;
@@ -370,9 +384,10 @@ mud_line_buffer_get_lines(MudLineBuffer *self)
while(entry)
{
- const gchar *line = (gchar *)entry->data;
+ const MudLineBufferLine *line =
+ (MudLineBufferLine *)entry->data;
- lines = g_string_append(lines, line);
+ lines = g_string_append(lines, line->line);
entry = g_list_next(entry);
}
@@ -380,10 +395,67 @@ mud_line_buffer_get_lines(MudLineBuffer *self)
return g_string_free(lines, (lines->len == 0) );
}
+const GList *
+mud_line_buffer_get_lines_with_attributes(MudLineBuffer *self)
+{
+ return self->priv->line_buffer;
+}
+
+gchar *
+mud_line_buffer_get_lines_and_partial(MudLineBuffer *self)
+{
+ GList *entry;
+ GString *lines;
+
+ if(!MUD_IS_LINE_BUFFER(self))
+ {
+ g_critical("Invalid MudLineBuffer passed to mud_line_buffer_get_lines");
+ return NULL;
+ }
+
+ entry = g_list_first(self->priv->line_buffer);
+ lines = g_string_new(NULL);
+
+ while(entry)
+ {
+ const MudLineBufferLine *line =
+ (MudLineBufferLine *)entry->data;
+
+ lines = g_string_append(lines, line->line);
+
+ entry = g_list_next(entry);
+ }
+
+ if(self->priv->incoming_buffer)
+ {
+ lines = g_string_append(lines,
+ g_string_free(self->priv->incoming_buffer,
+ FALSE));
+
+ self->priv->incoming_buffer = NULL;
+ }
+
+ return g_string_free(lines, (lines->len == 0) );
+}
+
+void
+mud_line_buffer_clear_partial_line(MudLineBuffer *self)
+{
+ g_return_if_fail(MUD_IS_LINE_BUFFER(self));
+
+ if(self->priv->incoming_buffer)
+ {
+ g_string_free(self->priv->incoming_buffer, TRUE);
+ self->priv->incoming_buffer = g_string_new(NULL);
+ }
+}
+
const gchar *
mud_line_buffer_get_line(MudLineBuffer *self,
guint line)
{
+ MudLineBufferLine *buffer_line;
+
if(!MUD_IS_LINE_BUFFER(self))
{
g_critical("Invalid MudLineBuffer passed to mud_line_buffer_get_line");
@@ -393,7 +465,10 @@ mud_line_buffer_get_line(MudLineBuffer *self,
if(line >= self->priv->length)
return NULL;
- return g_list_nth_data(self->priv->line_buffer, line);
+ buffer_line = g_list_nth_data(self->priv->line_buffer,
+ line);
+
+ return buffer_line->line;
}
gchar *
@@ -426,7 +501,10 @@ mud_line_buffer_get_range(MudLineBuffer *self,
for(i = start; i < end; ++i)
{
- range = g_string_append(range, entry->data);
+ MudLineBufferLine *buffer_line =
+ (MudLineBufferLine *)entry->data;
+
+ range = g_string_append(range, buffer_line->line);
entry = g_list_next(entry);
}
@@ -438,19 +516,35 @@ void
mud_line_buffer_remove_line(MudLineBuffer *self,
guint line)
{
- const gchar *remove_data;
+ MudLineBufferLine *buffer_line;
g_return_if_fail(MUD_IS_LINE_BUFFER(self));
- remove_data = mud_line_buffer_get_line(self, line);
-
- if(!remove_data)
+ if(line >= self->priv->length)
return;
+ buffer_line = g_list_nth_data(self->priv->line_buffer,
+ line);
+
self->priv->line_buffer = g_list_remove(self->priv->line_buffer,
- remove_data);
+ buffer_line);
- g_free((gchar *)remove_data); // Somewhat naughty. But the line is removed.
+ g_free(buffer_line->line);
+ g_free(buffer_line);
+}
+
+gboolean
+mud_line_buffer_partial_clear(MudLineBuffer *self)
+{
+ if(!MUD_IS_LINE_BUFFER(self))
+ return TRUE;
+
+ if(!self->priv->incoming_buffer)
+ return TRUE;
+ else if(self->priv->incoming_buffer->len == 0)
+ return TRUE;
+
+ return FALSE;
}
/* Private Methods */
@@ -458,9 +552,12 @@ static void
mud_line_buffer_free_line(gpointer value,
gpointer user_data)
{
- gchar *line = (gchar *)value;
+ MudLineBufferLine *line = (MudLineBufferLine *)value;
if(line)
+ {
+ g_free(line->line);
g_free(line);
+ }
}
diff --git a/src/mud-line-buffer.h b/src/mud-line-buffer.h
index 14ba8c4..060d268 100644
--- a/src/mud-line-buffer.h
+++ b/src/mud-line-buffer.h
@@ -49,25 +49,42 @@ struct _MudLineBuffer
MudLineBufferPrivate *priv;
};
-GType mud_line_buffer_get_type (void);
+typedef struct MudLineBufferLine
+{
+ // Attributes
+ gboolean gag;
+
+ // Line Data
+ gchar *line;
+} MudLineBufferLine;
+
+GType mud_line_buffer_get_type (void);
+
+void mud_line_buffer_add_data(MudLineBuffer *self,
+ const gchar *data,
+ guint length);
+
+void mud_line_buffer_flush(MudLineBuffer *self);
+
+gchar * mud_line_buffer_get_lines(MudLineBuffer *self);
+
+const GList * mud_line_buffer_get_lines_with_attributes(MudLineBuffer *self);
-void mud_line_buffer_add_data(MudLineBuffer *self,
- const gchar *data,
- guint length);
+gchar * mud_line_buffer_get_lines_and_partial(MudLineBuffer *self);
-void mud_line_buffer_flush(MudLineBuffer *self);
+const gchar * mud_line_buffer_get_line(MudLineBuffer *self,
+ guint line);
-gchar * mud_line_buffer_get_lines(MudLineBuffer *self);
+gchar * mud_line_buffer_get_range(MudLineBuffer *self,
+ guint start,
+ guint end);
-const gchar * mud_line_buffer_get_line(MudLineBuffer *self,
- guint line);
+void mud_line_buffer_remove_line(MudLineBuffer *self,
+ guint line);
-gchar * mud_line_buffer_get_range(MudLineBuffer *self,
- guint start,
- guint end);
+void mud_line_buffer_clear_partial_line(MudLineBuffer *self);
-void mud_line_buffer_remove_line(MudLineBuffer *self,
- guint line);
+gboolean mud_line_buffer_partial_clear(MudLineBuffer *self);
G_END_DECLS
diff --git a/src/mud-log.c b/src/mud-log.c
index 9714344..f78f263 100644
--- a/src/mud-log.c
+++ b/src/mud-log.c
@@ -128,7 +128,7 @@ static gboolean mud_log_keypress_cb(GtkWidget *widget,
GdkEventKey *event,
MudLog *self);
static void mud_log_line_added_cb(MudLineBuffer *buffer,
- const gchar *line,
+ MudLineBufferLine *line,
guint length,
MudLog *self);
@@ -583,14 +583,14 @@ mud_log_prev_spin_changed_cb(GtkSpinButton *button,
static void
mud_log_line_added_cb(MudLineBuffer *buffer,
- const gchar *line,
+ MudLineBufferLine *line,
guint length,
MudLog *self)
{
if(!self->priv->done)
{
if(line && length != 0)
- mud_log_write(self, line, length);
+ mud_log_write(self, line->line, length);
if(self->priv->include_next)
{
@@ -829,7 +829,7 @@ mud_log_close(MudLog *log)
{
while(!g_queue_is_empty(log->priv->span_queue))
{
- mud_log_write(log, "</span>", strlen("</span>"));
+ fwrite("</span>", 1, strlen("</span>"), log->priv->logfile);
g_queue_pop_head(log->priv->span_queue);
}
}
@@ -875,7 +875,7 @@ mud_log_islogging(MudLog *log)
}
void
-mud_log_write_hook(MudLog *log, gchar *data, gint length)
+mud_log_write_hook(MudLog *log, const gchar *data, gint length)
{
g_return_if_fail(MUD_IS_LOG(log));
@@ -988,6 +988,7 @@ mud_log_parse_ecma_color(MudLog *self,
gchar **argv;
gboolean xterm_forecolor, xterm_color;
+ g_printf("%s\n", data);
argv = g_strsplit(data, ";", -1);
argc = g_strv_length(argv);
diff --git a/src/mud-log.h b/src/mud-log.h
index cac6eb0..5df74d4 100644
--- a/src/mud-log.h
+++ b/src/mud-log.h
@@ -55,7 +55,7 @@ struct _MudLog
GType mud_log_get_type (void);
/*< Public Methods >*/
-void mud_log_write_hook(MudLog *log, gchar *data, gint length);
+void mud_log_write_hook(MudLog *log, const gchar *data, gint length);
void mud_log_open(MudLog *log);
void mud_log_close(MudLog *log);
gboolean mud_log_islogging(MudLog *log);
diff --git a/src/mud-subwindow.c b/src/mud-subwindow.c
index 303f6f3..4c050e5 100644
--- a/src/mud-subwindow.c
+++ b/src/mud-subwindow.c
@@ -50,6 +50,7 @@ struct _MudSubwindowPrivate
gboolean visible;
gboolean view_hidden;
gboolean input_enabled;
+ gboolean scroll;
GQueue *history;
gint current_history_index;
@@ -60,7 +61,7 @@ struct _MudSubwindowPrivate
GtkWidget *window;
GtkWidget *entry;
GtkWidget *terminal;
- GtkWidget *scroll;
+ GtkWidget *scrollbar;
GtkWidget *vbox;
gint x, y;
@@ -87,7 +88,8 @@ enum
PROP_VIEW_HIDDEN,
PROP_INPUT,
PROP_OLD_WIDTH,
- PROP_OLD_HEIGHT
+ PROP_OLD_HEIGHT,
+ PROP_SCROLL
};
/* Signal Indices */
@@ -268,6 +270,14 @@ mud_subwindow_class_init (MudSubwindowClass *klass)
FALSE,
G_PARAM_READWRITE));
+ g_object_class_install_property(object_class,
+ PROP_SCROLL,
+ g_param_spec_boolean("scroll-enabled",
+ "Scroll Enabled",
+ "True if subwindow scrolls.",
+ TRUE,
+ G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
+
/* Register Signals */
mud_subwindow_signal[RESIZED] =
g_signal_new("resized",
@@ -322,7 +332,7 @@ mud_subwindow_init (MudSubwindow *self)
self->priv->window = NULL;
self->priv->entry = NULL;
- self->priv->scroll = NULL;
+ self->priv->scrollbar = NULL;
self->priv->terminal = NULL;
self->priv->vbox = NULL;
}
@@ -403,7 +413,7 @@ mud_subwindow_constructor (GType gtype,
gtk_widget_hide(self->priv->entry);
self->priv->terminal = vte_terminal_new();
- self->priv->scroll = gtk_vscrollbar_new(NULL);
+ self->priv->scrollbar = gtk_vscrollbar_new(NULL);
term_box = gtk_hbox_new(FALSE, 0);
vte_terminal_set_encoding(VTE_TERMINAL(self->priv->terminal),
@@ -429,7 +439,7 @@ mud_subwindow_constructor (GType gtype,
0);
gtk_box_pack_end(GTK_BOX(term_box),
- self->priv->scroll,
+ self->priv->scrollbar,
FALSE,
FALSE,
0);
@@ -439,14 +449,17 @@ mud_subwindow_constructor (GType gtype,
gtk_container_add(GTK_CONTAINER(self->priv->window), self->priv->vbox);
gtk_range_set_adjustment(
- GTK_RANGE(self->priv->scroll),
+ GTK_RANGE(self->priv->scrollbar),
VTE_TERMINAL(self->priv->terminal)->adjustment);
gtk_window_set_title(GTK_WINDOW(self->priv->window), self->priv->title);
gtk_widget_show(term_box);
gtk_widget_show(self->priv->vbox);
- gtk_widget_show(self->priv->scroll);
+
+ if(self->priv->scroll)
+ gtk_widget_show(self->priv->scrollbar);
+
gtk_widget_show(self->priv->terminal);
gtk_widget_show(self->priv->window);
@@ -545,6 +558,13 @@ mud_subwindow_set_property(GObject *object,
self->priv->input_enabled = new_boolean;
break;
+ case PROP_SCROLL:
+ new_boolean = g_value_get_boolean(value);
+
+ if(new_boolean != self->priv->scroll)
+ self->priv->scroll = new_boolean;
+ break;
+
case PROP_VISIBLE:
new_boolean = g_value_get_boolean(value);
@@ -647,6 +667,10 @@ mud_subwindow_get_property(GObject *object,
g_value_set_string(value, self->priv->identifier);
break;
+ case PROP_SCROLL:
+ g_value_set_boolean(value, self->priv->scroll);
+ break;
+
case PROP_WIDTH:
g_value_set_uint(value, self->priv->width);
break;
@@ -1119,3 +1143,19 @@ mud_subwindow_enable_input(MudSubwindow *self,
mud_subwindow_set_size(self, self->priv->width, self->priv->height);
}
+void
+mud_subwindow_enable_scroll(MudSubwindow *self,
+ gboolean enable)
+{
+ g_return_if_fail(MUD_IS_SUBWINDOW(self));
+
+ self->priv->input_enabled = enable;
+
+ if(enable)
+ gtk_widget_show(self->priv->scrollbar);
+ else
+ gtk_widget_hide(self->priv->scrollbar);
+
+ mud_subwindow_set_size(self, self->priv->width, self->priv->height);
+}
+
diff --git a/src/mud-subwindow.h b/src/mud-subwindow.h
index 97eae87..f31e166 100644
--- a/src/mud-subwindow.h
+++ b/src/mud-subwindow.h
@@ -54,6 +54,7 @@ GType mud_subwindow_get_type (void);
void mud_subwindow_show(MudSubwindow *self);
void mud_subwindow_hide(MudSubwindow *self);
void mud_subwindow_enable_input(MudSubwindow *self, gboolean enable);
+void mud_subwindow_enable_scroll(MudSubwindow *self, gboolean scroll);
void mud_subwindow_set_title(MudSubwindow *self, const gchar *title);
void mud_subwindow_set_size(MudSubwindow *self, guint width, guint height);
void mud_subwindow_reread_profile(MudSubwindow *self);
diff --git a/src/mud-telnet.c b/src/mud-telnet.c
index f4d2f5e..7110097 100644
--- a/src/mud-telnet.c
+++ b/src/mud-telnet.c
@@ -162,7 +162,7 @@ mud_telnet_class_init (MudTelnetClass *klass)
"ga received",
"set if GA has been received",
FALSE,
- G_PARAM_READABLE));
+ G_PARAM_READWRITE));
g_object_class_install_property(object_class,
PROP_EOR_RECEIVED,
@@ -170,7 +170,7 @@ mud_telnet_class_init (MudTelnetClass *klass)
"eor received",
"set if EOR has been received",
FALSE,
- G_PARAM_READABLE));
+ G_PARAM_READWRITE));
g_object_class_install_property(object_class,
PROP_CONNECTION,
@@ -279,6 +279,14 @@ mud_telnet_set_property(GObject *object,
self->parent_view = MUD_CONNECTION_VIEW(g_value_get_object(value));
break;
+ case PROP_GA_RECEIVED:
+ self->ga_received = g_value_get_boolean(value);
+ break;
+
+ case PROP_EOR_RECEIVED:
+ self->eor_received = g_value_get_boolean(value);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
@@ -504,13 +512,13 @@ mud_telnet_process(MudTelnet *telnet, guchar * buf, guint32 c, gint *len)
case (guchar)TEL_GA:
telnet->ga_received = TRUE;
- g_log("Telnet", G_LOG_LEVEL_INFO, "%s", "GA Received.");
// TODO: Hook up to triggers.
telnet->priv->tel_state = TEL_STATE_TEXT;
break;
case (guchar)TEL_EOR_BYTE:
// TODO: Hook up to triggers.
+ telnet->eor_received = TRUE;
telnet->priv->tel_state = TEL_STATE_TEXT;
break;
@@ -772,6 +780,7 @@ mud_telnet_register_handlers(MudTelnet *telnet)
g_object_new(MUD_TYPE_TELNET_NEWENVIRON,
"telnet", telnet,
NULL));
+
#ifdef ENABLE_GST
/* MSP */
g_hash_table_replace(telnet->priv->handlers,
@@ -869,6 +878,10 @@ mud_telnet_get_telopt_string(guchar ch)
string = g_string_append(string, "ZMP");
break;
+ case TELOPT_AARDWOLF:
+ string = g_string_append(string, "AARDWOLF");
+ break;
+
default:
g_string_printf(string, "Dec: %d Hex: %x Ascii: %c", ch, ch, ch);
break;
diff --git a/src/mud-telnet.h b/src/mud-telnet.h
index e844187..1911026 100644
--- a/src/mud-telnet.h
+++ b/src/mud-telnet.h
@@ -98,6 +98,37 @@ G_BEGIN_DECLS
#define TEL_NEWENVIRON_ESC 2
#define TEL_NEWENVIRON_USERVAR 3
+/* Aardwolf
+ * http://www.aardwolf.com/blog/2008/07/10/telnet-negotiation-control-mud-client-interaction */
+#define TELOPT_AARDWOLF 102
+#define TEL_AARDWOLF_STATMON 1
+#define TEL_AARDWOLF_BIGMAP 2
+#define TEL_AARDWOLF_HELP 3
+#define TEL_AARDWOLF_MAP_TAGS 4
+#define TEL_AARDWOLF_CHANNEL_TAGS 5
+#define TEL_AARDWOLF_TELL_TAGS 6
+#define TEL_AARDWOLF_SPELLUP_TAGS 7
+#define TEL_AARDWOLF_SKILLGAINS_TAGS 8
+#define TEL_AARDWOLF_SAY_TAGS 9
+#define TEL_AARDWOLF_SCORE_TAGS 11
+#define TEL_AARDWOLF_MAPPER_ROOM_NAMES 12
+#define TEL_AARDWOLF_MAPPER_EXITS 14
+#define TEL_AARDWOLF_EDITOR_TAGS 15
+#define TEL_AARDWOLF_EQUIP_TAGS 16
+#define TEL_AARDWOLF_INVENTORY_TAGS 17
+#define TEL_AARDWOLF_QUIET_ALL 50
+#define TEL_AARDWOLF_AUTOTICK 51
+#define TEL_AARDWOLF_PROMPTS 52
+#define TEL_AARDWOLF_PAGING 53
+#define TEL_AARDWOLF_SERVER 100
+#define TEL_AARDWOLF_SERVER_LOGIN 1
+#define TEL_AARDWOLF_SERVER_MOTD 2
+#define TEL_AARDWOLF_SERVER_ACTIVE 3
+#define TEL_AARDWOLF_SERVER_AFK 4
+#define TEL_AARDWOLF_SERVER_NOTE 5
+#define TEL_AARDWOLF_SERVER_EDIT 6
+#define TEL_AARDWOLF_SERVER_PAGED 7
+
#define TEL_SUBREQ_BUFFER_SIZE 16318
#define TELOPT_STATE_QUEUE_EMPTY FALSE
#define TELOPT_STATE_QUEUE_OPPOSITE TRUE
diff --git a/src/mud-trigger.c b/src/mud-trigger.c
index db27fa6..3df1ad8 100644
--- a/src/mud-trigger.c
+++ b/src/mud-trigger.c
@@ -29,6 +29,7 @@
#include "mud-line-buffer.h"
#include "mud-trigger.h"
+#include "mud-subwindow.h"
#include "gnome-mud-builtins.h"
#include "utils.h"
@@ -40,9 +41,11 @@ struct _MudTriggerPrivate
gulong lines;
gboolean enabled;
- gboolean gag_output;
+ gboolean gag;
- gboolean multiline;
+ /* Simple Text Triggers */
+ GRegex *simple_regex;
+ gchar *match_string;
/* Glob Triggers */
GPatternSpec *glob;
@@ -56,8 +59,11 @@ struct _MudTriggerPrivate
/* Condition Triggers */
GList *condition_items;
- /* Filter Child */
- MudTrigger *child;
+ /* Filter */
+ gboolean filter;
+ GList *filter_set;
+ guint filter_line;
+ gboolean filter_active_step;
/* Key names */
gchar *profile_key;
@@ -69,6 +75,14 @@ struct _MudTriggerPrivate
/* Variables */
GList *variables;
+
+ /* Subwindow */
+ GList *windows;
+ gchar *title;
+ guint width;
+ guint height;
+ gboolean input;
+ gboolean scroll;
};
enum
@@ -109,7 +123,7 @@ static void mud_trigger_get_property(GObject *object,
// Callbacks
static void mud_trigger_line_added_cb(MudLineBuffer *buffer,
- const gchar *line,
+ MudLineBufferLine *line,
guint length,
MudTrigger *self);
@@ -192,8 +206,7 @@ mud_trigger_init (MudTrigger *self)
self->priv->line_buffer = NULL;
- self->priv->gag_output = FALSE;
- self->priv->multiline = FALSE;
+ self->priv->gag = FALSE;
self->priv->glob = NULL;
self->priv->glob_string = NULL;
@@ -203,10 +216,12 @@ mud_trigger_init (MudTrigger *self)
self->priv->condition_items = NULL;
- self->priv->child = NULL;
-
self->priv->trigger_key = NULL;
self->priv->profile_key = NULL;
+
+ self->priv->windows = NULL;
+
+ self->priv->filter_set = NULL;
}
static GObject *
@@ -244,12 +259,23 @@ mud_trigger_constructor (GType gtype,
g_printf("Action: %s\n", self->priv->action);
g_printf("Action Type: %d\n", self->priv->action_type);
+ self->priv->type = MUD_TRIGGER_TYPE_SINGLE;
+ /*self->priv->regex = g_regex_new("^(.*) says, \n\"(.*)\"",
+ G_REGEX_OPTIMIZE|G_REGEX_MULTILINE|G_REGEX_DOTALL,
+ 0,
+ NULL);*/
+
+ //self->priv->glob = g_pattern_spec_new("foo?*bar*");
+
+ /*self->priv->simple_regex = g_regex_new("hello world",
+ G_REGEX_OPTIMIZE,
+ 0,
+ NULL);*/
+
self->priv->regex = g_regex_new("^(.*) says, \"(.*)\"",
G_REGEX_OPTIMIZE,
- G_REGEX_MATCH_NOTEMPTY,
+ 0,
NULL);
-
-
return obj;
}
@@ -266,6 +292,9 @@ mud_trigger_finalize (GObject *object)
if(self->priv->regex)
g_regex_unref(self->priv->regex);
+ if(self->priv->glob)
+ g_pattern_spec_free(self->priv->glob);
+
g_free(self->priv->trigger_key);
g_free(self->priv->profile_key);
@@ -407,21 +436,22 @@ mud_trigger_add_data(MudTrigger *self,
g_free(stripped);
}
-// Callbacks
-static void
-mud_trigger_line_added_cb(MudLineBuffer *buffer,
- const gchar *line,
- guint length,
- MudTrigger *self)
+void
+mud_trigger_execute(MudTrigger *self,
+ MudLineBufferLine *line,
+ guint length)
{
+ gchar *stripped = utils_strip_ansi(line->line);
+ guint len = strlen(stripped);
+
switch(self->priv->type)
{
case MUD_TRIGGER_TYPE_SINGLE:
- if(self->priv->regex)
+ if(self->priv->regex) // Regex match
{
if(g_regex_match_full(self->priv->regex,
- line,
- length,
+ stripped,
+ len,
0,
0,
&self->priv->info,
@@ -429,19 +459,149 @@ mud_trigger_line_added_cb(MudLineBuffer *buffer,
{
mud_trigger_do_action(self);
+ if(self->priv->gag)
+ line->gag = TRUE;
+
g_match_info_free(self->priv->info);
}
+ }
+ else if(self->priv->glob) // Glob match
+ {
+ if(g_pattern_match_string(self->priv->glob,
+ stripped))
+ {
+ mud_trigger_do_action(self);
+ if(self->priv->gag)
+ line->gag = TRUE;
+ }
}
+ else if(self->priv->simple_regex) // Simple text match.
+ {
+ if(g_regex_match_full(self->priv->simple_regex,
+ stripped,
+ len,
+ 0,
+ 0,
+ &self->priv->info,
+ NULL))
+ {
+ mud_trigger_do_action(self);
+
+ if(self->priv->gag)
+ line->gag = TRUE;
+
+ g_match_info_free(self->priv->info);
+ }
+ }
+ else
+ g_return_if_reached();
+
break;
- case MUD_TRIGGER_TYPE_MULTI:
+ case MUD_TRIGGER_TYPE_CONDITION:
break;
- case MUD_TRIGGER_TYPE_FILTER:
+ default:
+ g_warn_if_reached();
break;
+ }
- case MUD_TRIGGER_TYPE_CONDITION:
+ g_free(stripped);
+}
+
+void
+mud_trigger_add_filter_child(MudTrigger *self,
+ MudTrigger *child)
+{
+ g_return_if_fail(MUD_IS_TRIGGER(self));
+ g_return_if_fail(MUD_IS_TRIGGER(child));
+
+ self->priv->filter_set = g_list_append(self->priv->filter_set,
+ child);
+}
+
+void
+mud_trigger_add_window(MudTrigger *self,
+ const gchar *title,
+ guint width,
+ guint height,
+ gboolean input,
+ gboolean scroll)
+{
+
+}
+
+// Callbacks
+static void
+mud_trigger_line_added_cb(MudLineBuffer *buffer,
+ MudLineBufferLine *line,
+ guint length,
+ MudTrigger *self)
+{
+ gulong len, max;
+
+ switch(self->priv->type)
+ {
+ case MUD_TRIGGER_TYPE_MULTI:
+ g_object_get(self->priv->line_buffer,
+ "length", &len,
+ "maximum-line-count", &max,
+ NULL);
+
+ if(len == max)
+ {
+ gchar *lines = mud_line_buffer_get_lines(self->priv->line_buffer);
+ guint lines_length = strlen(lines);
+
+ if(self->priv->regex) // Regex match
+ {
+ if(g_regex_match_full(self->priv->regex,
+ lines,
+ lines_length,
+ 0,
+ 0,
+ &self->priv->info,
+ NULL))
+ {
+ mud_trigger_do_action(self);
+
+ g_match_info_free(self->priv->info);
+ }
+
+ }
+ else if(self->priv->glob) // Glob match
+ {
+ if(g_pattern_match_string(self->priv->glob,
+ lines))
+ {
+ mud_trigger_do_action(self);
+ }
+ }
+ else if(self->priv->simple_regex) // Simple text match.
+ {
+ if(g_regex_match_full(self->priv->simple_regex,
+ lines,
+ lines_length,
+ 0,
+ 0,
+ &self->priv->info,
+ NULL))
+ {
+ mud_trigger_do_action(self);
+
+ g_match_info_free(self->priv->info);
+ }
+ }
+ else
+ g_return_if_reached();
+
+ g_free(lines);
+ }
+ break;
+
+ default:
+ g_warn_if_reached();
break;
}
}
@@ -462,10 +622,16 @@ mud_trigger_do_action(MudTrigger *self)
data = mud_trigger_parse(self,
self->priv->action);
+ // send to mud here
g_printf("Parsed: %s\n", data);
g_free(data);
- }
+ }
+ else
+ {
+ // send to mud here
+ g_printf("Action Fired: %s\n", self->priv->action);
+ }
}
break;
@@ -473,6 +639,7 @@ mud_trigger_do_action(MudTrigger *self)
break;
case MUD_TRIGGER_ACTION_LUA:
+ // coming in 0.13
break;
}
}
@@ -480,10 +647,10 @@ mud_trigger_do_action(MudTrigger *self)
static gchar *
mud_trigger_parse(MudTrigger *self, const gchar *data)
{
- guint length, matches_length, i;
gint state;
- GString *ret, *reg_num;
gchar **matches;
+ GString *ret, *reg_num;
+ guint length, matches_length, i, j, num;
length = strlen(data);
@@ -503,87 +670,62 @@ mud_trigger_parse(MudTrigger *self, const gchar *data)
switch(state)
{
case PARSE_STATE_TEXT:
- if(data[i] == '%')
- {
- reg_num = g_string_new(NULL);
+ if(data[i] == '%' && i + 1 < length)
state = PARSE_STATE_REGISTER;
- }
else
ret = g_string_append_c(ret, data[i]);
break;
case PARSE_STATE_REGISTER:
- if(!g_ascii_isdigit(data[i]) &&
- i + 1 < length &&
- !g_ascii_isdigit(data[i + 1]))
+ reg_num = g_string_new(NULL);
+
+ j = i;
+
+ while(TRUE)
{
- if(reg_num->len == 0)
- {
- ret = g_string_append_c(ret, data[i]);
+ if(j == length || data[j] != '%')
+ break;
- if(i != 0 && data[ i - 1 ] == '%')
- ret = g_string_append_c(ret, data[ i - 1 ]);
+ ret = g_string_append_c(ret, data[j++]);
+ }
- g_string_free(reg_num, TRUE);
- reg_num = NULL;
+ if(j == length)
+ {
+ if(data[j - 1] == '%')
+ ret = g_string_append_c(ret, data[j - 1]);
- state = PARSE_STATE_TEXT;
- }
- else
- {
- guint num = atol(reg_num->str);
- gint check = i - reg_num->len - 2;
-
- if(num >= matches_length - 1)
- {
- if(i != 0 && check > -1 && data[check] == '%')
- ret = g_string_append_c(ret, '%');
-
- ret = g_string_append(ret, _("#Submatch Out of Range#"));
- ret = g_string_append_c(ret, data[i]);
-
- state = PARSE_STATE_TEXT;
- }
- else
- {
- if(i != 0 && check > -1 && data[check] == '%')
- ret = g_string_append_c(ret, '%');
- ret = g_string_append(ret, matches[num + 1]);
- ret = g_string_append_c(ret, data[i]);
-
- state = PARSE_STATE_TEXT;
- }
-
- g_string_free(reg_num, TRUE);
- reg_num = NULL;
- }
+ i = j;
+ break;
+ }
+
+ for(; g_ascii_isdigit(data[j]) && j < length; j++)
+ reg_num = g_string_append_c(reg_num, data[j]);
+
+ if(reg_num->len == 0) // No number, not a register.
+ {
+ /* Append the % that got us here. */
+ ret = g_string_append_c(ret, '%');
+
+ i = j - 1;
+
+ g_string_free(reg_num, TRUE);
+
+ state = PARSE_STATE_TEXT;
}
else
{
- if(g_ascii_isdigit(data[i]))
- reg_num = g_string_append_c(reg_num, data[i]);
+ i = j - 1;
- if(i + 1 == length)
- {
- if(reg_num->len != 0)
- {
- guint num = atol(reg_num->str);
-
- if(num >= matches_length - 1)
- {
- ret = g_string_append(ret, _("#Submatch Out of Range#"));
- state = PARSE_STATE_TEXT;
- }
- else
- ret = g_string_append(ret, matches[num + 1]);
- }
-
- if(!g_ascii_isdigit(data[i]))
- ret = g_string_append_c(ret, data[i]);
-
- g_string_free(reg_num, TRUE);
- reg_num = NULL;
- }
+ num = atol(reg_num->str);
+
+ g_string_free(reg_num, TRUE);
+
+ if(num >= matches_length)
+ ret = g_string_append(ret, _("#Submatch Out of Range#"));
+ else
+ ret = g_string_append(ret, matches[num]);
+
+ state = PARSE_STATE_TEXT;
}
break;
}
diff --git a/src/mud-trigger.h b/src/mud-trigger.h
index f70153e..214c04d 100644
--- a/src/mud-trigger.h
+++ b/src/mud-trigger.h
@@ -36,6 +36,8 @@ typedef struct _MudTrigger MudTrigger;
typedef struct _MudTriggerClass MudTriggerClass;
typedef struct _MudTriggerPrivate MudTriggerPrivate;
+#include "mud-line-buffer.h"
+
struct _MudTriggerClass
{
GObjectClass parent_class;
@@ -53,7 +55,6 @@ typedef enum
{
MUD_TRIGGER_TYPE_SINGLE,
MUD_TRIGGER_TYPE_MULTI,
- MUD_TRIGGER_TYPE_FILTER,
MUD_TRIGGER_TYPE_CONDITION
} MudTriggerType;
@@ -89,6 +90,10 @@ void mud_trigger_add_data(MudTrigger *self,
const gchar *data,
guint length);
+void mud_trigger_execute(MudTrigger *self,
+ MudLineBufferLine *line,
+ guint length);
+
G_END_DECLS
#endif // MUD_TRIGGER_H
diff --git a/src/mud-window.c b/src/mud-window.c
index 521750d..8ae4ce1 100644
--- a/src/mud-window.c
+++ b/src/mud-window.c
@@ -44,6 +44,8 @@
#include "mud-parse-base.h"
#include "mud-connections.h"
#include "gnome-mud-marshallers.h"
+#include "mud-telnet.h"
+#include "handlers/mud-telnet-handlers.h"
#include "utils.h"
struct _MudWindowPrivate
@@ -424,6 +426,7 @@ mud_window_constructor (GType gtype,
self->profile_manager = g_object_new(MUD_TYPE_PROFILE_MANAGER,
"parent-window", self,
NULL);
+
mud_window_populate_profiles_menu(self);
return obj;
@@ -448,12 +451,12 @@ mud_window_finalize (GObject *object)
entry = g_slist_next(entry);
}
- g_object_unref(self->profile_manager);
-
g_slist_free(self->priv->mud_views_list);
g_object_unref(self->tray);
+ g_object_unref(self->profile_manager);
+
parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
parent_class->finalize(object);
@@ -518,6 +521,26 @@ mud_window_get_property(GObject *object,
static int
mud_window_close(GtkWidget *widget, MudWindow *self)
{
+ GSList *entry = self->priv->mud_views_list;
+
+ while(entry != NULL)
+ {
+ MudTelnetNaws *naws;
+ gboolean enabled;
+ MudConnectionView *view =
+ MUD_CONNECTION_VIEW(entry->data);
+
+ naws = MUD_TELNET_NAWS(mud_telnet_get_handler(view->telnet,
+ TELOPT_NAWS));
+
+ g_object_get(naws, "enabled", &enabled, NULL);
+
+ if(enabled)
+ mud_telnet_naws_disconnect_signals(naws);
+
+ entry = g_slist_next(entry);
+ }
+
g_object_unref(self);
return TRUE;
diff --git a/src/zmp/zmp-subwindow.c b/src/zmp/zmp-subwindow.c
index 7c4c5ca..22cd665 100644
--- a/src/zmp/zmp-subwindow.c
+++ b/src/zmp/zmp-subwindow.c
@@ -78,6 +78,7 @@ static void zmp_subwindow_open(MudTelnetZmp *self, gint argc, gchar **argv);
static void zmp_subwindow_close(MudTelnetZmp *self, gint argc, gchar **argv);
static void zmp_subwindow_select(MudTelnetZmp *self, gint argc, gchar **argv);
static void zmp_subwindow_set_input(MudTelnetZmp *self, gint argc, gchar **argv);
+static void zmp_subwindow_set_scroll(MudTelnetZmp *self, gint argc, gchar **argv);
static void zmp_subwindow_do_input(MudSubwindow *sub,
const gchar *input,
ZmpSubwindow *self);
@@ -244,6 +245,9 @@ zmp_subwindow_register_commands(MudTelnetZmp *zmp)
mud_zmp_register(zmp, mud_zmp_new_command("subwindow.",
"subwindow.set-input",
zmp_subwindow_set_input));
+ mud_zmp_register(zmp, mud_zmp_new_command("subwindow.",
+ "subwindow.set-scroll",
+ zmp_subwindow_set_scroll));
/* If the server sends us these, its a broken server.
@@ -392,6 +396,29 @@ zmp_subwindow_set_input(MudTelnetZmp *self,
}
static void
+zmp_subwindow_set_scroll(MudTelnetZmp *self,
+ gint argc,
+ gchar **argv)
+{
+ MudConnectionView *view;
+ MudTelnet *telnet;
+ guint enable;
+
+ if(argc != 3)
+ return;
+
+ g_object_get(self, "telnet", &telnet, NULL);
+ g_object_get(telnet, "parent-view", &view, NULL);
+
+ enable = (guint)atol(argv[2]);
+
+ mud_connection_view_enable_subwindow_scroll(view,
+ argv[1],
+ enable);
+
+}
+
+static void
zmp_subwindow_do_input(MudSubwindow *sub,
const gchar *input,
ZmpSubwindow *self)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]