diff options
Diffstat (limited to 'mixgtk/mixgtk_mixal.c')
-rw-r--r-- | mixgtk/mixgtk_mixal.c | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/mixgtk/mixgtk_mixal.c b/mixgtk/mixgtk_mixal.c new file mode 100644 index 0000000..b59688d --- /dev/null +++ b/mixgtk/mixgtk_mixal.c @@ -0,0 +1,213 @@ +/* -*-c-*- -------------- mixgtk_mixal.c : + * Implementation of the functions declared in mixgtk_mixal.h + * ------------------------------------------------------------------ + * Last change: Time-stamp: "01/03/12 23:48:29 jose" + * ------------------------------------------------------------------ + * Copyright (C) 2001 Free Software Foundation, Inc. + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + + +#include <stdlib.h> +#include "mixgtk_widgets.h" +#include "mixgtk_mixal.h" + + +static mix_vm_t *vm_; +static GtkCList *clist_; +static GdkColor sel_color_; +static GdkColor break_color_; +static GdkColor plain_color_; +static gulong lineno_; + +#define SEL_COLOR_ "lightgrey" +#define BREAK_COLOR_ "red" +#define PLAIN_COLOR_ "white" + +static gboolean +init_color_ (GdkColor *c, const gchar *name) +{ + static GdkColormap *cmap = NULL; + if (!cmap) cmap = gtk_widget_get_colormap (GTK_WIDGET (clist_)); + return (gdk_color_parse (name, c) && + gdk_colormap_alloc_color (cmap, c, FALSE, TRUE)); +} + +/* initialise the mixal widgets */ +gboolean +mixgtk_mixal_init (mix_vm_t *vm) +{ + g_return_val_if_fail (vm != NULL, FALSE); + vm_ = vm; + clist_ = GTK_CLIST (mixgtk_widget_factory_get (MIXGTK_WIDGET_MIXAL)); + g_return_val_if_fail (clist_ != NULL, FALSE); + + /* allocate colors */ + g_return_val_if_fail (init_color_ (&sel_color_, SEL_COLOR_), FALSE); + g_return_val_if_fail (init_color_ (&break_color_, BREAK_COLOR_), FALSE); + g_return_val_if_fail (init_color_ (&plain_color_, PLAIN_COLOR_), FALSE); + + return TRUE; +} + +/* load the corresponding mixal file */ +void +mixgtk_mixal_load_file (void) +{ + enum {ADDR_SIZE = 20, CONT_SIZE = 200}; + static gchar ADDR[ADDR_SIZE], CONT[CONT_SIZE]; + static gchar *TEXT[] = {ADDR, CONT}; + static gchar *NULL_TEXT[] = {NULL, NULL}; + + const mix_src_file_t *file; + + g_assert (vm_); + g_assert (clist_); + + gtk_clist_clear (clist_); + + file = mix_vm_get_src_file (vm_); + if (file != NULL) + { + gint k; + mix_address_t addr; + + lineno_ = mix_src_file_get_line_no (file); + + gtk_clist_freeze (clist_); + for (k = 0; k < lineno_; ++k) + { + const gchar *line = mix_src_file_get_line (file, k + 1); + snprintf (CONT, CONT_SIZE, "%03d: %s", k + 1, line); + addr = mix_vm_get_lineno_address (vm_, k + 1); + if (addr != MIX_VM_CELL_NO) + { + sprintf (ADDR, "%04d: ", mix_short_magnitude (addr)); + mix_word_print_to_buffer (mix_vm_get_addr_contents (vm_, addr), + ADDR + strlen (ADDR)); + } + else + ADDR[0] = '\0'; + gtk_clist_append (clist_, TEXT); + gtk_clist_set_row_data (clist_, k, GINT_TO_POINTER + (mix_short_magnitude (addr))); + } + gtk_clist_append (clist_, NULL_TEXT); + gtk_clist_set_row_data (clist_, k, GINT_TO_POINTER (MIX_VM_CELL_NO)); + gtk_clist_unselect_row (clist_, 0, 0); + gtk_clist_thaw (clist_); + } + else + lineno_ = 0; +} + + +/* update the widgets */ +static void +reset_bg_ (gint row) +{ + gint addr = GPOINTER_TO_INT (gtk_clist_get_row_data (clist_, row)); + gboolean isset = mix_vm_has_breakpoint_at_address (vm_, addr); + gtk_clist_set_background (clist_, row, + isset ? &break_color_ : &plain_color_); +} + +static void +select_row_ (gint row) +{ + static gint last = -1; + + gtk_clist_set_background (clist_, row, &sel_color_); + if (gtk_clist_row_is_visible (clist_, row) != GTK_VISIBILITY_FULL) + gtk_clist_moveto (clist_, row, 0, 0.25, 0); + if (last != -1 && last != row) reset_bg_ (last); + last = row; +} + +void +mixgtk_mixal_update (void) +{ + gint addr = 0; + gint k = 0; + + g_assert (vm_); + g_assert (clist_); + + addr = mix_short_magnitude (mix_vm_get_prog_count (vm_)); + k = gtk_clist_find_row_from_data (clist_, GINT_TO_POINTER (addr)); + select_row_ (k); +} + +/* breakpoints */ +void +mixgtk_mixal_update_bp_at_address (guint addr) +{ + gint k; + + g_assert (vm_); + g_assert (clist_); + + k = gtk_clist_find_row_from_data (clist_, GINT_TO_POINTER (addr)); + reset_bg_ (k); +} + +void +mixgtk_mixal_update_bp_at_line (guint line) +{ + if ( line < 1 ) return; + + while (line < lineno_) + { + gint addr = GPOINTER_TO_INT (gtk_clist_get_row_data (clist_, line - 1)); + if (addr != MIX_VM_CELL_NO) break; + ++line; + } + reset_bg_ (line - 1); +} + +void +mixgtk_mixal_update_bp_all () +{ + gint k, addr; + for (k = 0; k < lineno_; ++k) reset_bg_ (k); + addr = mix_vm_get_prog_count (vm_); + k = gtk_clist_find_row_from_data (clist_, GINT_TO_POINTER (addr)); + select_row_ (k); +} + +/* callbacks */ +void +on_mixal_select_row (GtkWidget *w, gint row, gint col, GdkEventButton *e, + gpointer data) +{ + gboolean isset; + gint addr, pc; + + gtk_clist_unselect_row (clist_, row, col); + addr = GPOINTER_TO_INT (gtk_clist_get_row_data (clist_, row)); + pc = mix_vm_get_prog_count (vm_); + if (addr < MIX_VM_CELL_NO && addr != pc) + { + isset = mix_vm_has_breakpoint_at_address (vm_, addr); + if (isset) + mix_vm_clear_breakpoint_address (vm_, addr); + else + mix_vm_set_breakpoint_address (vm_, addr); + reset_bg_ (row); + } +} + |