/* SPIM S20 MIPS simulator. X interface to SPIM Copyright (C) 1990 by James Larus (larus@cs.wisc.edu), James R. Goodman, and Alan Yuen-wui Siow. SPIM 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 1, or (at your option) any later version. SPIM 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 GNU CC; see the file COPYING. If not, write to James R. Larus, Computer Sciences Department, University of Wisconsin--Madison, 1210 West Dayton Street, Madison, WI 53706, USA or to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* $Header: /home/aa/projects/spim/public_html/cvsroot/spimsal/buttons.c,v 1.3 2000/07/25 20:47:24 cs61c Exp $ */ #include #include "spim.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "xspim.h" #include "buttons.h" #include "inst.h" #include "mem.h" #include "reg.h" /* Local functions: */ static void addBreakpoint (); static void addClearButton (); static void addModeButton (); static void addPrintButton (); static void addTerminalButton (); static void bkptPrompt (); static void bkptPromptDestroyed (); static void clearState (); static void continueAction (); static void continuePromptDestroyed (); static void deleteBreakpoint (); static void destroyPopupPrompt (); static void helpAction (); static void haltAction (); static void init_stack (); static void loadPrompt (); static void loadPromptDestroyed (); static void listBreakpoint (); static void noop (); static void parsePrintValue (); static void parseSetValue (); static Widget popupTwoFieldDialog (); static void printMemPrompt (); static void printPromptDestroyed (); static void printSymbol (); static void quitAction (); static void quitPrompt (); static void quitPromptDestroyed (); static void readAsFile (); static void runProgram (); static void runPrompt (); static void runPromptDestroyed (); static void selectMode (); static void setValue (); static void setValuePrompt (); static void setValuePromptDestroyed (); static void stepContinue (); static void stepProgram (); static void stepPrompt (); static void stepPromptDestroyed (); static void warpToSecondDialog (); static int scan_hex(char *str, mem_addr *value); /* Exported variables: */ char *xspim_file_name = NULL; /* Retain last file's name. */ /* Imported variables: */ extern mem_addr PC; extern XtAppContext app_context; extern Pixmap mark; extern mem_addr program_starting_address; extern int load_trap_handler; extern jmp_buf spim_top_level_env; /* Local variables: */ static Widget bkptButton; static void (*confirmAction) () = noop; void CreateButtons (Widget parent) { Widget button; Widget command; Arg args[10]; XtSetArg (args[0], XtNlabel, "quit"); XtSetArg (args[1], XtNwidth, button_width); button = XtCreateManagedWidget ("quitbutton", commandWidgetClass, parent, args, TWO); XtAddCallback (button, XtNcallback, quitPrompt, NULL); XtSetArg (args[0], XtNlabel, "load"); XtSetArg (args[1], XtNwidth, button_width); command = XtCreateManagedWidget ("loadbutton", commandWidgetClass, parent, args, TWO); XtAddCallback (command, XtNcallback, loadPrompt, NULL); XtSetArg (args[0], XtNlabel, "run"); XtSetArg (args[1], XtNwidth, button_width); button = XtCreateManagedWidget ("runbutton", commandWidgetClass, parent, args, TWO); XtAddCallback (button, XtNcallback, runPrompt, NULL); XtSetArg (args[0], XtNlabel, "step"); XtSetArg (args[1], XtNwidth, button_width); button = XtCreateManagedWidget ("stepbutton", commandWidgetClass, parent, args, TWO); XtAddCallback (button, XtNcallback, stepPrompt, NULL); addClearButton (parent); XtSetArg (args[0], XtNlabel, "set value"); XtSetArg (args[1], XtNwidth, button_width); button = XtCreateManagedWidget ("setvaluebutton", commandWidgetClass, parent, args, TWO); XtAddCallback (button, XtNcallback, setValuePrompt, NULL); addPrintButton (parent); XtSetArg (args[0], XtNlabel, "breakpoints"); XtSetArg (args[1], XtNwidth, button_width); button = XtCreateManagedWidget ("bkptbutton", commandWidgetClass, parent, args, TWO); bkptButton = button; XtAddCallback (button, XtNcallback, bkptPrompt, NULL); XtSetArg (args[0], XtNlabel, "help"); XtSetArg (args[1], XtNwidth, button_width); button = XtCreateManagedWidget ("helpbutton", commandWidgetClass, parent, args, TWO); XtAddCallback (button, XtNcallback, helpAction, NULL); XtSetArg (args[0], XtNlabel, "halt"); XtSetArg (args[1], XtNwidth, button_width); button = XtCreateManagedWidget ("haltbutton", commandWidgetClass, parent, args, TWO); XtAddCallback (button, XtNcallback, haltAction, NULL); addTerminalButton (parent); addModeButton (parent); } /* *** Quit *** */ static Widget quitPopup = NULL; static void quitPrompt ( Widget button, XtPointer client_data, XtPointer call_data) { Widget parent, dialog; Arg args[10]; Position x, y; if (quitPopup == NULL) { parent = XtParent (button); XtTranslateCoords (button, (Position) 0, (Position) 0, &x, &y); XtSetArg (args[0], XtNx, x); XtSetArg (args[1], XtNy, y); quitPopup = XtCreatePopupShell ("prompt", transientShellWidgetClass, parent, args, TWO); XtAddCallback (quitPopup, XtNdestroyCallback, quitPromptDestroyed, (XtPointer) 0); XtSetArg (args[0], XtNlabel, "quit?"); dialog = XtCreateManagedWidget ("quit", dialogWidgetClass, quitPopup, args, ONE); XawDialogAddButton (dialog, "quit", quitAction, (XtPointer) dialog); XawDialogAddButton (dialog, "abort command", destroyPopupPrompt, (XtPointer) dialog); } confirmAction = quitAction; XtPopup (quitPopup, XtGrabNone); } static void quitAction (Widget w, XtPointer client_data, XtPointer call_data) { Widget dialog = (Widget) client_data; destroyPopupPrompt (NULL, (XtPointer) dialog, (XtPointer) NULL); XtDestroyApplicationContext (XtWidgetToApplicationContext (w)); exit (0); } static void quitPromptDestroyed (Widget w, XtPointer client_data, XtPointer call_data) { quitPopup = NULL; } /* *** Load *** */ static Widget loadPopup = NULL; static void loadPrompt (Widget button, XtPointer client_data, XtPointer call_data) { Widget parent, dialog; Arg args[10]; Position x, y; if (loadPopup == NULL) { parent = XtParent (button); XtTranslateCoords (button, (Position) 0, (Position) 0, &x, &y); XtSetArg (args[0], XtNx, x); XtSetArg (args[1], XtNy, y); loadPopup = XtCreatePopupShell ("popup", transientShellWidgetClass, parent, args, TWO); XtAddCallback (loadPopup, XtNdestroyCallback, loadPromptDestroyed, (XtPointer) 0); if (xspim_file_name == NULL) xspim_file_name = str_copy (""); XtSetArg (args[0], XtNlabel, "input filename:"); XtSetArg (args[1], XtNvalue, xspim_file_name); dialog = XtCreateManagedWidget ("dialog", dialogWidgetClass, loadPopup, args, TWO); XawDialogAddButton (dialog, "assembly file", readAsFile, (XtPointer) dialog); XawDialogAddButton (dialog, "abort command", destroyPopupPrompt, (XtPointer) dialog); } confirmAction = readAsFile; XtPopup (loadPopup, XtGrabNone); } static void readAsFile (Widget w, XtPointer client_data, XtPointer call_data) { Widget dialog = (Widget) client_data; String value = XawDialogGetValueString (dialog); if (spim_is_running) { XBell(XtDisplay(w), BELL_VOLUME); return; } free (xspim_file_name); xspim_file_name = str_copy (value); read_file (value, 1); destroyPopupPrompt (NULL, (XtPointer) dialog, (XtPointer) NULL); } static void loadPromptDestroyed (Widget w, XtPointer client_data, XtPointer call_data) { loadPopup = NULL; } /* *** Run *** */ static Widget runPopup = NULL; static Widget run_field1_text, run_field2_text; static void runPrompt (Widget button, XtPointer client_data, XtPointer call_data) { char sa[20]; if (runPopup == NULL) { sprintf (sa, "0x%08x", starting_address ()); runPopup = popupTwoFieldDialog (button, "run program", "starting address:", sa, "args:", xspim_file_name, "ok", runProgram, NULL, NULL, &run_field1_text, &run_field2_text); XtAddCallback (runPopup, XtNdestroyCallback, runPromptDestroyed, (XtPointer) 0); } confirmAction = runProgram; XtPopup (runPopup, XtGrabNone); } static void runProgram (Widget w, XtPointer client_data, XtPointer call_data) { Arg args[10]; String value1, value2; Widget form = XtParent (w); mem_addr addr; if (spim_is_running) { XBell(XtDisplay(w), BELL_VOLUME); return; } XtSetArg (args[0], XtNstring, &value1); XtGetValues (run_field1_text, args, ONE); XtSetArg (args[0], XtNstring, &value2); XtGetValues (run_field2_text, args, ONE); XtPopdown (XtParent (form)); destroyPopupPrompt (NULL, (XtPointer) form, NULL); init_stack (value2); if (scan_hex(value1, &addr)) start_program (addr); } static void init_stack (char *args) { int argc = 0; char *argv[10000]; char *a; static int stack_initialized = 0; if (stack_initialized) return; while (*args != '\0') { /* Skip leading blanks */ while (*args == ' ' || *args == '\t') args++; /* First non-blank char */ a = args; /* Last non-blank, non-null char */ while (*args != ' ' && *args != '\t' && *args != '\0') args++; /* Terminate word */ if (a != args) { if (*args != '\0') *args++ = '\0'; /* Null terminate */ argv [argc++] = a; } } initialize_run_stack (argc, argv); stack_initialized = 1; } static void runPromptDestroyed (Widget w, XtPointer client_data, XtPointer call_data) { runPopup = NULL; } /* *** Step *** */ static char *step_size = NULL; /* Retain step size */ static Widget stepPopup = NULL; static Widget step_field1_text, step_field2_text; static void stepPrompt (Widget button, XtPointer client_data, XtPointer call_data) { if (stepPopup == NULL) { if (step_size == NULL) step_size = str_copy ("1"); stepPopup = popupTwoFieldDialog (button, "step program", "number of steps:", step_size, "args:", xspim_file_name, "step", stepProgram, "continue", stepContinue, &step_field1_text, &step_field2_text); XtAddCallback (stepPopup, XtNdestroyCallback, stepPromptDestroyed, (XtPointer) 0); } confirmAction = stepProgram; XtPopup (stepPopup, XtGrabNone); } static void stepProgram (Widget w, XtPointer client_data, XtPointer call_data) { Arg args[10]; String value1, value2; mem_addr addr; int steps; if (spim_is_running) { XBell(XtDisplay(w), BELL_VOLUME); return; } XtSetArg (args[0], XtNstring, &value1); XtGetValues (step_field1_text, args, ONE); XtSetArg (args[0], XtNstring, &value2); XtGetValues (step_field2_text, args, ONE); steps = atoi (value1); free (step_size); step_size = str_copy (value1); addr = starting_address (); init_stack (value2); if (steps > 0 && addr > 0) execute_program (addr, steps, 1, 1); else { sprintf(mess_buff, "Cannot step %d steps from 0x%x\n", steps, addr); error (mess_buff); } } static void stepContinue (Widget w, XtPointer client_data, XtPointer call_data) { Widget dialog = (Widget) client_data; if (spim_is_running) { XBell(XtDisplay(w), BELL_VOLUME); return; } XtPopdown (XtParent (dialog)); destroyPopupPrompt (NULL, (XtPointer) dialog, (XtPointer) NULL); stepPopup = NULL; execute_program (PC, DEFAULT_RUN_STEPS, 0, 0); } static void stepPromptDestroyed (Widget w, XtPointer client_data, XtPointer call_data) { stepPopup = NULL; } /* *** Clear *** */ static void addClearButton (Widget parent) { Widget command, menu, entry; Arg args[2]; if (spim_is_running) { XBell(XtDisplay(parent), BELL_VOLUME); return; } XtSetArg (args[0], XtNwidth, button_width); command = XtCreateManagedWidget ("clear", menuButtonWidgetClass, parent, args, ONE); menu = XtCreatePopupShell ("menu", simpleMenuWidgetClass, command, NULL, ZERO); entry = XtCreateManagedWidget ("registers", smeBSBObjectClass, menu, args, ONE); XtAddCallback (entry, XtNcallback, clearState, (XtPointer) 0); entry = XtCreateManagedWidget ("memory & registers", smeBSBObjectClass, menu, args, ONE); XtAddCallback (entry, XtNcallback, clearState, (XtPointer) 1); entry = XtCreateManagedWidget ("console display", smeBSBObjectClass, menu, args, ONE); XtAddCallback (entry, XtNcallback, clearState, (XtPointer) 2); entry = XtCreateManagedWidget ("reload", smeBSBObjectClass, menu, args, ONE); XtAddCallback (entry, XtNcallback, clearState, (XtPointer) 3); } static void clearState (Widget w, XtPointer client_data, XtPointer call_data) { int clear_world = (int) client_data; if (clear_world == 1) { write_output (message_out, "Memory and registers cleared\n\n"); initialize_world (load_trap_handler && !bare_machine); initialize_console (); } else if (clear_world == 2) { write_output (message_out, "Console display cleared\n\n"); clear_console_display(); } else if (clear_world == 3) { if (xspim_file_name == NULL) return; else { write_output (message_out, "Memory and registers cleared\n\n"); initialize_world (load_trap_handler && !bare_machine); read_file (xspim_file_name, 1); } } else { write_output (message_out, "Registers cleared\n\n"); initialize_registers (); } redisplay_text (); redisplay_data (); } /* *** Set Value *** */ static Widget setValuePopup = NULL; static Widget set_field1_text, set_field2_text; static void setValuePrompt (Widget button, XtPointer client_data, XtPointer call_data) { if (setValuePopup == NULL) { setValuePopup = popupTwoFieldDialog (button, "set value", "register/location:", "", "value:", "", "set", parseSetValue, NULL, NULL, &set_field1_text, &set_field2_text); XtAddCallback (setValuePopup, XtNdestroyCallback, setValuePromptDestroyed, (XtPointer) 0); } confirmAction = parseSetValue; XtPopup (setValuePopup, XtGrabNone); } static void parseSetValue (Widget w, XtPointer client_data, XtPointer call_data) { Arg args[10]; String value1, value2; Widget form = XtParent (w); if (spim_is_running) { XBell(XtDisplay(w), BELL_VOLUME); return; } XtSetArg (args[0], XtNstring, &value1); XtGetValues (set_field1_text, args, ONE); XtSetArg (args[0], XtNstring, &value2); XtGetValues (set_field2_text, args, ONE); destroyPopupPrompt (NULL, (XtPointer) form, NULL); setValue (value1, value2); } static void setValue (char *location_str, char *value_str) { mem_addr value; int reg_no; /* brg- allow 'set value' to chars in xspim */ if (value_str[0] == '\'' && value_str[2] == '\'') { value = location_str[1]; } else { scan_hex(value_str, &value); } reg_no = register_name_to_number (location_str); if (reg_no < 0) if (*location_str == '$' || *location_str == 'r' || *location_str == 'R') reg_no = register_name_to_number (location_str + 1); if (reg_no == 0) error ("Cannot modify register 0\n"); else if (reg_no > 0) R[reg_no] = value; else if (streq (location_str, "Status") || streq (location_str, "status")) Status_Reg = value; else if (streq (location_str, "PC") || streq (location_str, "pc")) PC = value; else if (streq (location_str, "EPC") | streq (location_str, "epc")) EPC = value; else { mem_addr addr; /* Try to parse string as a number */ if (!scan_hex(location_str, &addr)) { sprintf(mess_buff, "Unknown location selected: %s\n", location_str); error (mess_buff); } else SET_MEM_WORD (addr, value); } redisplay_data (); } static void setValuePromptDestroyed (Widget w, XtPointer client_data, XtPointer call_data) { setValuePopup = NULL; } /* *** Print *** */ static void addPrintButton (Widget parent) { Widget command, menu, entry; Arg args[2]; XtSetArg (args[0], XtNwidth, button_width); command = XtCreateManagedWidget ("print", menuButtonWidgetClass, parent, args, ONE); menu = XtCreatePopupShell ("menu", simpleMenuWidgetClass, command, NULL, ZERO); entry = XtCreateManagedWidget ("memory location(s)", smeBSBObjectClass, menu, args, ONE); XtAddCallback (entry, XtNcallback, printMemPrompt, NULL); entry = XtCreateManagedWidget ("global symbols", smeBSBObjectClass, menu, args, ONE); XtAddCallback (entry, XtNcallback, printSymbol, NULL); } static Widget printPopup = NULL; static Widget print_field1_text, print_field2_text; static void printMemPrompt (Widget button, XtPointer client_data, XtPointer call_data) { if (printPopup == NULL) { printPopup = popupTwoFieldDialog (XtParent (button), "print memory", "from", "", "to", "", "print", parsePrintValue, NULL, NULL, &print_field1_text, &print_field2_text); XtAddCallback (printPopup, XtNdestroyCallback, printPromptDestroyed, (XtPointer) 0); } confirmAction = parsePrintValue; XtPopup (printPopup, XtGrabNone); } static void parsePrintValue (Widget w, XtPointer client_data, XtPointer call_data) { Arg args[10]; String value1, value2; Widget form = XtParent (w); if (spim_is_running) { XBell(XtDisplay(w), BELL_VOLUME); return; } XtSetArg (args[0], XtNstring, &value1); XtGetValues (print_field1_text, args, ONE); XtSetArg (args[0], XtNstring, &value2); XtGetValues (print_field2_text, args, ONE); XtPopdown (XtParent (form)); destroyPopupPrompt (NULL, (XtPointer) form, NULL); if (!streq (value1, "")) { mem_addr from, to; scan_hex(value1, &from); scan_hex(value1, &to); if (streq (value2, "")) print_mem (from); else for ( ; from <= to; from+= BYTES_PER_WORD) print_mem (from); } } static void printSymbol (Widget w, XtPointer client_data, XtPointer call_data) { print_symbols (); } static void printPromptDestroyed (Widget w, XtPointer client_data, XtPointer call_data) { printPopup = NULL; } /* *** Breakpoints **** */ static char *breakpoint_addr = NULL; /* Retain last breakpoint address */ static Widget bkptPopup = NULL; static void bkptPrompt (Widget button, XtPointer client_data, XtPointer call_data) { Widget parent, dialog; Arg args[10]; Position x, y; if (bkptPopup == NULL) { parent = XtParent (button); XtTranslateCoords (button, (Position) 0, (Position) 0, &x, &y); XtSetArg (args[0], XtNx, x); XtSetArg (args[1], XtNy, y); bkptPopup = XtCreatePopupShell ("popup", transientShellWidgetClass, parent, args, TWO); if (breakpoint_addr == NULL) breakpoint_addr = str_copy (""); XtSetArg (args[0], XtNlabel, "address:"); XtSetArg (args[1], XtNvalue, breakpoint_addr); dialog = XtCreateManagedWidget ("dialog", dialogWidgetClass, bkptPopup, args, TWO); XtAddCallback (bkptPopup, XtNdestroyCallback, bkptPromptDestroyed, (XtPointer) 0); XawDialogAddButton (dialog, "add", addBreakpoint, (XtPointer) dialog); XawDialogAddButton (dialog, "delete", deleteBreakpoint, (XtPointer) dialog); XawDialogAddButton (dialog, "list", listBreakpoint, (XtPointer) dialog); XawDialogAddButton (dialog, "abort command", destroyPopupPrompt, (XtPointer) dialog); } confirmAction = addBreakpoint; XtPopup (bkptPopup, XtGrabNone); } static void addBreakpoint (Widget w, XtPointer client_data, XtPointer call_data) { Widget dialog = (Widget) client_data; String value = XawDialogGetValueString (dialog); mem_addr addr; if (spim_is_running) { XBell(XtDisplay(w), BELL_VOLUME); return; } free (breakpoint_addr); breakpoint_addr = str_copy (value); while (*breakpoint_addr == ' ') breakpoint_addr++; if (isdigit (*breakpoint_addr)) scan_hex(value, &addr); else addr = find_symbol_address (breakpoint_addr); add_breakpoint (addr); destroyPopupPrompt (NULL, (XtPointer) dialog, (XtPointer) NULL); } static void deleteBreakpoint (Widget w, XtPointer client_data, XtPointer call_data) { Widget dialog = (Widget) client_data; String value = XawDialogGetValueString (dialog); mem_addr addr; free (breakpoint_addr); breakpoint_addr = str_copy (value); scan_hex(value, &addr); delete_breakpoint (addr); destroyPopupPrompt (NULL, (XtPointer) dialog, (XtPointer) NULL); } static void listBreakpoint (Widget w, XtPointer client_data, XtPointer call_data) { list_breakpoints (); } static void bkptPromptDestroyed (Widget w, XtPointer client_data, XtPointer call_data) { bkptPopup = NULL; } /* *** Help *** */ static void helpAction (Widget w, XtPointer ignore, XtPointer ignored) { static char * msg = "\nSPIM is a MIPS R2000 simulator.\n\ Copyright (C) 1990 by James R. Larus, larus@cs.wisc.edu\n\n\ quit -- Exit from the simulator\n\ load -- Read a file into memory\n\ run -- Execute a program\n\ step -- Single-step through a program\n\ clear -- Reinitialize registers or memory\n\ set value -- Set the value in register or memory\n\ print -- Print the value in register or memory\n\ breakpoint -- Set or delete a breakpoint\n\ help -- This message\n\ terminals -- Raise or hide terminal windows\n\ mode -- Set SPIM operating modes\n"; write_output (message_out, msg); } static void haltAction (Widget w, XtPointer ignore, XtPointer ignored) { if (!spim_is_running) { XBell(XtDisplay(w), BELL_VOLUME); return; } control_c_seen(); } /* *** Terminal *** */ static void addTerminalButton (Widget parent) { Widget command, menu, entry; Arg args[2]; XtSetArg (args[0], XtNwidth, button_width); command = XtCreateManagedWidget ("terminals", menuButtonWidgetClass, parent, args, ONE); menu = XtCreatePopupShell ("menu", simpleMenuWidgetClass, command, NULL, ZERO); entry = XtCreateManagedWidget ("popup console", smeBSBObjectClass, menu, args, ONE); XtAddCallback (entry, XtNcallback, PopConsole, NULL); entry = XtCreateManagedWidget ("popup terminal2", smeBSBObjectClass, menu, args, ONE); XtAddCallback (entry, XtNcallback, PopTerminal, NULL); } /* *** Mode *** */ static void addModeButton (Widget parent) { Widget command, menu, entry; Arg args[2]; if (spim_is_running) { XBell(XtDisplay(parent), BELL_VOLUME); return; } XtSetArg (args[0], XtNwidth, button_width); command = XtCreateManagedWidget ("mode", menuButtonWidgetClass, parent, args, ONE); menu = XtCreatePopupShell ("menu", simpleMenuWidgetClass, command, NULL, ZERO); XtSetArg (args[0], XtNleftMargin, 20); entry = XtCreateManagedWidget ("bare", smeBSBObjectClass, menu, args, ONE); XtAddCallback (entry, XtNcallback, selectMode, NULL); if (bare_machine) { XtSetArg (args[0], XtNleftBitmap, mark); XtSetValues (entry, args, ONE); } XtSetArg (args[0], XtNleftMargin, 20); entry = XtCreateManagedWidget ("quiet", smeBSBObjectClass, menu, args, ONE); XtAddCallback (entry, XtNcallback, selectMode, NULL); if (quiet) { XtSetArg (args[0], XtNleftBitmap, mark); XtSetValues (entry, args, ONE); } XtSetArg (args[0], XtNleftMargin, 20); entry = XtCreateManagedWidget ("memio", smeBSBObjectClass, menu, args, ONE); XtAddCallback (entry, XtNcallback, selectMode, NULL); if (memio) { XtSetArg (args[0], XtNleftBitmap, mark); XtSetValues (entry, args, ONE); } } static void selectMode (Widget w, XtPointer client_data, XtPointer call_data) { String name = XtName (w); Arg args[1]; if (streq (name, "bare")) { bare_machine = !bare_machine; if (bare_machine) XtSetArg (args[0], XtNleftBitmap, mark); else XtSetArg (args[0], XtNleftBitmap, None); } else if (streq (name, "quiet")) { quiet = !quiet; if (quiet) XtSetArg (args[0], XtNleftBitmap, mark); else XtSetArg (args[0], XtNleftBitmap, None); } else if (streq (name, "memio")) { memio = !memio; if (memio) XtSetArg (args[0], XtNleftBitmap, mark); else XtSetArg (args[0], XtNleftBitmap, None); } XtSetValues (w, args, ONE); } /* *** Continue *** */ static Widget continuePopup = NULL; void ContinuePrompt (int interrupt_seen) { Widget dialog; Arg args[10]; Position x, y; char msg[256]; if (continuePopup != NULL) XtDestroyWidget (continuePopup); XtTranslateCoords (bkptButton, (Position) 0, (Position) 0, &x, &y); XtSetArg (args[0], XtNx, x); XtSetArg (args[1], XtNy, y); continuePopup = XtCreatePopupShell ("prompt", transientShellWidgetClass, bkptButton, args, TWO); XtAddCallback (continuePopup, XtNdestroyCallback, continuePromptDestroyed, (XtPointer) 0); if (interrupt_seen) sprintf (msg, "execution interrupt at 0x%08x", PC); else sprintf (msg, "breakpoint encountered at 0x%08x", PC); XtSetArg (args[0], XtNlabel, msg); dialog = XtCreateManagedWidget ("continue", dialogWidgetClass, continuePopup, args, ONE); XawDialogAddButton (dialog, "continue", continueAction, (XtPointer) dialog); XawDialogAddButton (dialog, "abort command", destroyPopupPrompt, (XtPointer) dialog); confirmAction = continueAction; XtPopup (continuePopup, XtGrabNone); } static void continueAction (Widget w, XtPointer client_data, XtPointer call_data) { Widget dialog = (Widget) client_data; if (spim_is_running) { XBell(XtDisplay(w), BELL_VOLUME); return; } XtPopdown (XtParent (dialog)); destroyPopupPrompt (NULL, (XtPointer) dialog, (XtPointer) NULL); continuePopup = NULL; execute_program (PC, 1, 0, 1); /* Step over breakpoint */ execute_program (PC, DEFAULT_RUN_STEPS - 1, 0, 0); } static void continuePromptDestroyed (Widget w, XtPointer client_data, XtPointer call_data) { continuePopup = NULL; } void Confirm (Widget widget, XEvent *event, String *params, Cardinal *num_params) { Widget dialog = XtParent (widget); (*confirmAction) (widget, (XtPointer) dialog, (XtPointer) NULL); } static void destroyPopupPrompt (Widget w, XtPointer client_data, XtPointer call_data) { Widget popup = XtParent ((Widget) client_data); confirmAction = noop; XtDestroyWidget (popup); } static void noop () { } static Widget popupTwoFieldDialog ( Widget button, String name, String field1_label, String field1_value, String field2_label, String field2_value, String action_name, void (*action) (), String action2_name, void (*action2) (), Widget *field1_text, Widget *field2_text) { Widget popup, form; Widget label, field1, field2; Widget button1, button2, cancelbutton; Widget parent = XtParent (button); Arg args[10]; Position x, y; static XtActionsRec action_table [] = {{"warpToSecondDialog", warpToSecondDialog},}; XtTranslateCoords (button, (Position) 0, (Position) 0, &x, &y); XtSetArg (args[0], XtNx, x); XtSetArg (args[1], XtNy, y); popup = XtCreatePopupShell ("prompt", transientShellWidgetClass, parent, args, TWO); form = XtCreateManagedWidget ("form", formWidgetClass, popup, NULL, ZERO); XtSetArg (args[0], XtNlabel, name); XtSetArg (args[1], XtNborderWidth, 0); label = XtCreateManagedWidget ("label", labelWidgetClass, form, args, TWO); XtSetArg (args[0], XtNfromVert, label); XtSetArg (args[1], XtNborderWidth, 0); XtSetArg (args[2], XtNlabel, field1_label); field1 = XtCreateManagedWidget ("field1", labelWidgetClass, form, args, THREE); XtSetArg (args[0], XtNfromHoriz, field1); XtSetArg (args[1], XtNfromVert, label); XtSetArg (args[2], XtNeditType, "edit"); XtSetArg (args[3], XtNstring, field1_value); XtSetArg (args[4], XtNtype, XawAsciiString); *field1_text = XtCreateManagedWidget ("field1_text", asciiTextWidgetClass, form, args, FIVE); XtOverrideTranslations (*field1_text, XtParseTranslationTable ("#override \n Return:warpToSecondDialog()")); XtAppAddActions (app_context, action_table, XtNumber (action_table)); XtSetArg (args[0], XtNfromVert, *field1_text); XtSetArg (args[1], XtNborderWidth, 0); XtSetArg (args[2], XtNlabel, field2_label); field2 = XtCreateManagedWidget ("field2", labelWidgetClass, form, args, THREE); XtSetArg (args[0], XtNfromHoriz, field1); XtSetArg (args[1], XtNfromVert, *field1_text); XtSetArg (args[2], XtNeditType, "edit"); XtSetArg (args[3], XtNstring, field2_value); XtSetArg (args[4], XtNtype, XawAsciiString); *field2_text = XtCreateManagedWidget ("field2_text", asciiTextWidgetClass, form, args, FIVE); XtOverrideTranslations (*field2_text, XtParseTranslationTable ("#override \n Return: Confirm()")); XtSetArg (args[0], XtNfromVert, *field2_text); button1 = XtCreateManagedWidget (action_name, commandWidgetClass, form, args, ONE); XtAddCallback (button1, XtNcallback, action, (XtPointer) form); if (action2 != NULL) { XtSetArg (args[0], XtNfromHoriz, button1); XtSetArg (args[1], XtNfromVert, *field2_text); button2 = XtCreateManagedWidget (action2_name, commandWidgetClass, form, args, TWO); XtAddCallback (button2, XtNcallback, action2, (XtPointer) form); } XtSetArg (args[0], XtNfromHoriz, action2 == NULL ? button1 : button2); XtSetArg (args[1], XtNfromVert, *field2_text); cancelbutton = XtCreateManagedWidget ("abort command", commandWidgetClass, form, args, TWO); XtAddCallback (cancelbutton, XtNcallback, destroyPopupPrompt, (XtPointer) form); return (popup); } static void warpToSecondDialog ( Widget widget, XEvent *event, String *params, Cardinal *num_params) { Widget form = XtParent (widget); Widget second_dialog; second_dialog = XtNameToWidget (form, "field2_text"); if (second_dialog) XWarpPointer (XtDisplay (second_dialog), None, XtWindow (second_dialog), 0, 0, 0, 0, 0, 10); } char * str_copy (char *str) { return (strcpy ((char *)malloc (strlen (str) + 1), str)); } static int scan_hex(char *str, mem_addr *value) { return (sscanf(str, " 0x%lx", value) || sscanf(str, " 0X%lx", value) || sscanf(str, " %lx", value)); }