home *** CD-ROM | disk | FTP | other *** search
- #ifdef HAVE_CONFIG_H
- # include <config.h>
- #endif
-
- #include <gtk/gtk.h>
- #include <gdk/gdkkeysyms.h>
-
- #if 0 && defined(UNDER_WIN32)
- #define WIN32_LEAN_AND_MEAN
- #include <gdk/win32/gdkwin32.h>
- #endif
-
- #include "gtkcallbacks.h"
- #include "gtkinterface.h"
- #include "gtksupport.h"
-
- #include "gtk_v99filesel.h"
-
- #include "gtkloop.h"
-
- #include "v9t9_common.h"
- #include "v9t9.h"
- #include "moduleconfig.h"
- #include "moduledb.h"
- #include "debugger.h"
- #include "dsr.h"
- #include "vdp.h"
- #include "fiad.h"
- #include "roms.h"
- #include "timer.h"
- #include "config.h"
-
- #define _L LOG_VIDEO
- #include "log.h"
-
- /*
- * Initial window size configured?
- */
- int GTK_size_configured;
-
- /*
- * Size of TI screen
- */
- int GTK_x_size, GTK_y_size;
-
- /*
- * Size of drawing area (as of last configure_event)
- * and multiple of x_size and y_size this is
- */
- int GTK_x_pixels, GTK_y_pixels, GTK_x_mult, GTK_y_mult;
- int GTK_user_size_configured;
-
- /*
- * "Pause" button
- */
- GtkButton *v9t9_window_pause_button;
-
- /*
- * Make a tag for a widget used in setting unique names
- * for repeated members of an object
- */
- static char *
- widget_tag(const char *base, int number, int mag)
- {
- static char widget_tag_buf[32];
- int len = strlen(base);
- unsigned int nyb = mag;
- memcpy(widget_tag_buf, base, len);
- while (nyb) {
- widget_tag_buf[len++] = "0123456789ABCDEF"[number & nyb];
- nyb >>= 4;
- }
- widget_tag_buf[len] = 0;
- return widget_tag_buf;
- }
-
- void
- on_v9t9_window_destroy (GtkObject *object,
- gpointer user_data)
- {
- gtk_main_quit();
- v9t9_sigterm(1);
- }
-
-
- gboolean
- on_v9t9_draw_area_configure_event (GtkWidget *widget,
- GdkEventConfigure *event,
- gpointer user_data)
- {
- /* g_print("configure_event, ev =%d,%d req=%d,%d alloc=%d,%d\n",
- event->width, event->height,
- widget->requisition.width, widget->requisition.height,
- widget->allocation.width, widget->allocation.height);*/
-
- #if defined(UNDER_WIN32)
- if (gtkVideo.runtimeflags & vmRTUnselected)
- {
- if (v9t9_drawing_area)
- {
- gtk_widget_destroy(v9t9_drawing_area);
- v9t9_drawing_area = NULL;
- }
- }
- #endif
-
- #if 0 && defined(UNDER_WIN32)
- // an attempt to make an actual window be reparented
- // inside the v9t9_drawing_area... doesn't seem to work
- {
- GdkWindow *window;
- GtkWidget *parent;
- GtkWidget *area;
- extern HWND hWndWindow;
-
- parent = v9t9_drawing_area->parent;
- window = gdk_window_foreign_new ((guint32) hWndWindow);
- gtk_widget_destroy(v9t9_drawing_area);
- v9t9_drawing_area = gtk_drawing_area_new();
- v9t9_drawing_area->window = window;
- gtk_widget_show(v9t9_drawing_area);
- // area = gtk_widget_new();
- // area->window = window;
-
- gtk_container_add(GTK_CONTAINER(parent), v9t9_drawing_area);
- }
-
- #endif
-
- GTK_x_mult = (widget->requisition.width) / GTK_x_size;
- GTK_y_mult = (widget->requisition.height) / GTK_y_size;
-
- if (!GTK_x_mult) GTK_x_mult = 1;
- if (!GTK_y_mult) GTK_y_mult = 1;
-
- if (GTK_x_size * GTK_x_mult != GTK_x_pixels ||
- GTK_y_size * GTK_y_mult != GTK_y_pixels)
- {
- GTK_x_pixels = GTK_x_size * GTK_x_mult;
- GTK_y_pixels = GTK_y_size * GTK_y_mult;
-
- vdpcompleteredraw();
- }
-
- return TRUE;
- }
-
- /*
- * Make sure the size of the widget is a multiple of 256 and 192
- */
- void
- on_v9t9_draw_area_size_request (GtkWidget *widget,
- GtkRequisition *requisition,
- gpointer user_data)
- {
- int psx, psy;
- GtkWidget *main;
-
- /* g_print("size_request, Req=%d,%d, req=%d,%d alloc=%d,%d\n",
- requisition->width, requisition->height,
- widget->requisition.width, widget->requisition.height,
- widget->allocation.width, widget->allocation.height);
-
- g_print("\tparent's parent's size is %d,%d\n",
- widget->parent->parent->allocation.width,
- widget->parent->parent->allocation.height);*/
-
- // base our size on main window size
- main = widget->parent;
- while (main && !GTK_IS_WINDOW(main)) {
- main = main->parent;
- }
-
- g_assert(main);
-
- if (!GTK_x_size) GTK_x_size = 256;
- if (!GTK_y_size) GTK_y_size = 192;
-
- if (GTK_size_configured || GTK_user_size_configured) {
-
- // did user specify the size?
- if (GTK_user_size_configured) {
- psx = GTK_x_mult * 256;
- psy = GTK_y_mult * 192;
- GTK_user_size_configured = 0;
- } else {
- // else, use parent's size
- psx = widget->allocation.width;
- psy = widget->allocation.height;
-
- // ignore smaller window size and keep existing size
- if (psx < 256 || psy < 192) {
- psx = main->allocation.width;
- psy = main->allocation.height;
- }
-
- if (psx < 256 || psy < 192) {
- psx = 256;
- psy = 192;
- }
- }
-
- } else {
-
- // if sizes not set up yet (say, by v9t9 reading -geometry),
- // take up 1/2 of the screen
-
- psx = gdk_screen_width() / 2 / GTK_x_size;
- psy = gdk_screen_height() / 2 / GTK_y_size;
-
- // fix to an aspected multiple of 256x192
- if (psx < 1) psx = 1;
- if (psy < 1) psy = 1;
- if (psx < psy) psx = psy;
- psx *= GTK_x_size;
- psy *= GTK_y_size;
- }
-
- GTK_size_configured = 1;
-
- if (psx > 16384) {
- psx = 16384;
- }
- if (psy > 16384) {
- psy = 16384;
- }
-
- // don't resize to 240 for text mode, since when the mode switches
- // back to graphics, the window will shrink to 1/2 size
- requisition->width = (psx / 256 /*GTK_x_size*/) * 256 /*GTK_x_size*/;
- if (requisition->width < 256 /*GTK_x_size*/) requisition->width = 256 /*GTK_x_size*/;
- requisition->height = (psy / GTK_y_size) * GTK_y_size;
- if (requisition->height < GTK_y_size) requisition->height = GTK_y_size;
- }
-
- #if 0 && defined(UNDER_WIN32)
- extern HWND hWndWindow;
- extern LRESULT CALLBACK WindowWndProc( HWND hWnd, UINT messg, WPARAM wParam, LPARAM lParam );
- void gtk_window_paint(RECT *updaterect);
- #endif
-
- gboolean
- on_v9t9_draw_area_expose_event (GtkWidget *widget,
- GdkEventExpose *event,
- gpointer user_data)
- {
- gint x,y,sx,sy;
- int xoffs;
-
- xoffs = (256 - GTK_x_size) * GTK_x_mult / 2;
- x = (event->area.x - xoffs);
- y = (event->area.y);
-
- sx = (event->area.width);
- sy = (event->area.height);
-
- // we can get expose events for stuff outside window
- if (x < 0) { sx += x; x = 0; }
- if (x >= GTK_x_pixels) return FALSE;
- if (y < 0) { sy += y; y = 0; }
- if (y >= GTK_y_pixels) return FALSE;
-
- if (sx + x > GTK_x_pixels) sx = GTK_x_pixels - x;
- if (sy + y > GTK_y_pixels) sy = GTK_y_pixels - y;
-
- sx = (sx + (x % GTK_x_mult) + GTK_x_mult - 1) / GTK_x_mult;
- sy = (sy + (y % GTK_y_mult) + GTK_y_mult - 1) / GTK_y_mult;
- x /= GTK_x_mult;
- y /= GTK_y_mult;
-
- logger(_L|L_2, "for expose %d,%d, dirtying (%d,%d) to (%d,%d)\n",
- GTK_x_mult, GTK_y_mult, x,y,x+sx,y+sy);
-
- #if 0 && defined(UNDER_WIN32)
- {
- RECT updaterect;
- #define AREA(x) event->area.x
- updaterect.left = AREA(x);
- updaterect.right = AREA(x) + AREA(width);
- updaterect.top = AREA(y);
- updaterect.bottom = AREA(y) + AREA(height);
-
- vdp_dirty_screen(x, y, sx, sy);
- //gtk_window_paint(&updaterect);
- //ValidateRect(hWndWindow, NULL);
- return TRUE;
- }
- #else
- GTK_clear_sides(256, GTK_x_size);
- vdp_dirty_screen(x, y, sx, sy);
-
- #endif
-
- return TRUE;
- }
-
-
- gboolean
- on_v9t9_draw_area_draw (GtkWidget *widget,
- GdkRectangle *area,
- gpointer user_data)
- {
- return FALSE;
- }
-
- /*
- * bring up command dialog on right click
- */
- gboolean
- on_v9t9_drawing_area_button_press_event
- (GtkWidget *widget,
- GdkEventButton *event,
- gpointer user_data)
- {
- // bring up v9t9 window
- if (event->button == 1) {
- gdk_window_raise(v9t9_window->window);
- }
- // raise command dialog to center on cursor
- else if (event->button > 1) {
- gdk_window_raise(command_center->window);
- gtk_widget_activate(command_center);
- gtk_widget_set_uposition(command_center,
- event->x_root - command_center->allocation.width / 2,
- event->y_root - command_center->allocation.height / 2);
- }
- return TRUE;
- }
-
-
- gboolean
- on_v9t9_key_press_event (GtkWidget *widget,
- GdkEventKey *event,
- gpointer user_data)
- {
- GTK_keyboard_set_key(event->keyval, 1);
- return TRUE;
- }
-
-
- gboolean
- on_v9t9_key_release_event (GtkWidget *widget,
- GdkEventKey *event,
- gpointer user_data)
- {
- GTK_keyboard_set_key(event->keyval, 0);
- return TRUE;
- }
-
- /*
- gboolean
- on_v9t9_draw_area_focus_out_event (GtkWidget *widget,
- GdkEventFocus *event,
- gpointer user_data)
- {
- g_print("focused out!\n");
- // gtk_window_set_focus(widget->parent->parent, widget);
- return TRUE;
- }
- */
-
- #define GTK_RESTORE_FOCUS \
- gtk_widget_grab_focus(v9t9_window);\
- gtk_window_set_focus(GTK_WINDOW(v9t9_window), v9t9_drawing_area)
-
- gboolean
- on_v9t9_window_enter_notify_event (GtkWidget *widget,
- GdkEventCrossing *event,
- gpointer user_data)
- {
- // g_print("v9t9_window_enter\n");
- GTK_RESTORE_FOCUS;
- return FALSE;
- }
-
-
- gboolean
- on_v9t9_draw_area_enter_notify_event (GtkWidget *widget,
- GdkEventCrossing *event,
- gpointer user_data)
- {
- // g_print("v9t9_drawing_area_enter\n");
- GTK_RESTORE_FOCUS;
-
- return FALSE;
- }
-
- #if 0
- #pragma mark -
- #endif
-
- /*
- * This is a callback for a generic button that has a fixed
- * command string in user_data.
- */
- void
- on_v9t9_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- GTK_send_command((const gchar *)user_data);
- }
-
- /*
- * This is for a generic cancel button which will unpause the
- * computer.
- */
- void
- on_v9t9_button_cancel (GtkButton *button,
- gpointer user_data)
- {
- if (!debugger_enabled())
- execution_pause(false);
-
- gtk_widget_destroy(GTK_WIDGET(user_data));
- }
-
-
- void
- on_v9t9_pause_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- v9t9_window_pause_button = button;
- execution_pause(!execution_paused());
- }
-
-
- void
- on_quit_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- GtkWidget *dialog = create_quit_dialog();
- gtk_widget_show(dialog);
-
- if (!debugger_enabled())
- execution_pause(true);
- }
-
- gboolean
- on_v9t9_window_configure_event (GtkWidget *widget,
- GdkEventConfigure *event,
- gpointer user_data)
- {
- // gtk_window_set_focus(GTK_WINDOW(widget), v9t9_drawing_area);
- return FALSE;
- }
-
- /***********************************/
- #if 0
- #pragma mark -
- #endif
-
- typedef struct {
- GList *lines;
- int index;
- } History;
-
- static GtkWidget *command_text_entry;
- static History *command_text_history;
-
- static History *history_get(History **where)
- {
- if (!*where) {
- *where = (History *)g_malloc(sizeof(History));
-
- (*where)->lines = g_list_alloc();
- (*where)->index = 0;
- }
- return *where;
- }
-
- static void history_append(History *history, gpointer data)
- {
- g_list_append(history->lines, data);
- history->index = g_list_length(history->lines);
- }
-
- static void history_update(History *history, gpointer data)
- {
- if (history->index == g_list_length(history->lines)) {
-
- }
- }
-
- static void history_remove(History *history)
- {
- int length = g_list_length(history->lines);
- if (length) {
- g_list_free(g_list_last(history->lines));
- history->index = MIN(history->index, length);
- }
- }
-
- static gpointer *history_prev(History *history)
- {
- if (history->index > 0) {
- history->index--;
- }
- return g_list_nth_data(history->lines, history->index);
- }
-
- static gpointer *history_next(History *history)
- {
- if (history->index + 1 < g_list_length(history->lines)) {
- history->index++;
- }
- return g_list_nth_data(history->lines, history->index);
- }
-
- /*
- * Someone has entered text in the window.
- * Need to turn on interactive mode temporarily, or
- * make the entry insensitive.
- *
- * user_data is the text box
- */
- void
- on_command_text_entry_activate (GtkEditable *editable,
- gpointer user_data)
- {
- History *history = history_get(&command_text_history);
-
- // get line of text
- gchar *text = gtk_editable_get_chars(editable, 0, -1);
-
- // execute text
- GTK_send_command(text);
-
- // append it
- history_append(history, text);
-
- // g_free(text);
-
- // select text so it can be cleared
- gtk_editable_select_region(editable, 0, -1);
- }
-
- gboolean
- on_command_text_entry_key_press_event (GtkWidget *widget,
- GdkEventKey *event,
- gpointer user_data)
- {
- gchar *text;
- History *history = history_get(&command_text_history);
- gint pos;
- GtkEditable *editable = GTK_EDITABLE(widget);
-
- // handle up and down arrow for history
- switch (event->keyval)
- {
- case GDK_Up:
- case GDK_Page_Up:
- text = gtk_editable_get_chars(editable, 0, -1);
- history_update(history, text);
- text = (gchar *)history_prev(history);
- if (text) {
- gtk_editable_delete_text(editable, 0, -1);
- pos = 0;
- gtk_editable_insert_text(editable,
- text, strlen(text),
- &pos);
- } else {
- // history_remove(history);
- }
- break;
- case GDK_Down:
- case GDK_Page_Down:
- text = gtk_editable_get_chars(editable, 0, -1);
- history_update(history, text);
- text = (gchar *)history_next(history);
- if (text) {
- gtk_editable_delete_text(editable, 0, -1);
- pos = 0;
- gtk_editable_insert_text(editable,
- text, strlen(text),
- &pos);
- } else {
- // history_remove(history);
- }
- break;
-
- // notice these keys
- case GDK_End:
- case GDK_Left:
- if (editable->has_selection) {
- text = gtk_editable_get_chars(editable, 0, -1);
- gtk_editable_select_region(editable, 0, 0);
- gtk_editable_set_position(editable, strlen(text));
- g_free(text);
- }
- break;
-
- case GDK_Home:
- case GDK_Right:
- if (editable->has_selection) {
- gtk_editable_select_region(editable, 0, 0);
- gtk_editable_set_position(editable, 0);
- }
- break;
-
-
- default:
- return TRUE;
- }
- return TRUE;
- }
-
- void
- on_log_text_box_realize_event (GtkWidget *widget,
- gpointer user_data)
- {
- v9t9_command_log = widget;
- }
-
- /*
- * Flush text in command log
- */
- void
- on_flush_item_activate (GtkMenuItem *menuitem,
- gpointer user_data)
- {
- GTK_flush_log();
- }
-
- #if 0
- #pragma mark -
- #endif
-
- /*
- * Select text font
- */
-
- static GtkWidget *font_selector;
- static gchar *last_font_selected;
-
- void
- on_font_item_activate (GtkMenuItem *menuitem,
- gpointer user_data)
- {
- if (!VALID_WINDOW(font_selector)) {
- font_selector = create_command_log_font_selector();
- } else {
- gtk_widget_hide(font_selector);
- }
-
- if (last_font_selected) {
- gtk_font_selection_dialog_set_font_name(
- GTK_FONT_SELECTION_DIALOG(font_selector),
- last_font_selected);
- }
-
- gtk_widget_show(font_selector);
- }
-
-
- void
- on_command_log_font_selector_ok_button1_clicked
- (GtkButton *button,
- gpointer user_data)
- {
- char *fontname;
-
- fontname = gtk_font_selection_dialog_get_font_name(
- GTK_FONT_SELECTION_DIALOG(font_selector));
- GTK_change_log_font(fontname);
-
- if (last_font_selected)
- g_free(last_font_selected);
-
- last_font_selected = fontname;
- gtk_widget_hide(font_selector);
- }
-
-
- void
- on_command_log_font_selector_apply_button1_clicked
- (GtkButton *button,
- gpointer user_data)
- {
- gchar *fontname;
-
- fontname = gtk_font_selection_dialog_get_font_name(
- GTK_FONT_SELECTION_DIALOG(font_selector));
- GTK_change_log_font(fontname);
-
- g_free(fontname);
- }
-
-
- void
- on_command_log_font_cancel1_button_clicked
- (GtkButton *button,
- gpointer user_data)
- {
- GTK_change_log_font(last_font_selected);
- gtk_widget_hide(font_selector);
- }
-
-
-
-
- gboolean
- on_command_text_entry_event (GtkWidget *widget,
- GdkEvent *event,
- gpointer user_data)
- {
- return FALSE;
- }
-
-
- gboolean
- on_command_dialog_key_press_event (GtkWidget *widget,
- GdkEventKey *event,
- gpointer user_data)
- {
- /* if (event->keyval == GDK_Up || event->keyval == GDK_Down) {
- gtk_signal_emit_stop_by_name(GTK_OBJECT(widget), "key_press_event");
- gtk_signal_emit_by_name(GTK_OBJECT(user_data), "key_press_event", event);
- }
- */
- return FALSE;
- }
-
-
- void
- on_command_dialog_destroy (GtkObject *object,
- gpointer user_data)
- {
- gtk_main_quit();
- v9t9_sigterm(1);
- }
-
- /***********************************************************************/
- #if 0
- #pragma mark -
- #endif
-
- /*
- * Module selection dialog
- */
-
- static GtkWidget *module_dialog;
- static GtkToggleButton *module_reset_toggle;
-
- /* These must correspond with columns in dialog */
- enum
- {
- mc_text_name,
- mc_tag_name,
- mc_setup_commands
- };
-
- static void
- module_clist_prefix_clear(GtkWidget *widget);
-
- void
- on_v9t9_window_module_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- GtkWidget *clist;
-
- if (!VALID_WINDOW(module_dialog)) {
- module_dialog = create_modules_dialog();
- module_reset_toggle = 0L;
- } else {
- gtk_widget_hide(module_dialog);
- }
-
- clist = gtk_object_get_data((GtkObject *)module_dialog, "module_clist");
- if (clist) module_clist_prefix_clear(clist);
- gtk_widget_show(module_dialog);
- }
-
- void
- on_module_clist_load_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- GtkCList *clist;
- GList *list;
-
- g_return_if_fail(GTK_IS_CLIST(clist = user_data));
-
- // Step through list of selected modules
- // and load them up
- list = clist->selection;
-
- while (list)
- {
- gint row = (gint)(list->data);
- ModuleEntry *ent = (ModuleEntry *)gtk_clist_get_row_data(clist, row);
-
- if (ent) module_load(ent);
- list = list->next;
- }
-
- if (clist->selection
- && (!module_reset_toggle ||
- gtk_toggle_button_get_active(module_reset_toggle)))
- {
- GTK_send_command("ResetComputer\n");
- }
-
- // Unselect items
- gtk_clist_unselect_all(clist);
-
- GTK_RESTORE_FOCUS;
- }
-
-
- void
- on_module_clist_close_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- GtkCList *clist;
- g_return_if_fail(GTK_IS_CLIST(clist = user_data));
-
- // Unselect items
- gtk_clist_unselect_all(clist);
-
- gtk_widget_hide(module_dialog);
- // module_reset_toggle = 0L;
- // module_dialog = 0L;
-
- GTK_RESTORE_FOCUS;
- }
-
- #define ALT_KEY(x) \
- ((x) == GDK_Meta_L ||\
- (x) == GDK_Meta_R ||\
- (x) == GDK_Alt_L ||\
- (x) == GDK_Alt_R)
-
- /*
- * Don't intercept ALT-key shortcuts
- */
- gboolean
- on_clist_key_release_event (GtkWidget *widget,
- GdkEventKey *event,
- gpointer user_data)
- {
- if (ALT_KEY(event->keyval)) {
- gtk_object_set_data(GTK_OBJECT(widget), "alt_down", (gpointer)0);
- }
- return FALSE;
- }
-
- /*
- * Key was pressed in (module) clist.
- *
- * Create a prefix string from the keys pressed and find
- * a suitable match in the given column in (int)user_data.
- */
- gboolean
- on_clist_key_press_event (GtkWidget *widget,
- GdkEventKey *event,
- gpointer user_data)
- {
- GtkCList *clist;
- gchar *old;
- char *prefix_name;
- gchar *prefix;
- int row;
- int col = (int)user_data;
- GList *list;
- int current;
- gboolean matched;
-
- g_return_val_if_fail(GTK_IS_CLIST(widget), false);
-
- clist = GTK_CLIST(widget);
-
- prefix_name = widget_tag("prefix_string_", col, 1);
- old = gtk_object_get_data(GTK_OBJECT(widget), prefix_name);
-
- /*
- * Don't intercept ALT keys
- */
- if (ALT_KEY(event->keyval))
- {
- gtk_object_set_data(GTK_OBJECT(widget), "alt_down", (gpointer)1);
- return false;
- }
-
- if ((int)gtk_object_get_data(GTK_OBJECT(widget), "alt_down"))
- {
- return false;
- }
-
- /*
- * Ignore accelerator keys
- */
- if (event->keyval == GDK_Escape)
- {
- return false;
- }
-
- /*
- * Start off with some old prefix value to compare against
- */
- if (!old)
- old = g_strdup("");
-
- /*
- * Don't append non-printable characters, which we assume
- * are control characters intended to clear the prefix.
- */
- if (event->string && *event->string && isprint(*event->string))
- {
- prefix = g_strconcat(old, event->string, 0L);
- }
- else
- {
- gtk_clist_unselect_all(clist);
- prefix = g_strdup("");
- }
-
- /* find current selection */
- list = clist->selection;
-
- /* find item with this prefix */
- current = (list ? (gint)list->data : -1);
- matched = false;
-
- // g_print("prefix='%s', current=%d\n", prefix, current);
-
- if (*prefix)
- for (row = 0; row < clist->rows; row++) {
- gchar *text;
- if (gtk_clist_get_text(clist, row, col, &text)
- && strncasecmp(text, prefix, strlen(prefix)) == 0) {
- current = row;
- matched = true;
- break;
- }
- }
-
- // g_print("old='%s', event='%s'\n", old, event->string);
-
- /* if we couldn't find one with new prefix,
- and this new key is a suffix of the last
- prefix, look for another one matching... */
-
- if (!matched
- && event->string && *event->string
- && strcasecmp(old + strlen(old) - strlen(event->string),
- event->string) == 0)
- {
- if (list) {
- current = (gint)list->data;
- if (current < 0 || current >= clist->rows)
- current = 0;
- }
- else
- current = 0;
-
- // g_print("current=%d, list->data=%d\n", current, list->data);
- g_free(prefix);
- prefix = g_strdup(old);
-
- for (row = current + 1; row != current;
- row = (row + 1 >= clist->rows ? 0 : row + 1)) {
- gchar *text;
- if (gtk_clist_get_text(clist, row, col, &text)
- && strncasecmp(text, prefix, strlen(prefix)) == 0) {
- current = row;
- matched = true;
- break;
- }
- }
- }
-
- gtk_object_set_data(GTK_OBJECT(widget), prefix_name, prefix);
-
- if (matched && current != -1) {
- gtk_clist_undo_selection(clist);
- clist->focus_row = current;
- gtk_clist_select_row(clist, current, 0 /*col*/);
- gtk_clist_moveto(clist, current, 0 /*col*/, 0.5, 0.5);
- } else if (!matched) {
- gtk_clist_undo_selection(clist);
- }
-
- g_free(old);
- return TRUE;
- }
-
- static void
- module_clist_prefix_clear(GtkWidget *widget)
- {
- gchar *prefix;
- int i;
- for (i=0; i < 2; i++) {
- char *name = widget_tag("prefix_string_", i, 1);
- prefix = (gchar *)gtk_object_get_data(GTK_OBJECT(widget), name);
- if (prefix) g_free(prefix);
- gtk_object_set_data(GTK_OBJECT(widget), name, 0L);
- }
- }
-
- gboolean
- on_module_clist_event (GtkWidget *widget,
- GdkEvent *event,
- gpointer user_data)
- {
- if ((event->type == GDK_KEY_PRESS
- && event->key.keyval == GDK_Return) ||
- event->type == GDK_2BUTTON_PRESS)
- {
- on_module_clist_load_button_clicked(NULL, user_data);
-
- gtk_widget_hide(module_dialog);
-
- GTK_RESTORE_FOCUS;
- }
- return FALSE;
- }
-
- /* Create clist from module database */
- void
- on_module_clist_realize (GtkWidget *widget,
- gpointer user_data)
- {
- ModuleEntry *ent;
- GtkCList *clist = GTK_CLIST(widget);
- int old_selection;
-
- old_selection = (clist->selection ? (gint)clist->selection->data : 0);
-
- // Clear clist
- gtk_clist_clear(clist);
-
- // Freeze display
- gtk_clist_freeze(clist);
-
- // Add an entry for each item
- ent = moddb;
- while (ent)
- {
- gchar *items[3];
- gint row;
-
- items[0] = ent->name;
- items[1] = ent->tag;
- items[2] = ent->commands;
-
- // add row
- row = gtk_clist_append(clist, items);
-
- // associate row with ModuleEntry
- gtk_clist_set_row_data(clist, row, ent);
-
- ent = ent->next;
- }
-
- // Unfreeze
- gtk_clist_thaw(clist);
-
- // Reselect old selection
- gtk_clist_select_row(clist, old_selection, 0 /*col*/);
- gtk_clist_moveto(clist, old_selection, 0 /*col*/, 0.5, 0.5);
-
- gtk_clist_set_column_max_width(clist, mc_tag_name, 50);
- }
-
- void
- on_module_clist_click_column (GtkCList *clist,
- gint column,
- gpointer user_data)
- {
- gboolean swap = (clist->sort_column == column);
- GtkSortType sort = swap
- ? (clist->sort_type == GTK_SORT_ASCENDING ?
- GTK_SORT_DESCENDING :
- GTK_SORT_ASCENDING)
- : GTK_SORT_ASCENDING;
-
- gtk_clist_set_sort_column(clist, column);
- gtk_clist_set_sort_type(clist, sort);
- gtk_clist_sort(clist);
- module_clist_prefix_clear(GTK_WIDGET(clist));
- }
-
- /*
- * Toggled "show setup commands" button
- */
- void
- on_show_commands_cb_toggled (GtkToggleButton *togglebutton,
- gpointer user_data)
- {
- GtkCList *clist;
- g_return_if_fail(GTK_IS_CLIST(clist = user_data));
-
- gtk_clist_set_column_visibility(clist, mc_setup_commands,
- gtk_toggle_button_get_active(togglebutton));
- gtk_clist_set_column_max_width(clist, mc_tag_name, 50);
- }
-
- /*
- * Toggled "reset computer after load" button
- */
- void
- on_reset_computer_cb_toggled (GtkToggleButton *togglebutton,
- gpointer user_data)
- {
- module_reset_toggle = togglebutton;
- }
-
-
- void
- on_modules_refresh_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- g_return_if_fail(GTK_IS_CLIST(user_data));
- GTK_send_command("InitModuleDatabase\n"
- "LoadConfigFile \"modules.inf\"\n");
- module_clist_prefix_clear(GTK_WIDGET(user_data));
- on_module_clist_realize(GTK_WIDGET(user_data), 0L);
- }
-
- void
- on_unload_current_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- GTK_send_command("UnloadModuleOnly\n");
- }
-
-
-
- /******************************************************************/
- #if 0
- #pragma mark -
- #endif
-
- /*
- * Disk selection dialog
- */
-
- static GtkWidget *disk_dialog;
- static GtkTable *disk_dialog_table;
-
- enum
- {
- ddt_disk_name,
- ddt_combo_history,
- ddt_choose_button
- };
-
- void
- on_v9t9_window_disks_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- if (!VALID_WINDOW(disk_dialog)) {
- disk_dialog = create_disks_dialog();
- } else {
- gtk_widget_hide(disk_dialog);
- }
- gtk_widget_show(disk_dialog);
- }
-
- /*
- * Clicked 'apply' button on dialog
- */
- void
- on_disk_dialog_apply_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- GTK_RESTORE_FOCUS;
- }
-
- /*
- * Clicked 'close' button on dialog
- */
- void
- on_disk_dialog_close_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- gtk_widget_hide(disk_dialog);
- // disk_dialog = 0L;
- // disk_dialog_table = 0L;
-
- GTK_RESTORE_FOCUS;
- }
-
- /*
- * Setup disk table. Format is:
- * column 0: label DSKx
- * column 1: combo box, history of names used [not implemented]
- * column 2: 'choose' button, which triggers on_disk_choose_button_clicked(row)
- */
-
- /*
- * Icky! No accessor functions.
- */
- static GtkWidget *table_get_widget(GtkTable *table, gint row, gint column)
- {
- GList *list;
-
- for (list = table->children; list; list = list->next) {
- GtkTableChild *child;
-
- child = (GtkTableChild *)list->data;
- if (child->top_attach == row && child->left_attach == column)
- return child->widget;
- }
- return 0L;
- }
-
- void
- on_disk_info_table_realize (GtkWidget *widget,
- gpointer user_data)
- {
- gint row;
- GtkTable *table;
- GtkWidget *kid;
-
- g_return_if_fail(GTK_IS_TABLE(table = GTK_TABLE(widget)));
-
- disk_dialog_table = table;
-
- for (row = 0; row < dsr_get_disk_count(); row++) {
- GtkWidget *label, *combo, *choose;
- const char *path;
-
- label = table_get_widget(table, row, ddt_disk_name);
- combo = table_get_widget(table, row, ddt_combo_history);
- choose = table_get_widget(table, row, ddt_choose_button);
-
- // enable widgets for disks we can use
- gtk_widget_set_sensitive(label, TRUE);
- gtk_widget_set_sensitive(combo, TRUE);
- gtk_widget_set_sensitive(choose, TRUE);
-
- path = dsr_get_disk_info(row + 1);
- // gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), path ? path : "");
- gtk_entry_set_text(GTK_ENTRY(combo), path ? path : "");
- }
-
- // Disable inaccessible kids
- for (; row < 5; row++) {
- int col;
- for (col = 0; col < 3; col++) {
- kid = table_get_widget(table, row, col);
- gtk_widget_set_sensitive(kid, FALSE);
- }
- }
- }
-
- /*
- * Canonicalize a path to either a directory or a filename
- */
- static gchar *disk_file_canonicalize(gchar **searchpath, gchar *syssearchpath,
- gboolean dir, const char *path,
- OSSpec *spec, gboolean add_dir)
- {
- char *fptr;
- gchar *copy;
-
- fptr = (char *)OS_GetFileNamePtr(path);
- if (dir) {
- // don't accept a file as a directory
- if (OS_MakeFileSpec(path, spec) == OS_NOERR &&
- OS_Status(spec) == OS_NOERR) {
- *fptr = 0;
- }
- if (OS_MakeSpec(path, spec, NULL) == OS_NOERR) {
- copy = g_strdup(OS_PathSpecToString1(&spec->path));
- } else {
- copy = g_strdup(path);
- }
- } else {
- // find file in the path, or add it.
- if (!findbinary(*searchpath, syssearchpath, fptr, spec)) {
- if (add_dir && *fptr) {
- char *list = (char *)xmalloc((*searchpath ? strlen(*searchpath) : 0)
- + (fptr - path) + 1 + 1);
- sprintf(list, "%s%c%.*s", *searchpath ? *searchpath : "", OS_ENVSEP, fptr - path, path);
- xfree(*searchpath);
- *searchpath = list;
- }
- copy = g_strdup(fptr);
- } else {
- copy = g_strdup(OS_NameSpecToString1(&spec->name));
- }
- }
-
- return copy;
- }
-
-
- #if 0
- // um, this combo crap really doesn't make sense...
-
- /*
- * Text in combo box changed for disk in user_data (1..x)
- */
- void
- on_disk_combo_entry_activate (GtkEditable *editable,
- gpointer user_data)
- {
- char msg[256];
- GtkCombo *combo;
- gint disk;
- gchar *path;
- gchar *canon;
-
- g_return_if_fail(GTK_IS_COMBO(combo = GTK_COMBO(GTK_WIDGET(editable)->parent)));
-
- disk = (gint)user_data;
- path = gtk_editable_get_chars(editable, 0, -1);
-
- snprintf(msg, sizeof(msg), "Changing DSK%d to '%s'\n", disk, path);
- GTK_append_log(msg, NULL, NULL);
-
- // if not an error, add to history
- if (dsr_set_disk_info(disk, path) && (canon = dsr_get_disk_info(disk))) {
- GtkList *strings = GTK_LIST(combo->list);
- GList *items;
- GtkWidget *item;
-
- gint pos;
-
- gtk_editable_delete_text(editable, 0, -1);
- pos = 0;
- gtk_editable_insert_text(editable, canon, strlen(canon), &pos);
-
- items = g_list_alloc();
- g_list_append(items, (gpointer)editable);
- gtk_list_prepend_items(strings, items);
-
- // ???
- // gtk_combo_set_popdown_strings(combo, strings);
- // combo->list = strings;
- }
-
- g_free(path);
- }
- #endif
-
- /*
- * Text in combo box changed for disk in user_data (1..x)
- */
- void
- on_disk_combo_entry_activate (GtkEditable *editable,
- gpointer user_data)
- {
- char msg[256];
- gint disk;
- char *path;
- gchar *copy;
- OSSpec spec;
-
- disk = (gint)user_data;
- path = gtk_editable_get_chars(editable, 0, -1);
-
- copy = disk_file_canonicalize(&diskimagepath, 0L,
- dsr_is_emu_disk(disk), path, &spec, true /*add_dir*/);
-
- snprintf(msg, sizeof(msg), "Changing DSK%d to '%s'\n", disk, copy);
- GTK_append_log(msg, NULL, NULL);
-
- dsr_set_disk_info(disk, copy);
-
- g_free(path);
- g_free(copy);
- }
-
-
- static GtkWidget*
- create_disk_file_selection (gchar *title)
- {
- GtkWidget *disk_file_selection;
- GtkWidget *ok_button2;
- GtkWidget *cancel_button2;
-
- disk_file_selection = v99_file_selection_new (title);
- // gtk_object_set_data (GTK_OBJECT (disk_file_selection), "disk_file_selection", disk_file_selection);
- gtk_container_set_border_width (GTK_CONTAINER (disk_file_selection), 10);
-
- ok_button2 = V99_FILE_SELECTION (disk_file_selection)->ok_button;
- gtk_object_set_data (GTK_OBJECT (disk_file_selection), "ok_button2", ok_button2);
- gtk_widget_show (ok_button2);
- GTK_WIDGET_SET_FLAGS (ok_button2, GTK_CAN_DEFAULT);
-
- cancel_button2 = V99_FILE_SELECTION (disk_file_selection)->cancel_button;
- gtk_object_set_data (GTK_OBJECT (disk_file_selection), "cancel_button2", cancel_button2);
- gtk_widget_show (cancel_button2);
- GTK_WIDGET_SET_FLAGS (cancel_button2, GTK_CAN_DEFAULT);
-
- return disk_file_selection;
- }
-
- #if 0
- #pragma mark -
- #endif
-
- /*
- * Choose a disk or directory for the disk in user_data (1..x)
- */
-
- V99FileSelection *disk_file_dialog; // V99FileDialog
-
- static void
- GTK_info_logger(u32 srcflags, const char *format, ...)
- {
- va_list va;
- if (srcflags & (LOG_ERROR|LOG_WARN))
- return;
- if (srcflags & LOG_VERBOSE_MASK)
- return;
-
- va_start(va, format);
- vlogger(srcflags, format, va);
- va_end(va);
- }
-
-
- /*
- * Given a filename, append a row to the clist with info
- * about the V9t9 file (if it is one)
- */
- static const char *
- emu_disk_clist_titles[] =
- { "Name", "Size", "Type", "P", "Host filename" };
-
- #if __MWERKS__
- // Support for the runtime initialization of local arrays
- #pragma gcc_extensions on
- #endif
-
- static int
- on_v99_file_selection_file_append(V99FileSelection *filesel,
- GtkCList *clist,
- const gchar *path,
- const gchar *filename)
- {
- char tiname[11];
- char size[8];
- char type[12];
- char protect[2];
- gchar *cols[6] = { tiname, size, type, protect, (gchar *)filename, NULL };
- int charwidth = gdk_string_width(filesel->file_list->style->font, "M");
- int widths[5]= { charwidth*10, charwidth*3, charwidth*10, charwidth*1, charwidth*16 };
- int col;
- fiad_tifile tf;
- OSSpec spec;
- fiad_logger_func old;
-
- /* Try to make a tifile from the entry */
- if (OS_MakeSpec2(path, filename, &spec) != OS_NOERR) {
- /* oops, not even a good file (maybe broken softlink) */
- return 0;
- }
-
- /* Don't log errors found in likely-non-V9t9 files,
- but log renames */
- old = fiad_set_logger(GTK_info_logger);
-
- if (fiad_tifile_setup_spec_with_spec(&tf, &spec) == OS_NOERR &&
- fiad_tifile_get_info(&tf))
- {
- /* it might have just been renamed */
- cols[4] = OS_NameSpecToString1(&tf.spec.name);
-
- memcpy(tiname, tf.fdr.filenam, 10);
- tiname[10] = 0;
- sprintf(size, "%d", tf.fdr.secsused + 1);
- strcpy(type, fiad_catalog_get_file_type_string(&tf.fdr));
- protect[0] = (tf.fdr.flags & ff_protected) ? 'Y' : ' ';
- protect[1] = 0;
-
- }
- else /* not a V9t9 file */
- {
- *tiname = 0;
- *size = 0;
- *protect = 0;
- *type = 0;
- }
-
- /* figure widths for each column */
- for (col = 0; col < 5; col++) {
- int width = gdk_string_width(filesel->file_list->style->font, cols[col]);
- if (width > widths[col]) {
- widths[col] = width;
- }
- gtk_clist_set_column_width(clist, col, widths[col]);
- }
-
- return gtk_clist_append(clist, cols);
- }
-
- #if __MWERKS__
- #pragma gcc_extensions reset
- #endif
-
- static void
- on_v99_file_selection_file_click_column(GtkCList *clist,
- gint column,
- gpointer user_data)
- {
- gboolean swap = (clist->sort_column == column);
- GtkSortType sort = swap
- ? (clist->sort_type == GTK_SORT_ASCENDING ?
- GTK_SORT_DESCENDING :
- GTK_SORT_ASCENDING)
- : GTK_SORT_ASCENDING;
-
- gtk_clist_set_sort_column(clist, column);
- gtk_clist_set_sort_type(clist, sort);
- gtk_clist_sort(clist);
- }
-
- /*
- * user_data is the disk number
- */
- void
- on_disk_file_ok_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- gint disk = (gint)user_data;
- gboolean dir = dsr_is_emu_disk(disk);
- const char *path;
- gchar *copy;
- OSSpec spec;
-
- g_return_if_fail(disk >= 1 && disk <= 5);
-
- path = v99_file_selection_get_filename(disk_file_dialog);
- copy = disk_file_canonicalize(&diskimagepath, 0L,
- dir, path, &spec, true /*add_dir*/);
-
- if (dsr_set_disk_info(disk, copy)) {
- GtkWidget *entry = table_get_widget(disk_dialog_table, disk-1, ddt_combo_history);
-
- gtk_entry_set_text(GTK_ENTRY(entry), copy);
- gtk_widget_hide((GtkWidget *)disk_file_dialog);
- // disk_file_dialog = 0L;
-
- GTK_RESTORE_FOCUS;
- }
-
- g_free(copy);
- //g_free(path);
- }
-
-
- void
- on_disk_file_cancel_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- gtk_widget_hide((GtkWidget *)disk_file_dialog);
- GTK_RESTORE_FOCUS;
- }
-
- /*
- * Main disk/file chooser dialog.
- *
- */
- void
- on_disk_choose_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- gint disk = (gint)user_data;
-
- g_return_if_fail(disk >= 1 && disk <= 5);
-
- if (!VALID_WINDOW(disk_file_dialog)) {
- disk_file_dialog = V99_FILE_SELECTION(create_disk_file_selection("Select Path"));
- if (dsr_is_real_disk(disk)) {
- // normal file selection
- v99_file_selection_set_file_list_active(disk_file_dialog,
- TRUE);
- } else {
- // v9t9 directory selection
- v99_file_selection_set_file_list_columns(disk_file_dialog,
- 5,
- (gchar **)emu_disk_clist_titles,
- on_v99_file_selection_file_append,
- NULL);
- gtk_signal_connect(GTK_OBJECT(disk_file_dialog->file_list),
- "click_column",
- on_v99_file_selection_file_click_column,
- NULL);
-
- // no, we can't select files as directories
- v99_file_selection_set_file_list_active(disk_file_dialog,
- FALSE);
- disk_file_dialog->user_data = (gpointer)(disk - 1);
- }
- }
-
- gtk_widget_show(GTK_WIDGET(disk_file_dialog));
-
- if (dsr_is_real_disk(disk)) {
- // OSError err;
- OSSpec spec;
- const char *filename;
- gchar *copy;
-
- // Set the full path if we can
- filename = dsr_get_disk_info(disk);
- copy = disk_file_canonicalize(&diskimagepath, 0L,
- false /*directory*/, filename, &spec,
- false /*add_dir*/);
-
- v99_file_selection_set_filename(disk_file_dialog,
- OS_SpecToString1(&spec));
- v99_file_selection_complete(disk_file_dialog,
- "*.dsk");
-
- g_free(copy);
- } else {
- // it's already a full path
- char path[OS_PATHSIZE];
- strcpy(path, dsr_get_disk_info(disk));
- #if !defined(UNDER_MACOS)
- // force a directory selection so ppl don't think they can
- // type a filename
- strcat(path, ".");
- #endif
- v99_file_selection_set_filename(disk_file_dialog,
- path);
-
- }
-
- // wire up buttons here (so we can pass known disk number)
- gtk_signal_connect(GTK_OBJECT(disk_file_dialog->ok_button),
- "clicked",
- GTK_SIGNAL_FUNC(on_disk_file_ok_button_clicked),
- (gpointer)disk);
- gtk_signal_connect(GTK_OBJECT(disk_file_dialog->cancel_button),
- "clicked",
- GTK_SIGNAL_FUNC(on_disk_file_cancel_button_clicked),
- (gpointer)disk);
- }
-
- /*
- * Toggle use of realdisk DSR
- */
-
- void
- on_real_disk_cb_toggled (GtkToggleButton *togglebutton,
- gpointer user_data)
- {
- char cmd[64];
- sprintf(cmd, "ToggleV9t9 dsrRealDisk %s",
- gtk_toggle_button_get_active(togglebutton) ? "on" : "off");
- GTK_send_command(cmd);
- gtk_signal_emit_by_name(GTK_OBJECT(user_data), "realize");
- }
-
-
- void
- on_real_disk_cb_realize (GtkWidget *widget,
- gpointer user_data)
- {
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
- !!(realDiskDSR.runtimeflags & vmRTInUse));
- gtk_signal_emit_by_name(GTK_OBJECT(user_data), "realize");
- }
-
- /*
- * Toggle use of emulated disk DSR
- */
-
- void
- on_emu_disk_cb_toggled (GtkToggleButton *togglebutton,
- gpointer user_data)
- {
- char cmd[64];
- sprintf(cmd, "ToggleV9t9 dsrEmuDisk %s",
- gtk_toggle_button_get_active(togglebutton) ? "on" : "off");
- GTK_send_command(cmd);
- gtk_signal_emit_by_name(GTK_OBJECT(user_data), "realize");
- }
-
-
- void
- on_emu_disk_cb_realize (GtkWidget *widget,
- gpointer user_data)
- {
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
- !!(emuDiskDSR.runtimeflags & vmRTInUse));
- gtk_signal_emit_by_name(GTK_OBJECT(user_data), "realize");
- }
-
- #if 0
- #pragma mark -
- #endif
-
- static GtkWidget *debugger_window;
- GtkWidget *debugger_registers_table,
- *debugger_instruction_box,
- *debugger_status_bar,
- *debugger_pc_entry,
- *debugger_wp_entry,
- *debugger_st_entry;
-
- // flag indicating we want to display all the time-wasting
- // updates (turned on/off during intermittent mode, etc)
- static bool debugger_verbose_updates;
-
- #define DBG_COLOR_NORMAL(s) (&(s)->fg[0])
- #define DBG_COLOR_VIEW(s) (&(s)->fg[0])
- #define DBG_COLOR_READ(s) (&(s)->mid[0])
- #define DBG_COLOR_WRITTEN(s) (&(s)->dark[0])
-
- static GdkColor *
- debugger_status_color_fg(status_item item, GtkStyle *style)
- {
- switch (item)
- {
- case STATUS_CPU_PC: return DBG_COLOR_NORMAL(style);
- case STATUS_CPU_STATUS: return DBG_COLOR_NORMAL(style);
- case STATUS_CPU_WP: return DBG_COLOR_NORMAL(style);
- case STATUS_CPU_REGISTER_VIEW: return DBG_COLOR_VIEW(style);
- case STATUS_CPU_REGISTER_READ: return DBG_COLOR_READ(style);
- case STATUS_CPU_REGISTER_WRITE: return DBG_COLOR_WRITTEN(style);
- case STATUS_CPU_INSTRUCTION: return DBG_COLOR_NORMAL(style);
- case STATUS_CPU_INSTRUCTION_LAST: return DBG_COLOR_WRITTEN(style);
- case STATUS_MEMORY_VIEW: return DBG_COLOR_VIEW(style);
- case STATUS_MEMORY_READ: return DBG_COLOR_READ(style);
- case STATUS_MEMORY_WRITE: return DBG_COLOR_WRITTEN(style);
- }
- return DBG_COLOR_NORMAL(style);
- }
-
- static GdkColor*
- debugger_status_color_bg(status_item item, GtkStyle *style)
- {
- // return &style->bg[0];
- return 0L;
- }
-
- /*
- * Set up registers table for the first time
- */
- static void
- setup_debugger_registers_table(void)
- {
- int reg;
- GtkWidget *w;
- GtkTable *t;
- GtkStyle *s;
- int width, height;
-
- g_return_if_fail(debugger_registers_table);
-
- t = GTK_TABLE(debugger_registers_table);
-
- s = gtk_widget_get_style(debugger_registers_table);
-
- // setup base size of text box
- width = gdk_string_width(s->font, "_>FFFF_");
- height = gdk_string_height(s->font, "!")*2;
-
- // gtk_style_unref(s);
-
- // fix the items below the register table here...
- gtk_widget_set_usize(debugger_pc_entry, width, height);
- gtk_widget_set_usize(debugger_wp_entry, width, height);
- gtk_widget_set_usize(debugger_st_entry, width, height);
-
- // resize
- gtk_table_resize(t, 16 /*rows*/, 2 /*columns*/);
-
- // set up each register row
- for (reg = 0; reg < 16; reg++) {
- // assign label...
- char tmp[32];
- sprintf(tmp, "R%d", reg);
- w = gtk_label_new(tmp);
- gtk_widget_ref(w);
- gtk_object_set_data_full(GTK_OBJECT(debugger_window),
- widget_tag("register_label_", reg, 1),
- w, (GtkDestroyNotify) gtk_widget_unref);
- gtk_widget_show(w);
- gtk_table_attach(t, w, 0, 1, reg, reg+1,
- (GtkAttachOptions) (0),
- (GtkAttachOptions) (0), 2, 0);
-
- // assign text entry to register
-
- w = gtk_text_new (NULL, NULL);
- gtk_widget_ref(w);
- gtk_text_set_editable (GTK_TEXT(w), false);
-
- // force size
- gtk_widget_set_usize(w, width, height);
-
- gtk_object_set_data_full(GTK_OBJECT(debugger_window),
- widget_tag("reg_value_", reg, 1),
- w, (GtkDestroyNotify) gtk_widget_unref);
- gtk_table_attach(t, w, 1, 2, reg, reg+1,
- (GtkAttachOptions) (0),
- (GtkAttachOptions) (0), 2, 0);
-
- gtk_widget_show(w);
- }
- }
-
- static void
- update_debugger_register(status_item item, int reg, int val)
- {
- GtkTable *t = GTK_TABLE(debugger_registers_table);
- GtkText *tb;
- GtkWidget *w;
- GtkStyle *style;
- char buffer[8];
-
- // get value widget
- w = table_get_widget(t, reg, 1);
-
- if (!VALID_WINDOW(w))
- return;
-
- // get style
- style = gtk_widget_get_style(w);
-
- // freeze entry
- tb = GTK_TEXT(w);
- gtk_text_freeze(tb);
-
- // remove old text
- gtk_editable_delete_text(GTK_EDITABLE(tb), 0, -1);
-
- // insert new text
- sprintf(buffer, ">%04X", val);
- gtk_text_insert(tb,
- style->font,
- debugger_status_color_fg(item, style),
- debugger_status_color_bg(item, style),
- buffer,
- 5);
-
- // update
- gtk_text_thaw(tb);
- }
-
- /*
- * Setup memory windows for the first time.
- *
- * Each entry in the vbox contains a frame with a scrolled window inside.
- */
-
- #define MEMORY_BYTES_PER_ROW 16
-
- static char *memory_frame_names[MEMORY_VIEW_COUNT] =
- {
- "cpu_1_memory_frame",
- "cpu_2_memory_frame",
- "video_memory_frame",
- "graphics_memory_frame",
- "speech_memory_frame"
- };
-
- static char *memory_view_names[MEMORY_VIEW_COUNT] =
- {
- "cpu_view_1",
- "cpu_view_2",
- "video_view",
- "graphics_view",
- "speech_view"
- };
-
- static void
- on_debugger_memory_window_size_request_event (GtkWidget *widget,
- GtkRequisition *requisition,
- gpointer user_data)
- {
- GtkWidget *tb;
- GtkStyle *s;
- int width, height;
-
- tb = widget;
-
- s = gtk_widget_get_style(tb);
-
- height = gdk_string_height(s->font, "!\n") * 3 / 2;
- width = gdk_string_width(s->font, "F");
-
- if (requisition->width < width) {
- requisition->width = width;
- gtk_widget_set_usize(widget, width, -2);
- }
- if (requisition->height < height) {
- requisition->height = height;
- gtk_widget_set_usize(widget, -2, height);
- }
-
- // requisition->width = 80;
- // requisition->height = 80;
-
- // g_print("requesting %d x %d\n", requisition->width, requisition->height);
-
- }
-
- static gboolean
- on_debugger_memory_window_size_allocate_event (GtkWidget *widget,
- GtkAllocation *allocation,
- gpointer user_data)
- {
- GtkWidget *tb;
- GtkStyle *s;
- int width, height, which;
-
- tb = widget;
-
- // g_print("allocated %d x %d\n", allocation->width, allocation->height);
-
- s = gtk_widget_get_style(tb);
- height = allocation->height / (gdk_string_height(s->font, "!\n") * 3 / 2);
- width = debugger_hex_dump_chars_to_bytes(allocation->width / (gdk_string_width(s->font, "F")) - 1);
- width &= ~1; // display whole words
-
- // in case the window was sized really small...
- if (height <= 0) height = 1;
- if (width <= 0) width = 1;
-
- // gtk_style_unref(s);
-
- gtk_object_set_data(GTK_OBJECT(widget), "view_width", (gpointer)width);
- gtk_object_set_data(GTK_OBJECT(widget), "view_height", (gpointer)height);
-
- which = (int)gtk_object_get_data(GTK_OBJECT(widget), "which");
- debugger_memory_view_size[which] = width * height;
-
- return FALSE;
- }
-
- static void
- setup_debugger_memory_views(void)
- {
- // GtkWidget *win;
- GtkWidget *w;
- GtkText *tb;
- GtkStyle *s;
- int width, height;
- int idx;
-
- int default_tab_width;
-
- // get a feel for width of window
- // by trying a test line
- default_tab_width = 1;
-
- // setup base size of text box
- s = gtk_widget_get_style(debugger_window);
- width = gdk_string_width(s->font, "^") * 80;
- height = gdk_string_height(s->font, "!") * 2;
- // gtk_style_unref(s);
-
- idx = MEMORY_VIEW_CPU_1;
- while (idx < MEMORY_VIEW_COUNT) {
- w = gtk_object_get_data(GTK_OBJECT(debugger_window),
- memory_frame_names[idx]);
-
- g_return_if_fail(w);
- g_return_if_fail(GTK_IS_BIN(w));
-
- w = GTK_BIN(w)->child;
- g_return_if_fail(GTK_IS_TEXT(w));
- tb = (GtkText *)w;
-
- // add a text box to the window
- /* w = gtk_text_new (NULL, NULL);
- tb = GTK_TEXT(w);
- gtk_widget_ref(w);*/
- gtk_text_set_editable (tb, false);
-
- // force size
- //gtk_widget_set_usize(w, width, height);
-
- // don't wrap lines!
- gtk_text_set_line_wrap(tb, false);
- gtk_text_set_adjustments(tb, NULL, NULL);
-
- // set tab width
- tb->default_tab_width = default_tab_width;
-
- gtk_object_set_data_full(GTK_OBJECT(debugger_window),
- memory_view_names[idx],
- w,
- (GtkDestroyNotify) gtk_widget_unref);
-
- gtk_object_set_data(GTK_OBJECT(tb),
- "which",
- (gpointer)idx);
-
- debugger_memory_view_size[idx] = MEMORY_BYTES_PER_ROW * 4;
-
- // watch for resizes so we can fill the memory view
- gtk_signal_connect (GTK_OBJECT (tb), "size_allocate",
- GTK_SIGNAL_FUNC (on_debugger_memory_window_size_allocate_event),
- (gpointer)tb);
-
- gtk_signal_connect (GTK_OBJECT (tb), "size_request",
- GTK_SIGNAL_FUNC (on_debugger_memory_window_size_request_event),
- (gpointer)tb);
-
- //gtk_widget_show(w);
- //gtk_container_add(GTK_CONTAINER(win), w);
-
- idx++;
- }
- }
-
- static void
- update_memory_window(status_item item, Memory *mem)
- {
- GtkText *tb;
- GtkWidget *w;
- GtkStyle *style;
- char buffer[256];
- char *start, *end, *astart, *aend;
- int len;
- int offs;
-
- int width, height, which;
-
- // get our view
- w = gtk_object_get_data(GTK_OBJECT(debugger_window),
- memory_view_names[mem->which]);
-
- if (!VALID_WINDOW(w))
- return;
-
- width = (int)gtk_object_get_data(GTK_OBJECT(w), "view_width");
- height = (int)gtk_object_get_data(GTK_OBJECT(w), "view_height");
- which = (int)gtk_object_get_data(GTK_OBJECT(w), "which");
-
- // get style
- style = gtk_widget_get_style(w);
-
- // freeze entry
- tb = GTK_TEXT(w);
- gtk_text_freeze(tb);
-
- // remove old text
- gtk_editable_delete_text(GTK_EDITABLE(tb), 0, -1);
-
- offs = 0;
-
- while (offs < debugger_memory_view_size[which]) {
- // create new text
- debugger_hex_dump_line(mem, offs, width,
- ' ', ' ', ' ',
- offs + width < debugger_memory_view_size[which]
- ? '\n' : 0,
- buffer, sizeof(buffer),
- &start, &end, &astart, &aend);
- len = strlen(buffer);
-
- if (!start) {
- start = end = buffer + len;
- astart = aend = buffer + len;
- }
-
- // insert normal text
- gtk_text_insert(tb,
- style->font,
- debugger_status_color_fg(STATUS_MEMORY_VIEW, style),
- debugger_status_color_bg(STATUS_MEMORY_VIEW, style),
- buffer,
- start - buffer);
-
- // insert hex byte update text
- if (start < end) {
- gtk_text_insert(tb,
- style->font,
- debugger_status_color_fg(item, style),
- debugger_status_color_bg(item, style),
- start,
- end - start);
- }
-
- // insert normal text
- if (end < astart) {
- gtk_text_insert(tb,
- style->font,
- debugger_status_color_fg(STATUS_MEMORY_VIEW, style),
- debugger_status_color_bg(STATUS_MEMORY_VIEW, style),
- end,
- astart - end);
- }
-
- // insert ascii changed text
- if (astart < aend) {
- gtk_text_insert(tb,
- style->font,
- debugger_status_color_fg(item, style),
- debugger_status_color_bg(item, style),
- astart,
- aend - astart);
- }
-
- // insert normal ascii text
- if (aend < buffer + len) {
- gtk_text_insert(tb,
- style->font,
- debugger_status_color_fg(STATUS_MEMORY_VIEW, style),
- debugger_status_color_bg(STATUS_MEMORY_VIEW, style),
- aend,
- buffer + len - aend);
- }
-
- offs += width;
- }
-
- // update
- gtk_text_thaw(tb);
- }
-
- #define INSTRUCTION_BOX_MAX_LENGTH (256*1024)
-
- static void
- setup_debugger_instruction_box(void)
- {
- GtkText *tb;
- GtkStyle *s;
- int width, height;
-
- g_return_if_fail(debugger_instruction_box);
-
- tb = GTK_TEXT(debugger_instruction_box);
-
- // set tab width
- tb->default_tab_width = 4;
-
- // setup base size of text box
- s = gtk_widget_get_style(debugger_instruction_box);
- width = gdk_string_width(s->font, "^") * 40;
- height = gdk_string_height(s->font, "!") * 16;
- // gtk_style_unref(s);
-
- // width = 64;
- // height = 16;
- // force size
- gtk_widget_set_usize(debugger_instruction_box, width, height);
- // memset((void *)&req, 0, sizeof(req));
- // req.width = width;
- // req.height = height;
- // gtk_widget_size_request(debugger_instruction_box, &req);
-
- // don't wrap lines!
- gtk_text_set_line_wrap(tb, false);
- }
-
- static void
- update_debugger_instruction(status_item item, bool show_verbose,
- Instruction *inst,
- char *hex, char *disasm, // may be NULL
- char *op1, char *op2)
- {
- char buffer[256];
- GtkStyle *style;
- GtkText *tb;
- int len, point;
-
- if (!VALID_WINDOW(debugger_instruction_box))
- return;
-
- // only deal with single instructions, ignore their effects
- if (item == STATUS_CPU_INSTRUCTION)
- {
- tb = GTK_TEXT(debugger_instruction_box);
-
- // delete old text
- len = gtk_text_get_length(tb);
- if (len > INSTRUCTION_BOX_MAX_LENGTH * 2) {
- gtk_text_freeze(tb);
- point = gtk_text_get_point(tb);
- gtk_text_set_point(tb, 0);
- gtk_text_forward_delete(tb, len - INSTRUCTION_BOX_MAX_LENGTH);
- gtk_text_set_point(tb, INSTRUCTION_BOX_MAX_LENGTH);
- gtk_text_thaw(tb);
- }
-
- len = sprintf(buffer, "%s %s %s\n",
- hex, inst->name, disasm);
-
- style = gtk_widget_get_style(debugger_instruction_box);
- gtk_text_insert(tb,
- style->font,
- debugger_status_color_fg(item, style),
- debugger_status_color_bg(item, style),
- buffer,
- len);
- gtk_text_set_point(tb, gtk_text_get_length(tb));
- }
- }
-
- static void
- ping_debugger_instruction_box(void)
- {
- /*
- GtkText *tb;
- g_return_if_fail(GTK_IS_TEXT(debugger_instruction_box));
- tb = GTK_TEXT(debugger_instruction_box);
- gtk_text_set_point(tb, gtk_text_get_length(tb));
- if (debugger_verbose_updates) {
- if (tb->freeze_count) gtk_text_thaw(tb);
- } else {
- gtk_text_insert(tb, NULL, NULL, NULL, "\n", 1);
- if (!tb->freeze_count) gtk_text_freeze(tb);
- }
- */
- }
-
- static void
- update_debugger_entry(GtkWidget *entry, status_item item, u16 val)
- {
- char buffer[32];
-
- if (!VALID_WINDOW(entry))
- return;
-
- sprintf(buffer, ">%04X", val);
- gtk_entry_set_text(GTK_ENTRY(entry), buffer);
- }
-
- /***************/
-
- static int debugger_verbose_update_count;
-
- void
- debugger_report_status(status_item item, va_list va)
- {
- bool show_verbose = execution_paused() || debugger_verbose_updates ||
- debugger_verbose_update_count != 0;
-
- if (!VALID_WINDOW(debugger_window))
- return;
-
- switch (item)
- {
- case STATUS_DEBUG_REFRESH:
- if (debugger_verbose_update_count) {
- debugger_register_clear_view();
- debugger_memory_clear_views();
- debugger_instruction_clear_view();
- debugger_verbose_update_count--;
- }
-
- break;
- case STATUS_CPU_PC:
- if (show_verbose) {
- update_debugger_entry(debugger_pc_entry, item, va_arg(va, int));
- }
- break;
-
- case STATUS_CPU_STATUS:
- if (show_verbose) {
- update_debugger_entry(debugger_st_entry, item, va_arg(va, int));
- }
- break;
-
- case STATUS_CPU_WP:
- if (show_verbose) {
- update_debugger_entry(debugger_wp_entry, item, va_arg(va, int));
- }
- break;
-
- case STATUS_CPU_REGISTER_READ:
- case STATUS_CPU_REGISTER_WRITE:
- {
- if (show_verbose) {
- int reg, val;
- reg = va_arg(va, int);
- val = va_arg(va, int);
- update_debugger_register(item, reg, val);
- }
- break;
- }
-
- case STATUS_CPU_REGISTER_VIEW:
- {
- if (show_verbose) {
- int wp;
- u16 *regs;
- int reg;
- wp = va_arg(va, int);
- regs = va_arg(va, u16 *);
- for (reg = 0; reg < 16; reg++) {
- update_debugger_register(item, reg, regs[reg]);
- }
- }
- break;
- }
-
- case STATUS_CPU_INSTRUCTION:
- {
- if (show_verbose) {
- Instruction *inst;
- char *hex, *disasm, *op1, *op2;
- inst = va_arg(va, Instruction *);
- hex = va_arg(va, char *);
- disasm = va_arg(va, char *);
- op1 = va_arg(va, char *);
- op2 = va_arg(va, char *);
-
- update_debugger_instruction(item, show_verbose,
- inst, hex, disasm, op1, op2);
- }
- break;
- }
-
- case STATUS_CPU_INSTRUCTION_LAST:
- {
- if (show_verbose) {
- Instruction *inst;
- char *op1, *op2;
- inst = va_arg(va, Instruction *);
- op1 = va_arg(va, char *);
- op2 = va_arg(va, char *);
-
- update_debugger_instruction(item, show_verbose,
- inst, 0L, 0L, op1, op2);
- }
- break;
- }
-
- case STATUS_MEMORY_READ:
- case STATUS_MEMORY_WRITE:
- case STATUS_MEMORY_VIEW:
- if (show_verbose) {
- Memory *mem = va_arg(va, Memory *);
- update_memory_window(item, mem);
- }
- break;
- }
- }
-
- /***************/
-
- static void
- debugger_run_event(void)
- {
- debugger_verbose_update_count = 2;
- debugger_refresh();
- }
-
- static void
- debugger_change_verbosity(bool verbose)
- {
- static int debugger_run_tag;
-
- if (debugger_verbose_updates != verbose) {
- debugger_verbose_updates = verbose;
- ping_debugger_instruction_box();
- if (!verbose) {
- if (!debugger_run_tag) {
- debugger_run_tag = TM_UniqueTag();
- }
- TM_SetEvent(debugger_run_tag, TM_HZ*100, 0,
- TM_FUNC|TM_REPEAT, TM_EVENT_FUNC(debugger_run_event));
- } else {
- if (debugger_run_tag) {
- TM_ResetEvent(debugger_run_tag);
- }
- }
- }
- }
-
- void
- on_v9t9_debug_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- /*
- GtkWidget *label = GTK_BIN(button)->child;
-
- debugger_enable(!debugger_enabled());
-
- if (debugger_enabled()) {
- gtk_label_set_text(GTK_LABEL(label), "Stop Tracing");
- } else {
- gtk_label_set_text(GTK_LABEL(label), "Trace");
- }
- */
-
- execution_pause(true);
- debugger_enable(true);
- debugger_change_verbosity(true);
- }
-
- void
- on_debugger_close_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- debugger_enable(false);
- execution_pause(false);
- }
-
- void
- on_debugger_run_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- debugger_change_verbosity(false);
- ping_debugger_instruction_box();
- execution_pause(false);
- }
-
-
- void
- on_debugger_walk_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- debugger_change_verbosity(true);
- ping_debugger_instruction_box();
- execution_pause(false);
- }
-
-
- void
- on_debugger_stop_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- debugger_change_verbosity(true);
- execution_pause(true);
- debugger_refresh();
- if (!(stateflag & ST_PAUSE))
- stateflag |= ST_SINGLESTEP;
- ping_debugger_instruction_box();
- }
-
- void
- on_debugger_next_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- debugger_change_verbosity(true);
- // execution_pause(true);
- // execution_pause(false);
- stateflag |= ST_SINGLESTEP;
- ping_debugger_instruction_box();
- }
-
- void
- GTK_system_debugger_enabled(bool enabled)
- {
- if (enabled) {
- if (!VALID_WINDOW(debugger_window)) {
- debugger_window = create_debugger_window();
- gtk_widget_set_name(debugger_window, "v9t9.debugger");
-
- debugger_registers_table = gtk_object_get_data(GTK_OBJECT(debugger_window),
- "debugger_registers_table");
- debugger_instruction_box = gtk_object_get_data(GTK_OBJECT(debugger_window),
- "debugger_instruction_box");
- debugger_status_bar = gtk_object_get_data(GTK_OBJECT(debugger_window),
- "debugger_status_bar");
- debugger_pc_entry = gtk_object_get_data(GTK_OBJECT(debugger_window),
- "debugger_pc_entry");
- debugger_wp_entry = gtk_object_get_data(GTK_OBJECT(debugger_window),
- "debugger_wp_entry");
- debugger_st_entry = gtk_object_get_data(GTK_OBJECT(debugger_window),
- "debugger_st_entry");
-
- setup_debugger_registers_table();
- setup_debugger_memory_views();
- setup_debugger_instruction_box();
- }
- // debugger_verbose_updates = true;
- // ping_debugger_instruction_box();
- gtk_widget_show(debugger_window);
- } else {
- if (debugger_window) {
- execution_pause(false);
- gtk_widget_hide(debugger_window);
- GTK_RESTORE_FOCUS;
- }
- }
- }
-
- void
- GTK_system_execution_paused(bool paused)
- {
- if (v9t9_window_pause_button) {
- GtkWidget *label = GTK_BIN(v9t9_window_pause_button)->child;
- if (!GTK_IS_LABEL(label))
- return;
-
- if (debugger_enabled()) {
- debugger_register_clear_view();
- debugger_memory_clear_views();
- debugger_instruction_clear_view();
- }
-
- if (paused) {
- gtk_label_set_text(GTK_LABEL(label), "Resume");
- } else {
- gtk_label_set_text(GTK_LABEL(label), "Pause");
- }
- }
- }
-
- #if 0
- #pragma mark -
- #endif
-
- /*
- * Generic routine that enables or disables a widget in user_data
- * based on the state of the toggle button.
- */
- void
- on_v9t9_togglebutton_realize_widget_enable (GtkWidget *widget,
- gpointer user_data)
- {
- g_return_if_fail(GTK_IS_TOGGLE_BUTTON(widget));
- g_return_if_fail(GTK_IS_WIDGET(user_data));
- gtk_widget_set_sensitive(GTK_WIDGET(user_data),
- gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
- }
-
- void
- on_v9t9_togglebutton_toggled_widget_enable (GtkToggleButton *togglebutton,
- gpointer user_data)
- {
- g_return_if_fail(GTK_IS_WIDGET(user_data));
- gtk_widget_set_sensitive(GTK_WIDGET(user_data),
- gtk_toggle_button_get_active(togglebutton));
- }
-
- void
- on_v9t9_togglebutton_realize_widget_enable_not (GtkWidget *widget,
- gpointer user_data)
- {
- g_return_if_fail(GTK_IS_TOGGLE_BUTTON(widget));
- g_return_if_fail(GTK_IS_WIDGET(user_data));
- gtk_widget_set_sensitive(GTK_WIDGET(user_data),
- !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
- }
-
- void
- on_v9t9_togglebutton_toggled_widget_enable_not (GtkToggleButton *togglebutton,
- gpointer user_data)
- {
- g_return_if_fail(GTK_IS_WIDGET(user_data));
- gtk_widget_set_sensitive(GTK_WIDGET(user_data),
- !gtk_toggle_button_get_active(togglebutton));
- }
-
- /*
- * Generic routine that toggles the value of the command variable
- * name in user_data depending on the value of togglebutton.
- */
- static void
- togglebutton_toggled_command_toggle
- (GtkToggleButton *togglebutton,
- gpointer user_data,
- gboolean if_active)
- {
- gchar *var = (gchar *)user_data;
- gboolean enabled = gtk_toggle_button_get_active(togglebutton);
- char command[256];
-
- snprintf(command, sizeof(command), "%s %s\n", var,
- if_active == enabled ? "on" : "off");
- GTK_send_command(command);
- }
-
- /*
- * Generic routine that toggles the value of the command variable
- * name in user_data depending on the value of togglebutton.
- */
- void
- on_v9t9_togglebutton_toggled_command_toggle
- (GtkToggleButton *togglebutton,
- gpointer user_data)
- {
- togglebutton_toggled_command_toggle(togglebutton, user_data, true);
- }
-
- /*
- * Generic routine that toggles the value of the command variable
- * name in user_data depending on the inverted value of togglebutton.
- */
- void
- on_v9t9_togglebutton_toggled_command_toggle_not
- (GtkToggleButton *togglebutton,
- gpointer user_data)
- {
- togglebutton_toggled_command_toggle(togglebutton, user_data, false);
- }
-
-
- /*
- * Generic routine that sets the value of the togglebutton
- * based on the value of the command variable name in user_data.
- */
- static void
- togglebutton_realize_active (GtkWidget *widget,
- gpointer user_data,
- gboolean if_active)
- {
- GtkToggleButton *tb;
- char *var = (char *)user_data;
- command_symbol *sym;
- int toggle;
-
- g_return_if_fail(var);
- g_return_if_fail(GTK_IS_TOGGLE_BUTTON(widget));
- tb = GTK_TOGGLE_BUTTON(widget);
-
- /* Look up the symbol and set its value */
- if (command_match_symbol(universe, var, &sym) &&
- command_arg_get_num(sym->args, &toggle))
- {
- // don't call this, or else it triggers the other
- // callback and executes a command...
- //gtk_toggle_button_set_active(tb, if_active == toggle);
- tb->active = (if_active == !!toggle);
- }
- else
- {
- logger(LOG_USER|LOG_FATAL, "Button mapped to missing option '%s'\n",
- var);
- }
- }
-
- /*
- * Generic routine that sets the value of the togglebutton
- * based on the true value of the command variable name in user_data.
- */
- void
- on_v9t9_togglebutton_realize_active (GtkWidget *widget,
- gpointer user_data)
- {
- togglebutton_realize_active(widget, user_data, true);
- }
-
- /*
- * Generic routine that sets the value of the togglebutton
- * based on the false value of the command variable name in user_data.
- */
- void
- on_v9t9_togglebutton_realize_inactive (GtkWidget *widget,
- gpointer user_data)
- {
- togglebutton_realize_active(widget, user_data, false);
- }
-
- /*
- * Generic callback to execute a command if a toggle button
- * has been clicked and thusly enabled.
- */
- void
- on_v9t9_togglebutton_clicked (GtkButton *button,
- gpointer user_data)
- {
- g_return_if_fail(GTK_IS_TOGGLE_BUTTON(button));
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
- {
- GTK_send_command((const gchar *)user_data);
- }
- }
-
- static char *
- _v9t9_dsr_entry_get_filename(gpointer user_data)
- {
- char *var, *filename;
- command_symbol *sym;
-
- var = (char *)user_data;
-
- /* Look up the symbol and set its value */
- if (command_match_symbol(universe, var, &sym) &&
- command_arg_get_string(sym->args, &filename))
- {
- return filename;
- }
- else
- {
- logger(LOG_USER|LOG_FATAL, "Text entry mapped to missing option '%s'\n",
- var);
- return 0L;
- }
- }
-
- static void
- _v9t9_dsr_entry_set_filename(gpointer user_data, char *filename)
- {
- char msg[256];
-
- snprintf(msg, sizeof(msg), "%s \"%s\"\n",
- (gchar *)user_data, filename);
- GTK_send_command(msg);
- }
-
- /*
- * Generic DSR entry activation callback
- */
- void
- on_v9t9_dsr_entry_activate (GtkEditable *editable,
- gpointer user_data)
- {
- char *path;
- gchar *copy;
- OSSpec spec;
-
- if (GTK_WIDGET(editable)->state != GTK_STATE_INSENSITIVE)
- {
- path = gtk_editable_get_chars(editable, 0, -1);
-
- copy = disk_file_canonicalize(&romspath, systemromspath,
- false /*directory*/, path, &spec,
- true /*add_dir*/);
- _v9t9_dsr_entry_set_filename(user_data, copy);
-
- g_free(path);
- g_free(copy);
- }
- }
-
- /*
- * Setup the text entry
- */
- void
- on_v9t9_dsr_entry_realize (GtkWidget *widget,
- gpointer user_data)
- {
- char *filename;
-
- g_return_if_fail(GTK_IS_ENTRY(widget));
-
- filename = _v9t9_dsr_entry_get_filename(user_data);
- gtk_entry_set_text(GTK_ENTRY(widget), filename ? filename : "");
- }
-
- static GtkFileSelection *dsr_file_dialog;
-
- static GtkFileSelection *
- create_dsr_file_selection (void)
- {
- GtkWidget *dsr_file_selection;
- GtkWidget *ok_button2;
- GtkWidget *cancel_button2;
-
- dsr_file_selection = gtk_file_selection_new ("Select ROM Filename");
- gtk_object_set_data (GTK_OBJECT (dsr_file_selection), "dsr_file_selection", dsr_file_selection);
- gtk_container_set_border_width (GTK_CONTAINER (dsr_file_selection), 10);
-
- ok_button2 = GTK_FILE_SELECTION (dsr_file_selection)->ok_button;
- gtk_object_set_data (GTK_OBJECT (dsr_file_selection), "ok_button2", ok_button2);
- gtk_widget_show (ok_button2);
- GTK_WIDGET_SET_FLAGS (ok_button2, GTK_CAN_DEFAULT);
-
- cancel_button2 = GTK_FILE_SELECTION (dsr_file_selection)->cancel_button;
- gtk_object_set_data (GTK_OBJECT (dsr_file_selection), "cancel_button2", cancel_button2);
- gtk_widget_show (cancel_button2);
- GTK_WIDGET_SET_FLAGS (cancel_button2, GTK_CAN_DEFAULT);
-
- return GTK_FILE_SELECTION(dsr_file_selection);
- }
-
- /*
- * user_data is the text entry widget
- */
- static void
- on_dsr_file_ok_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- gchar *path;
- gchar *copy;
- GtkEntry *entry;
- OSSpec spec;
-
- g_return_if_fail(GTK_IS_ENTRY(user_data));
-
- entry = GTK_ENTRY(user_data);
-
- path = gtk_file_selection_get_filename(dsr_file_dialog);
- copy = disk_file_canonicalize(&romspath, systemromspath,
- false /*directory*/, path, &spec,
- true /*add_dir*/);
-
- gtk_entry_set_text(entry, copy);
- gtk_signal_emit_by_name(GTK_OBJECT(entry), "activate");
-
- gtk_widget_unref((GtkWidget *)dsr_file_dialog);
- dsr_file_dialog = 0L;
-
- g_free(copy);
- }
-
- /*
- * user_data is the DSR filename variable
- */
- static void
- on_dsr_file_cancel_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- gtk_widget_unref((GtkWidget *)dsr_file_dialog);
- dsr_file_dialog = 0L;
- }
-
- /*
- * Choose a new entry for the filename.
- *
- * user_data is the text entry widget
- */
- void
- on_v9t9_dsr_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- OSSpec spec;
- const char *filename;
- GtkEntry *entry;
- gchar *copy;
-
- g_return_if_fail(GTK_IS_ENTRY(user_data));
-
- entry = GTK_ENTRY(user_data);
-
- if (VALID_WINDOW(dsr_file_dialog)) {
- return;
- }
-
- dsr_file_dialog = create_dsr_file_selection();
-
- gtk_widget_show(GTK_WIDGET(dsr_file_dialog));
- filename = gtk_entry_get_text(entry);
-
- copy = disk_file_canonicalize(&romspath, systemromspath,
- false /*directory*/, filename, &spec,
- false /*add_dir*/);
-
- gtk_file_selection_set_filename(dsr_file_dialog, OS_SpecToString1(&spec));
- gtk_file_selection_complete(dsr_file_dialog, "*.bin");
-
- g_free(copy);
-
- // wire up buttons here (so we can pass known disk number)
- gtk_signal_connect(GTK_OBJECT(dsr_file_dialog->ok_button),
- "clicked",
- GTK_SIGNAL_FUNC(on_dsr_file_ok_button_clicked),
- (gpointer)entry);
- gtk_signal_connect(GTK_OBJECT(dsr_file_dialog->cancel_button),
- "clicked",
- GTK_SIGNAL_FUNC(on_dsr_file_cancel_button_clicked),
- (gpointer)0L);
- }
-
- /***********************************************/
- #if 0
- #pragma mark -
- #endif
-
- static GtkWidget *memory_dialog;
-
- void
- on_v9t9_window_memory_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- if (!VALID_WINDOW(memory_dialog)) {
- memory_dialog = create_memory_dialog();
- } else {
- gtk_widget_hide(memory_dialog);
- }
- gtk_widget_show(memory_dialog);
-
- execution_pause(true);
- }
-
-
- void
- on_memory_dialog_close_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- gtk_widget_hide(memory_dialog);
- execution_pause(false);
- GTK_RESTORE_FOCUS;
- }
-
- /*
- * Lookup and execute the first iteration of a dynamic command
- */
- static int
- _v9t9_dynamic_command(const char *name, command_symbol **sym)
- {
- if (!command_match_symbol(universe, name, sym))
- logger(_L|LOG_FATAL, "Unknown command '%s'\n", name);
-
- if (!((*sym)->flags & c_DYNAMIC))
- logger(_L|LOG_FATAL, "'%s' is not c_DYNAMIC\n", name);
-
- return (*sym)->action(*sym, csa_READ, 0);
- }
-
- /*
- * Activate or deactivate a button that optionally loads
- * a module ROM. These conflict with the "LoadModule"
- * command and the commands that load them won't be saved
- * to the config file if they are empty. We use this
- * to tell whether they are being used.
- */
- void
- on_memory_config_module_rom_button_realize
- (GtkWidget *widget,
- gpointer user_data)
- {
- GtkToggleButton *tb;
- command_symbol *sym;
-
- #if 0
- // old style: one button per ROM
- g_return_if_fail(user_data);
- g_return_if_fail(GTK_IS_TOGGLE_BUTTON(widget));
- tb = GTK_TOGGLE_BUTTON(widget);
-
- /*
- * If the entry is loaded, activate the button.
- */
- tb->active = (_v9t9_dynamic_command((char *)user_data, &sym));
- #endif
-
- g_return_if_fail(GTK_IS_TOGGLE_BUTTON(widget));
- tb = GTK_TOGGLE_BUTTON(widget);
-
- /*
- * If the module entry is not loaded, activate the button.
- */
- tb->active = (!_v9t9_dynamic_command("ReplaceModule", &sym));
- }
-
- /*
- * User opted to set a custom module ROM file,
- * this means we have to unload the module entry so
- * this will have precedence.
- */
- void
- on_memory_config_module_rom_button_clicked
- (GtkToggleButton *togglebutton,
- gpointer user_data)
- {
- gpointer ptr;
-
- if (gtk_toggle_button_get_active(togglebutton))
- {
- /* Activate all the children */
- ptr = gtk_object_get_data((GtkObject *)memory_dialog, "module_rom_entry");
- if (ptr) gtk_signal_emit_by_name(GTK_OBJECT(ptr), "activate");
- ptr = gtk_object_get_data((GtkObject *)memory_dialog, "module_grom_entry");
- if (ptr) gtk_signal_emit_by_name(GTK_OBJECT(ptr), "activate");
- ptr = gtk_object_get_data((GtkObject *)memory_dialog, "module_rom1_entry");
- if (ptr) gtk_signal_emit_by_name(GTK_OBJECT(ptr), "activate");
- ptr = gtk_object_get_data((GtkObject *)memory_dialog, "module_rom2_entry");
- if (ptr) gtk_signal_emit_by_name(GTK_OBJECT(ptr), "activate");
- }
-
- #if 0
- // old style: one button per rom
- g_return_if_fail(GTK_IS_ENTRY(user_data));
-
- if (gtk_toggle_button_get_active(togglebutton))
- {
- if (_v9t9_dynamic_command("ReplaceModule", &sym))
- {
- GTK_send_command("UnloadModuleOnly\n");
- }
- gtk_signal_emit_by_name(GTK_OBJECT(user_data), "activate");
- }
- #endif
- }
-
- /*
- * Activated the ROM entry, disable the banked ROM entries
- */
- void
- on_memory_config_banked_module_deactivate
- (GtkEditable *editable,
- gpointer user_data)
- {
- gchar *str;
- g_return_if_fail(GTK_IS_WIDGET(user_data));
-
- str = gtk_entry_get_text(GTK_ENTRY(editable));
- if (str && *str)
- gtk_widget_set_sensitive(GTK_WIDGET(user_data), false);
- else
- gtk_widget_set_sensitive(GTK_WIDGET(user_data), true);
-
- /* v9t9 handles the memory map stuff */
- }
-
- /*
- * Banked module entry activated
- */
- void
- on_module_config_banked_module_activate
- (GtkEditable *editable,
- gpointer user_data)
- {
- gchar *str;
- g_return_if_fail(GTK_IS_WIDGET(user_data));
-
- str = gtk_entry_get_text(GTK_ENTRY(editable));
- if (str && *str)
- gtk_widget_set_sensitive(GTK_WIDGET(user_data), false);
- else
- gtk_widget_set_sensitive(GTK_WIDGET(user_data), true);
-
- /* v9t9 handles the memory map stuff */
- }
-
- #if 0
- #pragma mark -
- #endif
-
- /*
- * OPTIONS WINDOW
- */
-
- static GtkWidget *options_dialog;
-
- void
- on_v9t9_window_options_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- if (!VALID_WINDOW(options_dialog)) {
- options_dialog = create_options_dialog();
- } else {
- gtk_widget_hide(options_dialog);
- }
- gtk_widget_show(options_dialog);
- }
-
- void
- on_option_dialog_close_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- gtk_widget_hide(options_dialog);
-
- GTK_RESTORE_FOCUS;
- }
-
- /*
- * Set the value of a spin button from a command.
- */
- void
- on_v9t9_spin_button_realize_value (GtkWidget *widget,
- gpointer user_data)
- {
- GtkSpinButton *s;
- command_symbol *sym;
- int val;
-
- g_return_if_fail(user_data != 0L);
- g_return_if_fail(GTK_IS_SPIN_BUTTON(widget));
- s = GTK_SPIN_BUTTON(widget);
-
- /* Look up the symbol and set its value */
- if (command_match_symbol(universe, (char *)user_data, &sym) &&
- command_arg_get_num(sym->args, &val))
- {
- gtk_spin_button_set_value(s, (gfloat)val);
- }
- else
- {
- logger(LOG_USER|LOG_FATAL, "Button mapped to missing option '%s'\n",
- user_data);
- }
- }
-
- /*
- * User changed value of a spin button.
- * user_data is the name of the command to set.
- */
- void
- on_v9t9_spin_button_changed_value (GtkEditable *editable,
- gpointer user_data)
- {
- char command[256];
- GtkSpinButton *s;
-
- g_return_if_fail(user_data != 0L);
- g_return_if_fail(GTK_IS_SPIN_BUTTON(editable));
- s = GTK_SPIN_BUTTON(editable);
-
- snprintf(command, sizeof(command), "%s %d\n", (char *)user_data,
- gtk_spin_button_get_value_as_int(s));
-
- GTK_send_command(command);
- }
-
- /*
- * Clicked a button that affects the value of another widget.
- */
- void
- on_v9t9_button_clicked_realize_widget (GtkButton *button,
- gpointer user_data)
- {
- GtkWidget *w;
- g_return_if_fail(GTK_IS_WIDGET(user_data));
-
- w = GTK_WIDGET(user_data);
-
- // why can't we realize the widget again?
- gtk_widget_hide(w);
- gtk_widget_show(w);
- }
-
- #if 0
- #pragma mark -
- #endif
-
- V99FileSelection *config_file_dialog;
-
- /*
- * user_data is 0 for saving, != 0 for loading
- */
- static void
- on_config_file_ok_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- const char *path;
- OSSpec spec;
- OSError err;
-
- path = v99_file_selection_get_filename(config_file_dialog);
- err = OS_MakeFileSpec(path, &spec);
- if (err != OS_NOERR) {
- logger(_L|LOG_ERROR|LOG_USER, "Could not resolve filename '%s' (%s)\n",
- path, OS_GetErrText(err));
- return;
- }
-
- if ((gint)user_data == GTK_QUICK_LOAD ?
- config_load_spec(&spec, true /*session*/) :
- config_save_spec(&spec, true /*session*/))
- {
- gtk_widget_hide((GtkWidget *)config_file_dialog);
- GTK_RESTORE_FOCUS;
- }
- }
-
-
- static void
- on_config_file_cancel_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- gtk_widget_hide((GtkWidget *)config_file_dialog);
- GTK_RESTORE_FOCUS;
- }
-
- /*
- * Change directory by selecting an entry in the pathlist
- */
- static void
- on_config_file_path_list_select_row (GtkWidget *clist,
- gint row,
- gint column,
- GdkEventButton *event,
- gpointer data )
- {
- gchar *text;
- gchar *wild;
- gchar sep[] = { G_DIR_SEPARATOR, 0 };
-
- /* Get the directory selected */
- gtk_clist_get_text(GTK_CLIST(clist), row, column, &text);
-
- if (strcmp(text, ".") == 0) {
- text = OS_PathSpecToString1(&v9t9_homedir);
- }
- wild = g_strconcat(text, sep, "*.cnf", 0L);
- v99_file_selection_complete(V99_FILE_SELECTION(config_file_dialog), wild);
- g_free(wild);
- }
-
- /*
- * user_data is 0 for saving, != 0 for loading
- */
- void
- on_v9t9_quick_load_save_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- GtkCList *clist;
- int paused = execution_paused();
- if ((int)user_data == 0) execution_pause(1);
-
- if (VALID_WINDOW(config_file_dialog)) {
- gtk_widget_destroy((GtkWidget *)config_file_dialog);
- }
-
- config_file_dialog = V99_FILE_SELECTION(create_disk_file_selection(
- (gint)user_data == GTK_QUICK_SAVE
- ? "Save Session File"
- : "Load Session File"));
-
- v99_file_selection_set_file_list_active(config_file_dialog, TRUE);
-
- // wire up buttons here
- gtk_signal_connect(GTK_OBJECT(config_file_dialog->ok_button),
- "clicked",
- GTK_SIGNAL_FUNC(on_config_file_ok_button_clicked),
- user_data);
- gtk_signal_connect(GTK_OBJECT(config_file_dialog->cancel_button),
- "clicked",
- GTK_SIGNAL_FUNC(on_config_file_cancel_button_clicked),
- (gpointer)0L);
-
- gtk_widget_show(GTK_WIDGET(config_file_dialog));
-
- // FIXME: add tooltips
- clist = v99_file_selection_add_path_list(config_file_dialog,
- "Sessions",
- sessionspath);
-
- /* wire up callback to change directory */
- gtk_signal_connect(GTK_OBJECT(clist),
- "select_row",
- GTK_SIGNAL_FUNC(on_config_file_path_list_select_row),
- (gpointer)0L);
-
- clist = v99_file_selection_add_path_list(config_file_dialog,
- "Configurations",
- configspath);
-
- /* wire up callback to change directory */
- gtk_signal_connect(GTK_OBJECT(clist),
- "select_row",
- GTK_SIGNAL_FUNC(on_config_file_path_list_select_row),
- (gpointer)0L);
-
- if ((gint)user_data == GTK_QUICK_LOAD)
- v99_file_selection_complete(config_file_dialog, "*.cnf");
- else
- v99_file_selection_complete(config_file_dialog, "quicksave.cnf");
-
- v99_file_selection_set_filename(config_file_dialog, "quicksave.cnf");
-
- }
-
- /*********************************************/
-
- /*
- * Logging Configuration dialog.
- *
- * The meat of the dialog is automatically generated.
- */
- static GtkWidget *log_dialog;
- static GtkTable *log_table;
-
- void
- on_v9t9_window_logging_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- if (!VALID_WINDOW(log_dialog)) {
- log_dialog = create_logging_dialog();
- } else {
- gtk_widget_hide(log_dialog);
- }
- gtk_widget_show(log_dialog);
- }
-
- void
- on_logging_reset_all_clicked (GtkButton *button,
- gpointer user_data)
- {
- GTK_send_command("Log All 0\n");
-
- /* force a realize */
- gtk_signal_emit_by_name(GTK_OBJECT(log_table), "realize");
- }
-
- void
- on_logging_dialog_close_button_clicked (GtkButton *button,
- gpointer user_data)
- {
- gtk_widget_hide(log_dialog);
- }
-
- /*
- * Logging spin button needs to be realized.
- * user_data is the logging subsystem.
- */
- void
- on_log_spin_button_realize_value (GtkWidget *widget,
- gpointer user_data)
- {
- GtkSpinButton *s;
- int val;
-
- g_return_if_fail(GTK_IS_SPIN_BUTTON(widget));
- s = GTK_SPIN_BUTTON(widget);
-
- /* Look up the symbol and set its value */
- val = log_level((int)user_data);
- gtk_spin_button_set_value(s, (gfloat)val);
- }
-
- /*
- * Logging spin button changes.
- * user_data is the log subsystem.
- */
- static void
- on_log_spin_button_changed_value (GtkEditable *editable,
- gpointer user_data)
- {
- char command[256];
- GtkSpinButton *s;
-
- g_return_if_fail(GTK_IS_SPIN_BUTTON(editable));
- s = GTK_SPIN_BUTTON(editable);
-
- snprintf(command, sizeof(command), "Log %s %d\n",
- log_name((int)user_data),
- gtk_spin_button_get_value_as_int(s));
-
- GTK_send_command(command);
- }
-
-
- /*
- * Clicked a button that affects the value
- */
- static void
- on_log_button_clicked_realize_widget (GtkButton *button,
- gpointer user_data)
- {
- GtkWidget *w;
- g_return_if_fail(GTK_IS_WIDGET(user_data));
-
- w = GTK_WIDGET(user_data);
-
- // why can't we realize the widget again?
- gtk_widget_hide(w);
- gtk_widget_show(w);
- }
-
- /*
- * This action sets up the log_dialog's log_table item
- * to include a dial and label for each log subsystem.
- */
- void
- on_logging_log_table_realize (GtkWidget *widget,
- gpointer user_data)
- {
- int rows = LOG_NUM_SRC / 3;
- int cols = 3;
- int row, col, sys;
-
- /* Get the table */
- log_table = GTK_TABLE(gtk_object_get_data((GtkObject *)log_dialog, "log_table"));
- if (!log_table)
- logger(_L|LOG_FATAL, "Cannot get log_table from dialog\n");
-
- /* Resize from 1x1 to an interesting size */
- gtk_table_resize(log_table, rows, cols);
-
- /* Add an entry for each subsystem */
- row = col = 0;
- for (sys = 0; sys < LOG_NUM_SRC; sys++) {
- /* make the widgets */
- GtkObject *spin_adj = gtk_adjustment_new(
- log_level(sys),
- L_0,
- L_4,
- 1,
- 1,
- 1);
- GtkWidget *spin = gtk_spin_button_new(GTK_ADJUSTMENT(spin_adj), 1, 1);
- GtkWidget *label = gtk_label_new(log_name(sys));
- GtkWidget *hbox = gtk_hbox_new(false /*homogenous*/, 4 /*spacing*/);
-
- /* standard stuff */
- gtk_widget_ref(spin);
- gtk_widget_ref(label);
- gtk_widget_ref(hbox);
-
- gtk_object_set_data_full (GTK_OBJECT (log_table), "log_spin_button",
- spin,(GtkDestroyNotify) gtk_widget_unref);
- gtk_object_set_data_full (GTK_OBJECT (log_table), "log_label",
- label,(GtkDestroyNotify) gtk_widget_unref);
- gtk_object_set_data_full (GTK_OBJECT (log_table), "log_hbox",
- hbox,(GtkDestroyNotify) gtk_widget_unref);
-
- /* associate subsystem with spin button */
- gtk_signal_connect_after (GTK_OBJECT (spin), "activate",
- GTK_SIGNAL_FUNC (on_log_spin_button_changed_value),
- (gpointer)sys);
- gtk_signal_connect (GTK_OBJECT (spin), "changed",
- GTK_SIGNAL_FUNC (on_log_spin_button_changed_value),
- (gpointer)sys);
- gtk_signal_connect (GTK_OBJECT (spin), "realize",
- GTK_SIGNAL_FUNC (on_log_spin_button_realize_value),
- (gpointer)sys);
- gtk_signal_connect (GTK_OBJECT (spin), "show",
- GTK_SIGNAL_FUNC (on_log_spin_button_realize_value),
- (gpointer)sys);
-
- gtk_box_pack_start(GTK_BOX(hbox), label,
- TRUE /*expand*/, FALSE /*fill*/, 0 /*padding*/);
- gtk_box_pack_start(GTK_BOX(hbox), spin,
- FALSE /*expand*/, TRUE /*fill*/, 0 /*padding*/);
-
- gtk_widget_show(spin);
- gtk_widget_show(label);
- gtk_widget_show(hbox);
-
- /* add hbox to table */
- gtk_table_attach_defaults (GTK_TABLE (log_table),
- hbox, col, col+1, row, row+1);
-
- if (++col >= cols) {
- col = 0;
- ++row;
- }
- }
- }
-
-