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

📄 mixgtk_device.c

📁 汇编语言编程源代码
💻 C
字号:
/* -*-c-*- ---------------- mixgtk_device.c : * actual types for mixgtk devices * ------------------------------------------------------------------ * $Id: mixgtk_device.c,v 1.17 2002/03/29 16:30:49 jao Exp $ * ------------------------------------------------------------------ * Copyright (C) 2001, 2002 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 <stdio.h>#include <stdlib.h>#include <string.h>#include <mixlib/mix_vm_command.h>#include <mixlib/xmix_device.h>#include "mixgtk.h"#include "mixgtk_gen_handlers.h"#include "mixgtk_widgets.h"#include "mixgtk_config.h"#include "mixgtk_cmd_dispatcher.h"#include "mixgtk_device.h"#define BIN_DEV_COL_ 5static const gchar *DEV_FORMAT_KEY_ = "Device.format";/* device container */static GtkNotebook *container_ = NULL;/* devdir dialog */static GtkWidget *devdir_dlg_ = NULL;static GtkEntry *devdir_entry_ = NULL;/** configuration stuff */#define LAST_BIN_DEV_   mix_dev_DISK_7static GtkWidget *devdlg_ = NULL;static GtkWidget *dtoggle_ = NULL;static GtkWidget *wtoggle_ = NULL;static GtkWidget *combo_ = 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{  mix_device_t device;  GtkWidget *widget;  gint pos;};struct mixgtk_bin_device_t{  struct mixgtk_device_t gtk_device;  guint last_insert;  GtkWidget *scroll;  gboolean dec;};/* callbacks for output devices */static voidwrite_char_ (struct mixgtk_device_t *dev, const mix_word_t *block){  enum {MAX_BLOCK = 16, BUFF_SIZE = MAX_BLOCK * 5 + 2};  static gchar BUFFER[BUFF_SIZE];  guint k, j;  for (k = 0; k < SIZES_[dev->device.type]; k++)    for (j = 1; j < 6; j++)      {	mix_char_t ch = mix_word_get_byte (block[k], j);	BUFFER[5 * k + j - 1] = mix_char_to_ascii (ch);      }  BUFFER[5 * k] = '\n';  BUFFER[5 * k + 1] = '\0';    gtk_text_insert (GTK_TEXT (dev->widget), NULL, NULL, NULL, BUFFER, -1);  }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 voidwrite_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++)    {      row = dev->last_insert / BIN_DEV_COL_;      col = dev->last_insert % BIN_DEV_COL_;      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 voidredraw_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 gbooleanwrite_ (mix_device_t *dev, const mix_word_t *block){  struct mixgtk_device_t *gtkdev  = (struct mixgtk_device_t *) dev;    if (dev->type != mix_dev_CONSOLE && !(DEF_DEV_VTABLE_->write)(dev, block))    return FALSE;  if (MODES_[dev->type] == mix_dev_CHAR) write_char_ (gtkdev, block);  else write_bin_ ((struct mixgtk_bin_device_t *)gtkdev, block);    gtk_notebook_set_page (container_, gtkdev->pos);  return TRUE;}static gboolean read_ (mix_device_t *dev, mix_word_t *block){  struct mixgtk_device_t *gtkdev  = (struct mixgtk_device_t *) dev;  if (dev->type != mix_dev_CONSOLE && !(DEF_DEV_VTABLE_->read)(dev, block))    return FALSE;  if (MODES_[dev->type] == mix_dev_CHAR) write_char_ (gtkdev, block);  else write_bin_ ((struct mixgtk_bin_device_t *)gtkdev, block);    gtk_notebook_set_page (container_, gtkdev->pos);  return TRUE;}static gboolean ioc_ (mix_device_t *dev, mix_short_t cmd){  return (DEF_DEV_VTABLE_->ioc)(dev, cmd);}static gbooleanbusy_ (const mix_device_t *dev) {  return (DEF_DEV_VTABLE_->busy)(dev);}static voiddestroy_ (mix_device_t *dev){  struct mixgtk_device_t *gtkdev = (struct mixgtk_device_t *)dev;  if (MODES_[dev->type] == mix_dev_BIN)    gtk_widget_destroy (((struct mixgtk_bin_device_t *)dev)->scroll);  gtk_widget_destroy (gtkdev->widget);  (DEF_DEV_VTABLE_->destroy) (dev);  gtk_notebook_remove_page (GTK_NOTEBOOK (container_), gtkdev->pos);  --last_pos_;}static mix_device_vtable_t MIXGTK_VTABLE_ = {  write_, read_, ioc_, busy_, destroy_};/* create the gui part of the device */static voidmixgtk_device_construct_gui_ (struct mixgtk_device_t *dev){  GtkWidget *label = gtk_label_new (DEF_NAMES_[dev->device.type]);  g_assert (label);  dev->pos = last_pos_++;  if (MODES_[dev->device.type] == mix_dev_CHAR)    {      GtkWidget *box = gtk_hbox_new (0, 0);      GtkWidget *scroll = NULL;      GtkAdjustment *vadj = NULL;      dev->widget = gtk_text_new (NULL, NULL);      g_assert (box);      g_assert (dev->widget);      gtk_text_set_editable (GTK_TEXT (dev->widget), FALSE);      vadj = GTK_TEXT (dev->widget)->vadj;      scroll = gtk_vscrollbar_new (vadj);      gtk_box_pack_start (GTK_BOX (box), dev->widget, TRUE, TRUE, 0);      gtk_box_pack_start (GTK_BOX (box), scroll, FALSE, FALSE, 0);      gtk_notebook_insert_page (container_, box, label, dev->pos);      gtk_widget_show (box);      gtk_widget_show (scroll);    }  else    {      gint k;      struct mixgtk_bin_device_t *bindev =	(struct mixgtk_bin_device_t *)dev;            bindev->scroll = gtk_scrolled_window_new (NULL, NULL);      g_assert (bindev->scroll);      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (bindev->scroll),				      GTK_POLICY_AUTOMATIC,				      GTK_POLICY_AUTOMATIC);      dev->widget = gtk_clist_new (BIN_DEV_COL_);      g_assert (dev->widget);      for (k =0; k < BIN_DEV_COL_; ++k)	{	  gtk_clist_set_column_width (GTK_CLIST (dev->widget), k, 120);	  gtk_clist_set_column_auto_resize (GTK_CLIST (dev->widget), k, TRUE);	}      gtk_container_add (GTK_CONTAINER (bindev->scroll), dev->widget);      gtk_notebook_insert_page (container_, bindev->scroll, label, dev->pos);      gtk_widget_show (bindev->scroll);    }    gtk_widget_show (label);  gtk_widget_set_style (dev->widget,			gtk_widget_get_style (GTK_WIDGET (container_)));  gtk_widget_show (dev->widget);  gtk_widget_draw (GTK_WIDGET (container_), NULL);}/* create a new mixgtk device */static mix_device_t *mixgtk_device_new_ (mix_device_type_t type){  struct mixgtk_device_t *dev = NULL;    g_return_val_if_fail (type < mix_dev_INVALID, NULL);  if (MODES_[type] == mix_dev_CHAR)    {      dev = g_new (struct mixgtk_device_t, 1);    }  else    {      dev = (struct mixgtk_device_t *) g_new (struct mixgtk_bin_device_t, 1);      ((struct mixgtk_bin_device_t *)dev)->last_insert = 0;    }  construct_device_ (&dev->device, type);  dev->device.vtable = &MIXGTK_VTABLE_;  mixgtk_device_construct_gui_ (dev);  return (mix_device_t *)dev;}static mix_device_t *mixgtk_device_copy_ (const struct mixgtk_device_t *from){  struct mixgtk_device_t *result =    (struct mixgtk_device_t *)mixgtk_device_new_ (from->device.type);  g_return_val_if_fail (result != NULL, NULL);  if (MODES_[from->device.type] == mix_dev_CHAR)    {      gchar *text = gtk_editable_get_chars (GTK_EDITABLE (from->widget),					    0, -1);      gtk_text_insert (GTK_TEXT (result->widget), NULL, NULL, NULL, text, -1);      g_free (text);    }  else    {      static gchar *VALS[BIN_DEV_COL_] = {""};      struct mixgtk_bin_device_t *to = (struct mixgtk_bin_device_t *) result;      struct mixgtk_bin_device_t *fr = (struct mixgtk_bin_device_t *) from;      to->last_insert = fr->last_insert;      to->dec = fr->dec;      if (to->last_insert > 0)	{	  gint k, j, rows =  to->last_insert / BIN_DEV_COL_;	  GtkCList *tl = GTK_CLIST (result->widget);	  GtkCList *fl = GTK_CLIST (from->widget);	  for (k = 0; k < rows; ++k)	    {	      mix_word_t *words = g_new (mix_word_t, BIN_DEV_COL_);	      mix_word_t *oldwords =		(mix_word_t *) gtk_clist_get_row_data (fl, k);	      for (j = 0; j < BIN_DEV_COL_; ++j) words[j] = oldwords[j];	      gtk_clist_append (tl, VALS);	      gtk_clist_set_row_data_full (tl, k, words, g_free);	    }	  redraw_bin_device_ (to);	}    }  return (mix_device_t *)result;}/* init default devices */gbooleanmixgtk_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;  vm_ = vm;  last_pos_ = 0;  devdlg_ = NULL;  devdir_dlg_ = NULL;  devdir_entry_ = NULL;  dtoggle_ = NULL;  wtoggle_ = NULL;  combo_ = NULL;  /* remove dummy page from container */  gtk_notebook_remove_page (container_, 0);  mix_vm_set_device_factory (vm, mixgtk_device_new_);    /* read format configuration */  if (mixgtk_config_get (DEV_FORMAT_KEY_))    decs_ =  atoi (mixgtk_config_get (DEV_FORMAT_KEY_));      /* re-create existing devices */  for (k = 0; k < mix_dev_INVALID; ++k)    {      mix_device_t *dev = mix_vm_get_device (vm, k);      if (dev != NULL)	{	  mix_device_t *newdev =	    mixgtk_device_copy_ ((struct mixgtk_device_t *)dev);	  mix_vm_connect_device (vm, newdev);	}    }  /* set to first page */  gtk_notebook_set_page (container_, 0);    return TRUE;}voidmixgtk_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));    }  }static mix_device_type_tget_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 voidinit_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);}voidon_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));}voidon_devform_activate (){  if (!devdlg_) init_devform_ ();  new_decs_ = decs_;  gtk_widget_show (devdlg_);  on_deventry_changed ();}voidon_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_ ());}voidon_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));  decs_ = new_decs_;  snprintf (value, 20, "%d", decs_);  mixgtk_config_update (DEV_FORMAT_KEY_, value);}voidon_devok_button_clicked (){  on_devapp_button_clicked ();  gtk_widget_hide (devdlg_);}voidon_devcancel_button_clicked (){  gtk_widget_hide (devdlg_);}voidon_devset_button_clicked (){  static gint32 ON = 0xffff, OFF = 0;  new_decs_ = (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dtoggle_)))?    ON : OFF;}voidon_devdir_activate (){  static const gchar *DEVDIR_ENTRY_NAME = "devdir_entry";  if (devdir_dlg_ == NULL)    {      devdir_dlg_ = mixgtk_widget_factory_get_dialog (MIXGTK_DEVDIR_DIALOG);      g_assert (devdir_dlg_);      devdir_entry_ = GTK_ENTRY	(mixgtk_widget_factory_get_child_by_name (MIXGTK_DEVDIR_DIALOG,						  DEVDIR_ENTRY_NAME));      g_assert (devdir_entry_);    }  gtk_entry_set_text (devdir_entry_, mix_device_get_dir ());  gtk_widget_show (devdir_dlg_);}static voiddevdir_callback (const gchar *file){  gtk_entry_set_text (devdir_entry_, file);}voidon_devdir_browse_clicked (){  mixgtk_get_file (devdir_callback, "Devices dir", mix_device_get_dir ());}voidon_devdir_cancel_clicked (){  gtk_widget_hide (devdir_dlg_);}voidon_devdir_ok_clicked (){  const gchar *dirname = gtk_entry_get_text (devdir_entry_);  gchar *cmd = g_strconcat (mix_vm_command_to_string (MIX_CMD_SDDIR),			    " ", dirname, NULL);  gtk_widget_hide (devdir_dlg_);  mixgtk_cmd_dispatcher_dispatch (cmd);  g_free (cmd);}

⌨️ 快捷键说明

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