summaryrefslogtreecommitdiffhomepage
path: root/mixgtk
diff options
context:
space:
mode:
Diffstat (limited to 'mixgtk')
-rw-r--r--mixgtk/mixgtk.glade10
-rw-r--r--mixgtk/mixgtk_cmd_dispatcher.c228
-rw-r--r--mixgtk/mixgtk_mixvm.h1
-rw-r--r--mixgtk/mixgtk_widgets.c3
-rw-r--r--mixgtk/mixgtk_widgets.h3
5 files changed, 220 insertions, 25 deletions
diff --git a/mixgtk/mixgtk.glade b/mixgtk/mixgtk.glade
index 6676fbd..a0dcfcf 100644
--- a/mixgtk/mixgtk.glade
+++ b/mixgtk/mixgtk.glade
@@ -2586,6 +2586,11 @@
<name>extern_cancel_button</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
+ <signal>
+ <name>clicked</name>
+ <handler>on_extern_cancel_button_clicked</handler>
+ <last_modification_time>Mon, 04 Jun 2001 21:31:50 GMT</last_modification_time>
+ </signal>
<label>_Cancel</label>
<relief>GTK_RELIEF_NORMAL</relief>
</widget>
@@ -2595,6 +2600,11 @@
<name>extern_ok_button</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
+ <signal>
+ <name>clicked</name>
+ <handler>on_extern_ok_button_clicked</handler>
+ <last_modification_time>Mon, 04 Jun 2001 21:32:21 GMT</last_modification_time>
+ </signal>
<label>_OK</label>
<relief>GTK_RELIEF_NORMAL</relief>
</widget>
diff --git a/mixgtk/mixgtk_cmd_dispatcher.c b/mixgtk/mixgtk_cmd_dispatcher.c
index d53e991..bb1d4db 100644
--- a/mixgtk/mixgtk_cmd_dispatcher.c
+++ b/mixgtk/mixgtk_cmd_dispatcher.c
@@ -24,18 +24,20 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <mixlib/mix_vm_command.h>
-#include "mixgtk_cmd_dispatcher.h"
#include "mixgtk_mixvm.h"
#include "mixgtk_mixal.h"
+#include "mixgtk_config.h"
+#include "mixgtk_cmd_dispatcher.h"
/* a mix vm command dispatcher */
-struct mixgtk_dispatch_
+typedef struct mixgtk_dispatch_
{
mix_vm_cmd_dispatcher_t *dispatcher; /* the underlying cmd dispatcher */
FILE *out; /* the dispatcher's output file */
@@ -45,10 +47,128 @@ struct mixgtk_dispatch_
GtkWidget *status; /* the status bar widget */
guint context; /* context of the status bar messages */
GCompletion *completions; /* mixvm command completions */
-};
+} mixgtk_dispatch_data_t;
static struct mixgtk_dispatch_ dis_data_ = {NULL};
+/* local commands stuff */
+static const gchar *EDITOR_ = NULL;
+static const gchar *MIXASM_ = NULL;
+static const gchar *EDITOR_KEY_ = "Editor";
+static const gchar *MIXASM_KEY_ = "Mixasm";
+
+typedef gboolean (*local_handler_t) (mixgtk_dispatch_data_t *,
+ const gchar *);
+
+static void
+log_command_ (mixgtk_dispatch_data_t *dis, const gchar *cmd)
+{
+ gtk_text_insert (GTK_TEXT (dis->log), NULL, NULL, NULL,"MIX> ", -1);
+ gtk_text_insert (GTK_TEXT (dis->log), NULL, NULL, NULL, cmd, -1);
+ gtk_text_insert (GTK_TEXT (dis->log), NULL, NULL, NULL, "\n", -1);
+}
+
+static void
+flush_log_ (mixgtk_dispatch_data_t *dis)
+{
+ enum {BLKSIZE = 100};
+ static gchar BUFFER[BLKSIZE];
+
+ ssize_t k;
+ fflush (dis->out);
+ while ((k = read (dis->fildes[0], BUFFER, BLKSIZE)) != 0)
+ {
+ if (k == -1 && errno != EINTR) break;
+ if (k != -1)
+ gtk_text_insert (GTK_TEXT (dis->log), NULL, NULL, NULL,
+ BUFFER, k);
+ }
+}
+
+static gboolean
+exec_ (mixgtk_dispatch_data_t *dis, const gchar *cmd, const gchar *arg)
+{
+ gchar *fullcmd = NULL;
+ gboolean r = FALSE;
+ fullcmd = g_strdup_printf (cmd, arg);
+ r = !system (fullcmd);
+ flush_log_ (dis);
+ g_free (fullcmd);
+ return r;
+}
+
+static const gchar *
+get_src_file_path_ (mixgtk_dispatch_data_t *dis)
+{
+ static gchar *PATH = NULL;
+
+ const mix_vm_t *vm = mix_vm_cmd_dispatcher_get_vm (dis->dispatcher);
+ const mix_src_file_t *f = mix_vm_get_src_file (vm);
+
+ if (PATH)
+ {
+ g_free (PATH);
+ PATH = NULL;
+ }
+
+ if (f)
+ PATH = mix_file_complete_name (mix_src_file_get_path (f), MIX_SRC_DEFEXT);
+
+ return PATH;
+}
+
+static gboolean
+edit_handler_ (mixgtk_dispatch_data_t *dis, const gchar *arg)
+{
+ if (!arg) arg = get_src_file_path_ (dis);
+ if (!arg) return FALSE;
+ return exec_ (dis, EDITOR_, arg);
+}
+
+static gboolean
+compile_handler_ (mixgtk_dispatch_data_t *dis, const gchar *arg)
+{
+ if (!arg) arg = get_src_file_path_ (dis);
+ if (!arg) return FALSE;
+ return exec_ (dis, MIXASM_, arg);
+}
+
+static const gchar* local_cmds_[] = {
+ "edit", "compile"
+};
+
+static const local_handler_t handlers_[] = {
+ edit_handler_, compile_handler_
+};
+
+#define LOCAL_NO_ (sizeof (local_cmds_) / sizeof (local_cmds_[0]))
+
+static gboolean
+dispatch_local_command_ (mixgtk_dispatch_data_t *dis, const gchar *cmd)
+{
+ int k = 0;
+
+ g_return_val_if_fail (dis != NULL, FALSE);
+ g_return_val_if_fail (cmd != NULL, FALSE);
+
+ for (k = 0; k < LOCAL_NO_; ++k)
+ {
+ if (!strncmp (local_cmds_[k], cmd, strlen (local_cmds_[k])))
+ {
+ int j = 0;
+ const gchar *arg = NULL;
+ while (cmd[j] && !isspace (cmd[j])) ++j;
+ if (cmd[j]) arg = cmd + j;
+ log_command_ (dis, cmd);
+ handlers_[k](dis, arg);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
/* completions */
static void
init_completions_ (void)
@@ -59,10 +179,12 @@ init_completions_ (void)
dis_data_.completions = g_completion_new (NULL);
for (k = 0; k < MIX_CMD_INVALID; ++k)
cmds = g_list_append (cmds, (gpointer) mix_vm_command_to_string (k));
+ for (k = 0; k < sizeof (local_cmds_) / sizeof (local_cmds_[0]); ++k)
+ cmds = g_list_append (cmds, (gpointer)local_cmds_[k]);
g_completion_add_items (dis_data_.completions, cmds);
}
-/* global hooks for the command dispatcher */
+/* global hooks for the command dispatcher
static void
global_pre_hook_ (mix_vm_cmd_dispatcher_t *dis,
mix_vm_command_t cmd, const gchar *arg, gpointer data)
@@ -86,24 +208,13 @@ global_pre_hook_ (mix_vm_cmd_dispatcher_t *dis,
_("\n*** Invalid command ***\n"), -1);
}
}
+*/
static void
global_post_hook_ (mix_vm_cmd_dispatcher_t *dis,
mix_vm_command_t cmd, const gchar *arg, gpointer data)
{
- enum {BLKSIZE = 100};
- static gchar BUFFER[BLKSIZE];
-
- ssize_t k;
- fflush (dis_data_.out);
- while ((k = read (dis_data_.fildes[0], BUFFER, BLKSIZE)) != 0)
- {
- if (k == -1 && errno != EINTR) break;
- if (cmd < MIX_CMD_INVALID)
- gtk_text_insert (GTK_TEXT (dis_data_.log), NULL, NULL, NULL,
- BUFFER, k);
- }
-
+ flush_log_ ((mixgtk_dispatch_data_t *)data);
mixgtk_mixvm_update_vm_widgets ();
}
@@ -168,10 +279,9 @@ allbp_post_hook_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg,
static void
install_hooks_ (void)
{
- mix_vm_cmd_dispatcher_global_pre_hook (dis_data_.dispatcher,
- global_pre_hook_, NULL);
mix_vm_cmd_dispatcher_global_post_hook (dis_data_.dispatcher,
- global_post_hook_, NULL);
+ global_post_hook_,
+ (gpointer)(&dis_data_));
mix_vm_cmd_dispatcher_post_hook (dis_data_.dispatcher,
MIX_CMD_LOAD, load_post_hook_,
NULL);
@@ -198,6 +308,63 @@ install_hooks_ (void)
NULL);
}
+/* configuration stuff */
+static void
+read_config_ (void)
+{
+ EDITOR_ = mixgtk_config_get (EDITOR_KEY_);
+ if (!EDITOR_)
+ {
+ static const gchar *ENV[] = {"MDK_EDITOR", "X_EDITOR", NULL};
+ int k = 0;
+ while (!EDITOR_ && ENV[k]) EDITOR_ = getenv (ENV[k++]);
+ if (EDITOR_) EDITOR_ = g_strconcat (EDITOR_, " %s", NULL);
+ }
+ MIXASM_ = mixgtk_config_get (MIXASM_KEY_);
+ if (!MIXASM_) MIXASM_ = "mixasm -g %s";
+}
+
+static GtkWidget *ext_dlg_ = NULL;
+static GtkWidget *ed_entry_ = NULL;
+static GtkWidget *asm_entry_ = NULL;
+
+static const gchar *ED_NAME_ = "editor_entry";
+static const gchar *ASM_NAME_ = "mixasm_entry";
+
+void
+on_external_programs_activate ()
+{
+ if (!ext_dlg_)
+ {
+ ext_dlg_ = mixgtk_widget_factory_get_dialog (MIXGTK_EXTERNPROG_DIALOG);
+ g_return_if_fail (ext_dlg_ != NULL);
+ ed_entry_ = mixgtk_widget_factory_get_child_by_name
+ (MIXGTK_EXTERNPROG_DIALOG, ED_NAME_);
+ g_assert (ed_entry_);
+ asm_entry_ = mixgtk_widget_factory_get_child_by_name
+ (MIXGTK_EXTERNPROG_DIALOG, ASM_NAME_);
+ g_assert (asm_entry_);
+ }
+ gtk_entry_set_text (GTK_ENTRY (ed_entry_), EDITOR_);
+ gtk_entry_set_text (GTK_ENTRY (asm_entry_), MIXASM_);
+ gtk_widget_show (ext_dlg_);
+}
+
+void
+on_extern_cancel_button_clicked ()
+{
+ gtk_widget_hide (ext_dlg_);
+}
+
+void
+on_extern_ok_button_clicked ()
+{
+ EDITOR_ = gtk_entry_get_text (GTK_ENTRY (ed_entry_));
+ MIXASM_ = gtk_entry_get_text (GTK_ENTRY (asm_entry_));
+ mixgtk_config_update (EDITOR_KEY_, EDITOR_);
+ mixgtk_config_update (MIXASM_KEY_, MIXASM_);
+ gtk_widget_hide (ext_dlg_);
+}
/* initialise the command dispatcher */
gboolean
@@ -215,6 +382,10 @@ mixgtk_cmd_dispatcher_init (void)
{
int r = pipe (dis_data_.fildes);
g_return_val_if_fail (r == 0, FALSE);
+ /* connect stdout/stderr to the pipe's write end */
+ if (dup2 (dis_data_.fildes[1], STDOUT_FILENO) == -1
+ || dup2 (dis_data_.fildes[1], STDERR_FILENO) == -1)
+ return FALSE;
dis_data_.out = fdopen (dis_data_.fildes[1], "w");
g_return_val_if_fail (dis_data_.out != NULL, FALSE);
r = fcntl (dis_data_.fildes[0], F_GETFL, 0);
@@ -225,6 +396,7 @@ mixgtk_cmd_dispatcher_init (void)
dis_data_.dispatcher =
mix_vm_cmd_dispatcher_new (dis_data_.out, dis_data_.out);
mix_vm_cmd_dispatcher_print_time (dis_data_.dispatcher, FALSE);
+
install_hooks_ ();
}
@@ -238,6 +410,7 @@ mixgtk_cmd_dispatcher_init (void)
}
if (!dis_data_.completions) init_completions_ ();
+ read_config_ ();
return TRUE;
}
@@ -266,7 +439,7 @@ mixgtk_cmd_dispatcher_get_times (gint *uptime, gint *progtime, gint *laptime)
}
/* get the underlying vm */
-extern mix_vm_t *
+mix_vm_t *
mixgtk_cmd_dispatcher_get_vm (void)
{
return (mix_vm_t *) mix_vm_cmd_dispatcher_get_vm (dis_data_.dispatcher);
@@ -280,14 +453,20 @@ on_mixvm_cmd_entry_activate (GtkWidget *w, gpointer e)
GList *cmds = NULL;
gchar *prefix = NULL;
- text = gtk_entry_get_text (GTK_ENTRY (w));
+ text = g_strchomp (gtk_entry_get_text (GTK_ENTRY (w)));
- if (mix_vm_command_from_string (g_strchomp (text)) != MIX_CMD_INVALID)
+ if (mix_vm_command_from_string (text) != MIX_CMD_INVALID)
{
mix_vm_cmd_dispatcher_dispatch_text (dis_data_.dispatcher, text);
gtk_entry_set_text (GTK_ENTRY (w), "");
return;
}
+
+ if (dispatch_local_command_ (&dis_data_, text))
+ {
+ gtk_entry_set_text (GTK_ENTRY (w), "");
+ return;
+ }
cmds = g_completion_complete (dis_data_.completions, text, &prefix);
@@ -323,7 +502,10 @@ on_mixvm_cmd_entry_activate (GtkWidget *w, gpointer e)
}
else
{
+ log_command_ (&dis_data_, text);
mix_vm_cmd_dispatcher_dispatch_text (dis_data_.dispatcher, text);
gtk_entry_set_text (GTK_ENTRY (w), "");
}
}
+
+
diff --git a/mixgtk/mixgtk_mixvm.h b/mixgtk/mixgtk_mixvm.h
index 8207d91..04d210a 100644
--- a/mixgtk/mixgtk_mixvm.h
+++ b/mixgtk/mixgtk_mixvm.h
@@ -26,6 +26,7 @@
#define MIXGTK_MIXVM_H
#include <mixlib/mix_vm.h>
+#include "mixgtk.h"
/* initialise the mixvm widgets */
extern gboolean
diff --git a/mixgtk/mixgtk_widgets.c b/mixgtk/mixgtk_widgets.c
index b032898..d5ac7b1 100644
--- a/mixgtk/mixgtk_widgets.c
+++ b/mixgtk/mixgtk_widgets.c
@@ -37,7 +37,8 @@ static const gchar * dnames_[] = {
"color_dialog",
"colorsel_dialog",
"fontsel_dialog",
- "devform_dialog"
+ "devform_dialog",
+ "external_dialog"
};
#define DLG_NO_ (sizeof (dnames_) / sizeof(dnames_[0]))
diff --git a/mixgtk/mixgtk_widgets.h b/mixgtk/mixgtk_widgets.h
index 261ad12..ed7cf7e 100644
--- a/mixgtk/mixgtk_widgets.h
+++ b/mixgtk/mixgtk_widgets.h
@@ -37,7 +37,8 @@ typedef enum {
MIXGTK_COLOR_DIALOG, /* color customization dialog */
MIXGTK_COLORSEL_DIALOG, /* color selection dialog */
MIXGTK_FONTSEL_DIALOG, /* font selection dialog */
- MIXGTK_DEVFORM_DIALOG /* device format config dialog */
+ MIXGTK_DEVFORM_DIALOG, /* device format config dialog */
+ MIXGTK_EXTERNPROG_DIALOG /* external programs dialog */
} mixgtk_dialog_id_t;
/* enumeration of mixvm widget ids */