diff options
Diffstat (limited to 'mixgtk')
| -rw-r--r-- | mixgtk/mixgtk.glade | 10 | ||||
| -rw-r--r-- | mixgtk/mixgtk_cmd_dispatcher.c | 228 | ||||
| -rw-r--r-- | mixgtk/mixgtk_mixvm.h | 1 | ||||
| -rw-r--r-- | mixgtk/mixgtk_widgets.c | 3 | ||||
| -rw-r--r-- | mixgtk/mixgtk_widgets.h | 3 | 
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 */ | 
