⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mixgtk_mixal.c

📁 汇编语言编程源代码
💻 C
字号:
/* -*-c-*- -------------- mixgtk_mixal.c : * Implementation of the functions declared in mixgtk_mixal.h * ------------------------------------------------------------------ *  Last change: Time-stamp: "2001-04-29 22:30:43 jao" * ------------------------------------------------------------------ * 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 <string.h>#include "mixgtk_widgets.h"#include "mixgtk_config.h"#include "mixgtk_mixal.h"#define MIXAL_TAB_POS_ 2static mix_vm_t *vm_ = NULL;static GtkCList *clist_;static gulong lineno_;static const gchar *LOCAL_STATUS_BAR_ = "mixal_statusbar";static GtkStatusbar *status_;static gint status_context_;static GPtrArray *tips_text_ = NULL;static GtkWidget *symbols_dlg_ = NULL;static GtkWidget *symbols_clist_ = NULL;static const gchar *SYMBOLS_CLIST_NAME_ = "symbols_clist";static voidinit_symbols_ (void) {  symbols_dlg_ = mixgtk_widget_factory_get_dialog (MIXGTK_SYMBOLS_DIALOG);  g_assert (symbols_dlg_);  symbols_clist_ = mixgtk_widget_factory_get_child_by_name    (MIXGTK_SYMBOLS_DIALOG, SYMBOLS_CLIST_NAME_);  g_assert (symbols_clist_);  gtk_clist_set_sort_type (GTK_CLIST (symbols_clist_), GTK_SORT_ASCENDING);  gtk_clist_set_auto_sort (GTK_CLIST (symbols_clist_), TRUE);}static voidinsert_symbol_ (gpointer symbol, gpointer value, gpointer list){  enum {DEC_SIZE = 25, WORD_SIZE = 20};  static gchar DEC[DEC_SIZE], WORD[WORD_SIZE];    gchar *text[] = {(gchar *)symbol, DEC, WORD};  mix_word_t w = (mix_word_t)GPOINTER_TO_INT (value);  snprintf (DEC, DEC_SIZE, "%s%ld",	    mix_word_is_negative (w)? "-" : "+",	    mix_word_magnitude (w));  mix_word_print_to_buffer (w, WORD);  gtk_clist_append ((GtkCList *)list, text);}static voidfill_symbols_ (const mix_symbol_table_t *table){  if (symbols_clist_)    gtk_clist_clear (GTK_CLIST (symbols_clist_));  else    init_symbols_ ();    mix_symbol_table_foreach (((mix_symbol_table_t *)table),			    insert_symbol_, (gpointer)symbols_clist_);}static GdkColor colors_[3][2];static GdkColormap *colormap_ = NULL;static const char* default_colors_[3][2] = {  {"red", "black"},  {"lightgrey", "black"},  {"white", "black"}};static const char* keys_[3][2] = {  {"MIXAL.bp.color.bg", "MIXAL.bp.color.fg"},  {"MIXAL.lc.color.bg", "MIXAL.lc.color.fg"},  {"MIXAL.pl.color.bg", "MIXAL.pl.color.fg"}};static const GdkColor *parse_color_ (const gchar *str){  static GdkColor color;  if (sscanf (str, "%hd%hd%hd", &(color.red), &(color.green), &(color.blue)) < 3)    {      g_warning ("Wrong color spec: %s\n", str);      return NULL;    }    return &color;}static const gchar *color_to_string_ (const GdkColor *color){  enum {LEN = 100};  static gchar buffer[LEN];  g_snprintf (buffer, LEN, "%hd %hd %hd",	      color->red, color->green, color->blue);  return buffer;}static gbooleaninit_color_ (GdkColor *c, const gchar *name){  return (gdk_color_parse (name, c) &&	  gdk_colormap_alloc_color (colormap_, c, FALSE, TRUE));}/* initialise the mixal widgets */gbooleanmixgtk_mixal_init (mix_vm_t *vm, mixgtk_dialog_id_t top){  static gboolean restart = FALSE;  int i,j;    g_return_val_if_fail (vm != NULL, FALSE);  vm_ = vm;  clist_ = GTK_CLIST (mixgtk_widget_factory_get (top, MIXGTK_WIDGET_MIXAL));  g_return_val_if_fail (clist_ != NULL, FALSE);    if (!mixgtk_config_is_split ())    status_ = GTK_STATUSBAR      (mixgtk_widget_factory_get (MIXGTK_MAIN, MIXGTK_WIDGET_STATUSBAR));  else    status_ = GTK_STATUSBAR      (mixgtk_widget_factory_get_child_by_name (top, LOCAL_STATUS_BAR_));    g_return_val_if_fail (status_ != NULL, FALSE);  status_context_ = gtk_statusbar_get_context_id (status_, "MIXAL status");    symbols_dlg_ = symbols_clist_ = NULL;  /* allocate colors */  colormap_ = gtk_widget_get_colormap (GTK_WIDGET (clist_));  for (i = 0; i < 3; ++i)    for (j = 0; j < 2; ++j)      {	const gchar *ccol = mixgtk_config_get (keys_[i][j]);	const GdkColor *color = NULL;	if (ccol && (color = parse_color_ (ccol)))	  {	    mixgtk_mixal_set_color (i, j, color);	  }	else	  {	    g_return_val_if_fail (init_color_				  (&colors_[i][j], default_colors_[i][j]),				  FALSE);	  }      }  if (restart) mixgtk_mixal_load_file ();  else restart = TRUE;    return TRUE;}/* set the plain, location pointer and break colors */voidmixgtk_mixal_set_color (mixal_line_t line, mixal_line_zone_t zone,			const GdkColor *color){  g_return_if_fail (color != NULL);  g_return_if_fail (line <= MIXAL_LINE_PLAIN);  g_return_if_fail (zone <= MIXAL_LINE_FG);  colors_[line][zone].red = color->red;  colors_[line][zone].green = color->green;  colors_[line][zone].blue = color->blue;  gdk_colormap_alloc_color (colormap_, &colors_[line][zone], FALSE, TRUE);  mixgtk_mixal_update_bp_all ();  mixgtk_config_update (keys_[line][zone],			color_to_string_(&colors_[line][zone]));}const GdkColor *mixgtk_mixal_get_color (mixal_line_t line, mixal_line_zone_t zone){  g_return_val_if_fail (line <= MIXAL_LINE_PLAIN, FALSE);  g_return_val_if_fail (zone <= MIXAL_LINE_FG, FALSE);  return &colors_[line][zone];}/* load the corresponding mixal file */static voidupdate_tips_ (const mix_symbol_table_t *table,	      const gchar *line){  enum {SIZE = 256};  static gchar BUFFER[256];  static const gchar *DELIMITERS = " /+*=-()\t,:\n";  if (line)    {      guint k = 0;      gchar *tip = g_strdup ("");      gchar *new_tip;      gchar **tokens;      gchar *text = g_strdup (line);      text = g_strdelimit (text, DELIMITERS, ' ');      tokens = g_strsplit (g_strstrip (text), " ", -1);      while (tokens[k])	{	  if (mix_symbol_table_is_defined (table, tokens[k]))	    {	      mix_word_t val = mix_symbol_table_value (table, tokens[k]);	      snprintf (BUFFER, SIZE, "[ %s = %s%ld ]", tokens[k],			mix_word_is_negative (val)? "-" : "+",			mix_word_magnitude (val));	      new_tip = g_strconcat (tip, " ", BUFFER, NULL);	      g_free (tip);	      tip = new_tip;	    }	  ++k;	}      g_ptr_array_add (tips_text_, (gpointer)tip);      g_strfreev (tokens);      g_free (text);    }}voidmixgtk_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;      const mix_symbol_table_t *table =	mix_vm_get_symbol_table (vm_);            lineno_ = mix_src_file_get_line_no (file);      if (tips_text_) g_ptr_array_free (tips_text_, TRUE);      tips_text_ = g_ptr_array_new ();      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)));	  if (table) update_tips_ (table, line);	  	}      if (table) fill_symbols_ (table);      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 voidreset_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 ? &colors_[MIXAL_LINE_BREAK][MIXAL_LINE_BG]:			    &colors_[MIXAL_LINE_PLAIN][MIXAL_LINE_BG]);  gtk_clist_set_foreground (clist_, row,			    isset ? &colors_[MIXAL_LINE_BREAK][MIXAL_LINE_FG]:			    &colors_[MIXAL_LINE_PLAIN][MIXAL_LINE_FG]);}  static voidselect_row_ (gint row){  static gint last = -1;    gtk_clist_set_background (clist_, row, &colors_[MIXAL_LINE_LOC][MIXAL_LINE_BG]);  gtk_clist_set_foreground (clist_, row, &colors_[MIXAL_LINE_LOC][MIXAL_LINE_FG]);  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;}voidmixgtk_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 */voidmixgtk_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);}voidmixgtk_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);}voidmixgtk_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 */voidon_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)    {      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);    }}ginton_mixal_motion_notify_event (GtkWidget *list, GdkEventMotion *event,			      gpointer data){  static gint last_row = 0;  static guint last_message = 0;  gint row = last_row, col = 0;  if (gtk_clist_get_selection_info (clist_, event->x, event->y, &row, &col)      && row != last_row && tips_text_)    {      const gchar *msg = NULL;      last_row = row;      if (last_message)	gtk_statusbar_remove (status_, status_context_, last_message);      msg = (const gchar *)g_ptr_array_index (tips_text_, row);      if (msg)	last_message = gtk_statusbar_push (status_, status_context_, msg);      else	last_message = 0;     }  return FALSE;}voidon_symbol_ok_clicked (){  gtk_widget_hide (symbols_dlg_);}voidon_symbols_activate (){  if (!symbols_dlg_) init_symbols_ ();  gtk_widget_show (symbols_dlg_);}voidon_notebook_switch_page (GtkNotebook *notebook){  gint p = gtk_notebook_get_current_page (notebook);  if (p != MIXAL_TAB_POS_) gtk_statusbar_pop (status_, status_context_);  if (p == MIXAL_TAB_POS_) mixgtk_mixal_update ();}voidon_mixal_leave_notify_event (){  gtk_statusbar_pop (status_, status_context_);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -