summaryrefslogtreecommitdiffhomepage
path: root/mixgtk/mixgtk_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'mixgtk/mixgtk_device.c')
-rw-r--r--mixgtk/mixgtk_device.c206
1 files changed, 197 insertions, 9 deletions
diff --git a/mixgtk/mixgtk_device.c b/mixgtk/mixgtk_device.c
index 26e48f5..b152469 100644
--- a/mixgtk/mixgtk_device.c
+++ b/mixgtk/mixgtk_device.c
@@ -23,17 +23,30 @@
#include <stdio.h>
+#include <stdlib.h>
#include <mixlib/xmix_device.h>
#include "mixgtk.h"
+#include "mixgtk_widgets.h"
+#include "mixgtk_config.h"
#include "mixgtk_device.h"
#define BIN_DEV_COL_ 5
+static const gchar *DEV_FORMAT_KEY_ = "Device.format";
+
/* device container */
static GtkNotebook *container_ = NULL;
static gint last_pos_ = 0;
/* virtual machine */
static mix_vm_t *vm_ = NULL;
+/* dec settings */
+static gint32 decs_ = 0;
+static gint32 new_decs_ = 0;
+
+/* macros manipulating dec settings */
+#define IS_DEC(flags,type) (((flags) >> (type)) & 1)
+#define SET_DEC(flags,type) ((flags) |= (1<<(type)))
+#define CLEAR_DEC(flags,type) ((flags) &= ~(1<<(type)))
/* a mixgtk device */
struct mixgtk_device_t
@@ -48,6 +61,7 @@ struct mixgtk_bin_device_t
struct mixgtk_device_t gtk_device;
guint last_insert;
GtkWidget *scroll;
+ gboolean dec;
};
/* callbacks for output devices */
@@ -72,31 +86,81 @@ write_char_ (struct mixgtk_device_t *dev, const mix_word_t *block)
}
-static void
-write_bin_ (struct mixgtk_bin_device_t *dev, const mix_word_t *block)
+static const gchar *
+get_word_string_ (mix_word_t w, gboolean dec)
{
enum {BUFF_SIZE = 17};
static gchar BUFFER[BUFF_SIZE] = { 0 };
+ if (dec)
+ snprintf (BUFFER, BUFF_SIZE, "%s%011ld",
+ mix_word_is_negative (w)? "-" : "+",
+ mix_word_magnitude (w));
+ else
+ mix_word_print_to_buffer (w, BUFFER);
+ return BUFFER;
+}
+
+static void
+write_bin_ (struct mixgtk_bin_device_t *dev, const mix_word_t *block)
+{
static gchar *DEFTEXT[BIN_DEV_COL_] = { "0", "0", "0", "0", "0" };
guint k, col, row;
+ gboolean dec = FALSE;
+
GtkCList *list = GTK_CLIST (dev->gtk_device.widget);
+ dec = IS_DEC(decs_, dev->gtk_device.device.type);
+
gtk_clist_freeze (list);
for (k = 0; k < SIZES_[dev->gtk_device.device.type]; k++)
{
- mix_word_print_to_buffer (block[k], BUFFER);
row = dev->last_insert / BIN_DEV_COL_;
col = dev->last_insert % BIN_DEV_COL_;
- if (col == 0) gtk_clist_append (list, DEFTEXT);
- gtk_clist_set_text (list, row, col, BUFFER);
+ if (col == 0)
+ {
+ int j;
+ mix_word_t *words = g_new (mix_word_t, 5);
+ gtk_clist_append (list, DEFTEXT);
+ for (j = 0; j < 5; ++j) words[j] = block[k + j];
+ gtk_clist_set_row_data_full (list, row, (gpointer)words, g_free);
+ }
+ gtk_clist_set_text (list, row, col, get_word_string_ (block[k], dec));
dev->last_insert++;
}
gtk_clist_thaw (list);
}
+static void
+redraw_bin_device_ (struct mixgtk_bin_device_t *dev)
+{
+ gint k, col, row;
+ gboolean dec = FALSE;
+ mix_word_t *words = NULL;
+ GtkCList *list;
+
+ if (!dev) return;
+
+ list = GTK_CLIST (dev->gtk_device.widget);
+ dec = IS_DEC(decs_, dev->gtk_device.device.type);
+
+ gtk_clist_freeze (list);
+
+ for (k = 0; k < dev->last_insert; ++k)
+ {
+ row = k / BIN_DEV_COL_;
+ col = k % BIN_DEV_COL_;
+ if (col == 0)
+ words = gtk_clist_get_row_data (list, row);
+ gtk_clist_set_text (list, row, col, get_word_string_ (words[col], dec));
+ }
+
+ gtk_clist_thaw (list);
+}
+
+
static gboolean
write_ (mix_device_t *dev, const mix_word_t *block)
{
@@ -254,7 +318,7 @@ mixgtk_device_init (GtkNotebook *container, mix_vm_t *vm)
};
gint k = 0;
-
+
g_return_val_if_fail (container != NULL, FALSE);
g_return_val_if_fail (vm != NULL, FALSE);
container_ = container;
@@ -265,6 +329,9 @@ mixgtk_device_init (GtkNotebook *container, mix_vm_t *vm)
mix_vm_set_device_factory (vm, mixgtk_device_new_);
+ /* read format configuration */
+ decs_ = atoi (mixgtk_config_get (DEV_FORMAT_KEY_));
+
/* connect default devices */
while (def_types[k] != mix_dev_INVALID)
{
@@ -279,6 +346,127 @@ mixgtk_device_init (GtkNotebook *container, mix_vm_t *vm)
return TRUE;
}
-/* connect a new (file-based) device */
-gboolean
-mixgtk_device_connect (mix_device_type_t type, const gchar *name);
+void
+mixgtk_device_set_format (mix_device_type_t dev, gboolean dec)
+{
+ gboolean changed;
+
+ g_return_if_fail (dev < mix_dev_INVALID);
+
+ changed = (dec && !IS_DEC (decs_, dev)) || (!dec && IS_DEC (decs_, dev));
+
+ if (changed && (MODES_[dev] == mix_dev_BIN))
+ {
+ if (dec) SET_DEC (decs_, dev);
+ else CLEAR_DEC (decs_, dev);
+ redraw_bin_device_ ((struct mixgtk_bin_device_t *)
+ mix_vm_get_device (vm_, dev));
+ }
+
+}
+
+
+/** configuration stuff */
+#define LAST_BIN_DEV_ mix_dev_DISK_7
+static GtkWidget *devdlg_ = NULL;
+static GtkWidget *dtoggle_ = NULL;
+static GtkWidget *wtoggle_ = NULL;
+static GtkWidget *combo_ = NULL;
+
+static mix_device_type_t
+get_device_idx_ (void)
+{
+ const gchar *name = gtk_entry_get_text
+ (GTK_ENTRY (GTK_COMBO (combo_)->entry));
+ /* inefficient, but the list is short */
+ int k;
+ for (k = 0; k <= LAST_BIN_DEV_; ++k)
+ if (!strcmp (name, DEF_NAMES_[k])) return k;
+ g_assert_not_reached ();
+ return 0;
+}
+
+static void
+init_devform_ (void)
+{
+ GList *names = NULL;
+ int k;
+
+ devdlg_ = mixgtk_widget_factory_get_dialog (MIXGTK_DEVFORM_DIALOG);
+ g_assert (devdlg_);
+ dtoggle_ = mixgtk_widget_factory_get_child_by_name
+ (MIXGTK_DEVFORM_DIALOG, "decradio");
+ g_assert (dtoggle_);
+ wtoggle_ = mixgtk_widget_factory_get_child_by_name
+ (MIXGTK_DEVFORM_DIALOG, "wordradio");
+ g_assert (wtoggle_);
+ combo_ = mixgtk_widget_factory_get_child_by_name
+ (MIXGTK_DEVFORM_DIALOG, "dev_combo");
+ g_assert (combo_);
+
+ for (k = 0; k <= LAST_BIN_DEV_; ++k)
+ names = g_list_append (names, (gchar *)DEF_NAMES_[k]);
+ gtk_combo_set_popdown_strings (GTK_COMBO (combo_), names);
+}
+
+void
+on_deventry_changed ()
+{
+ mix_device_type_t dev = get_device_idx_ ();
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dtoggle_),
+ IS_DEC (new_decs_, dev));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (wtoggle_),
+ !IS_DEC (new_decs_, dev));
+}
+
+void
+on_devform_activate ()
+{
+ if (!devdlg_) init_devform_ ();
+ new_decs_ = decs_;
+ gtk_widget_show (devdlg_);
+ on_deventry_changed ();
+}
+
+
+void
+on_decradio_toggled (GtkToggleButton *button)
+{
+ if (gtk_toggle_button_get_active (button))
+ SET_DEC (new_decs_, get_device_idx_ ());
+ else
+ CLEAR_DEC (new_decs_, get_device_idx_ ());
+}
+
+void
+on_devapp_button_clicked ()
+{
+ int k;
+ gchar value[20];
+ for (k = 0; k <= LAST_BIN_DEV_; ++k)
+ mixgtk_device_set_format (k, IS_DEC (new_decs_, k));
+ snprintf (value, 20, "%d", decs_);
+ mixgtk_config_update (DEV_FORMAT_KEY_, value);
+}
+
+void
+on_devok_button_clicked ()
+{
+ on_devapp_button_clicked ();
+ gtk_widget_hide (devdlg_);
+}
+
+void
+on_devcancel_button_clicked ()
+{
+ gtk_widget_hide (devdlg_);
+}
+
+void
+on_devset_button_clicked ()
+{
+ static gint32 ON = 0xffff, OFF = 0;
+ new_decs_ = (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dtoggle_)))?
+ ON : OFF;
+}
+