home *** CD-ROM | disk | FTP | other *** search
- // $Id: options.C,v 1.154 1998/11/29 09:54:07 zeller Exp $ -*- C++ -*-
- // Save and edit DDD options
-
- // Copyright (C) 1996-1998 Technische Universitaet Braunschweig, Germany.
- // Written by Andreas Zeller <zeller@ips.cs.tu-bs.de>.
- //
- // This file is part of DDD.
- //
- // DDD is free software; you can redistribute it and/or
- // modify it under the terms of the GNU General Public
- // License as published by the Free Software Foundation; either
- // version 2 of the License, or (at your option) any later version.
- //
- // DDD 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 DDD -- see the file COPYING.
- // If not, write to the Free Software Foundation, Inc.,
- // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- //
- // DDD is the data display debugger.
- // For details, see the DDD World-Wide-Web page,
- // `http://www.cs.tu-bs.de/softech/ddd/',
- // or send a mail to the DDD developers <ddd@ips.cs.tu-bs.de>.
-
- char options_rcsid[] =
- "$Id: options.C,v 1.154 1998/11/29 09:54:07 zeller Exp $";
-
- #ifdef __GNUG__
- #pragma implementation
- #endif
-
- #include "options.h"
-
- #include "config.h"
-
- #include "AppData.h"
- #include "DataDisp.h"
- #include "DestroyCB.h"
- #include "GDBAgent.h"
- #include "GraphEdit.h"
- #include "SourceView.h"
- #include "TimeOut.h"
- #include "UndoBuffer.h"
- #include "cook.h"
- #include "Command.h"
- #include "comm-manag.h"
- #include "ddd.h"
- #include "file.h"
- #include "filetype.h"
- #include "frame.h"
- #include "gdbinit.h"
- #include "plotter.h"
- #include "post.h"
- #include "resources.h"
- #include "session.h"
- #include "settings.h"
- #include "shell.h"
- #include "status.h"
- #include "string-fun.h"
- #include "verify.h"
- #include "windows.h"
- #include "wm.h"
-
- #include <Xm/Xm.h>
- #include <Xm/Text.h>
- #include <Xm/TextF.h>
- #include <Xm/ToggleB.h>
- #include <Xm/Scale.h>
- #include <Xm/DialogS.h>
- #include <Xm/BulletinB.h>
- #include <Xm/MessageB.h>
- #include <Xm/PanedW.h>
-
- #include <stdio.h>
- #include <fstream.h>
- #include <unistd.h>
- #include <errno.h>
- #include <string.h> // strerror
- #include <time.h> // ctime
-
- #include <limits.h>
- #ifndef ARG_MAX
- #define ARG_MAX 4096
- #endif
-
- #include <signal.h>
-
- #if HAVE_PTRACE
- extern "C" {
- #if HAVE_SYS_PTRACE_H
- #include <sys/ptrace.h>
- #endif
- #if !HAVE_PTRACE_DECL
- extern int ptrace(int request, int pid, int addr, int data);
- #endif
- #if HAVE_SYS_WAIT_H
- #include <sys/wait.h>
- #endif
- }
- #endif
-
- #if HAVE_LINK && !HAVE_LINK_DECL
- extern "C" int link (const char *oldname, const char *newname);
- #endif
-
- #if HAVE_SYMLINK && !HAVE_SYMLINK_DECL
- extern "C" int symlink (const char *oldname, const char *newname);
- #endif
-
- #if !HAVE_POPEN_DECL
- extern "C" FILE *popen(const char *command, const char *mode);
- #endif
- #if !HAVE_PCLOSE_DECL
- extern "C" int pclose(FILE *stream);
- #endif
-
-
- //-----------------------------------------------------------------------------
- // Helper Decls
- //-----------------------------------------------------------------------------
-
- // If the current state file has changed, return true.
- // If MODE is ACKNOWLEDGE, refer to last acknowledgement time.
- // If MODE is ACCESS, refer to last access time (read or write).
- // If RESET is given, reset modification time.
- enum ChangeMode { ACKNOWLEDGE, ACCESS };
- static bool options_file_has_changed(ChangeMode mode, bool reset = false);
-
-
- //-----------------------------------------------------------------------------
- // Source Options
- //-----------------------------------------------------------------------------
-
- void sourceToggleFindWordsOnlyCB (Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.find_words_only = info->set;
-
- if (info->set)
- set_status("Finding only complete words.");
- else
- set_status("Finding arbitrary occurrences.");
-
- update_options();
- }
-
- void sourceToggleFindCaseSensitiveCB (Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.find_case_sensitive = info->set;
-
- if (info->set)
- set_status("Case-sensitive search enabled.");
- else
- set_status("Case-sensitive search disabled.");
-
- update_options();
- }
-
- void sourceToggleCacheSourceFilesCB (Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.cache_source_files = info->set;
-
- if (info->set)
- set_status("Caching source texts.");
- else
- set_status("Not caching source texts. "
- "Source text cache has been cleared.");
-
- update_options();
- }
-
- void sourceToggleCacheMachineCodeCB (Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.cache_machine_code = info->set;
-
- update_options();
-
- if (info->set)
- set_status("Caching machine code.");
- else
- set_status("Not caching machine code. "
- "Machine code cache has been cleared.");
- }
-
- void sourceToggleDisplayLineNumbersCB (Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.display_line_numbers = info->set;
- update_options();
-
- #if 0
- if (info->set)
- set_status("Displaying line numbers.");
- else
- set_status("Not displaying line numbers.");
- #endif
- }
-
- void sourceSetUseSourcePathCB (Widget, XtPointer client_data, XtPointer)
- {
- Boolean state = (int)(long)client_data;
-
- app_data.use_source_path = state;
- string referring_to_sources_using =
- "Referring to sources using ";
-
- if (state)
- set_status(referring_to_sources_using + "full source file paths.");
- else
- set_status(referring_to_sources_using + "source file base names.");
-
- source_arg->set_string(source_view->line_of_cursor());
- update_options();
- }
-
- void sourceSetDisplayGlyphsCB (Widget, XtPointer client_data, XtPointer)
- {
- Boolean state = (int)(long)client_data;
-
- app_data.display_glyphs = state;
-
- update_options();
-
- string displaying = "Displaying breakpoints and positions ";
- if (state)
- set_status(displaying + "as glyphs.");
- else
- set_status(displaying + "as text characters.");
- }
-
- void sourceToggleAllRegistersCB (Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.all_registers = info->set;
-
- if (info->set)
- set_status("Showing all registers.");
- else
- set_status("Showing integer registers only.");
-
- update_options();
- }
-
- void sourceSetTabWidthCB (Widget, XtPointer, XtPointer call_data)
- {
- XmScaleCallbackStruct *info = (XmScaleCallbackStruct *)call_data;
-
- app_data.tab_width = info->value;
- update_options();
-
- set_status("Tab width set to " + itostring(app_data.tab_width) + ".");
- }
-
- void sourceSetSourceIndentCB (Widget, XtPointer, XtPointer call_data)
- {
- XmScaleCallbackStruct *info = (XmScaleCallbackStruct *)call_data;
-
- app_data.indent_source = info->value;
- update_options();
-
- set_status("Source indentation set to " +
- itostring(app_data.indent_source) + ".");
- }
-
- void sourceSetCodeIndentCB (Widget, XtPointer, XtPointer call_data)
- {
- XmScaleCallbackStruct *info = (XmScaleCallbackStruct *)call_data;
-
- app_data.indent_code = info->value;
- update_options();
-
- set_status("Code indentation set to " +
- itostring(app_data.indent_code) + ".");
- }
-
- //-----------------------------------------------------------------------------
- // Graph Options
- //-----------------------------------------------------------------------------
-
- void graphToggleDetectAliasesCB(Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.detect_aliases = info->set;
- string alias_detection = "Alias detection ";
-
- if (info->set)
- set_status(alias_detection + "enabled.");
- else
- set_status(alias_detection + "disabled.");
-
- update_options();
- }
-
- void graphToggleAlign2dArraysCB(Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.align_2d_arrays = info->set;
- string displaying_arrays_as =
- "Two-dimensional arrays will be displayed as ";
-
- if (info->set)
- set_status(displaying_arrays_as + "tables.");
- else
- set_status(displaying_arrays_as + "nested one-dimensional arrays.");
-
- update_options();
- }
-
- void graphToggleShowHintsCB(Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- Arg args[10];
- Cardinal arg = 0;
- XtSetArg(args[arg], XtNshowHints, info->set); arg++;
- XtSetValues(data_disp->graph_edit, args, arg);
-
- if (info->set)
- set_status("Hints on.");
- else
- set_status("Hints off.");
-
- update_options();
- }
-
- void graphToggleShowAnnotationsCB(Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- Arg args[10];
- Cardinal arg = 0;
- XtSetArg(args[arg], XtNshowAnnotations, info->set); arg++;
- XtSetValues(data_disp->graph_edit, args, arg);
-
- if (info->set)
- set_status("Annotations on.");
- else
- set_status("Annotations off.");
-
- data_disp->refresh_titles();
-
- update_options();
- }
-
- void graphToggleShowDependentTitlesCB(Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.show_dependent_display_titles = info->set;
- if (info->set)
- set_status("Dependent titles on.");
- else
- set_status("Dependent titles off.");
-
- data_disp->refresh_titles();
-
- update_options();
- }
-
- void graphToggleClusterDisplaysCB(Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.cluster_displays = info->set;
-
- if (info->set)
- set_status("Display clustering enabled.");
- else
- set_status("Display clustering disabled.");
-
- update_options();
- }
-
- void graphToggleSnapToGridCB(Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- Arg args[10];
- Cardinal arg = 0;
- XtSetArg(args[arg], XtNsnapToGrid, info->set); arg++;
- XtSetValues(data_disp->graph_edit, args, arg);
-
- if (info->set)
- set_status("Snap to grid on.");
- else
- set_status("Snap to grid off.");
-
- update_options();
- }
-
-
- void graphToggleCompactLayoutCB(Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- LayoutMode mode = RegularLayoutMode;
- if (info->set)
- mode = CompactLayoutMode;
-
- Arg args[10];
- Cardinal arg = 0;
- XtSetArg(args[arg], XtNlayoutMode, mode); arg++;
- XtSetValues(data_disp->graph_edit, args, arg);
-
- if (info->set)
- set_status("Compact layout enabled.");
- else
- set_status("Regular layout enabled.");
-
- update_options();
- }
-
- void graphToggleAutoLayoutCB(Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- Arg args[10];
- Cardinal arg = 0;
- XtSetArg(args[arg], XtNautoLayout, info->set); arg++;
- XtSetValues(data_disp->graph_edit, args, arg);
-
- if (info->set)
- set_status("Automatic layout on.");
- else
- set_status("Automatic layout off.");
-
- update_options();
- }
-
- void graphToggleAutoCloseCB(Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.auto_close_data_window = info->set;
-
- if (info->set)
- set_status("Automatic closing on.");
- else
- set_status("Automatic closing off.");
-
- update_options();
- }
-
- void graphSetGridSizeCB (Widget, XtPointer, XtPointer call_data)
- {
- XmScaleCallbackStruct *info = (XmScaleCallbackStruct *)call_data;
-
- Arg args[10];
- Cardinal arg = 0;
-
- if (info->value >= 2)
- {
- XtSetArg(args[arg], XtNgridWidth, info->value); arg++;
- XtSetArg(args[arg], XtNgridHeight, info->value); arg++;
- XtSetArg(args[arg], XtNshowGrid, True); arg++;
- XtSetValues(data_disp->graph_edit, args, arg);
- set_status("Grid size set to " + itostring(info->value) + ".");
- }
- else
- {
- XtSetArg(args[arg], XtNshowGrid, False); arg++;
- XtSetValues(data_disp->graph_edit, args, arg);
- set_status("Grid off.");
- }
-
- update_options();
- }
-
- //-----------------------------------------------------------------------------
- // General Options
- //-----------------------------------------------------------------------------
-
- void dddToggleGroupIconifyCB (Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.group_iconify = info->set;
- string ddd_windows_are_iconified =
- DDD_NAME " windows are iconified ";
-
- if (info->set)
- set_status(ddd_windows_are_iconified + "as a group.");
- else
- set_status(ddd_windows_are_iconified + "separately.");
-
- update_options();
- }
-
- void dddToggleUniconifyWhenReadyCB (Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.uniconify_when_ready = info->set;
-
- if (info->set)
- set_status(DDD_NAME " windows will be uniconified automatically "
- "whenever " DDD_NAME " becomes ready.");
- else
- set_status(DDD_NAME " windows always remain iconified.");
-
- update_options();
- }
-
- void dddSetGlobalTabCompletionCB(Widget, XtPointer client_data, XtPointer)
- {
- Boolean state = (int)(long)client_data;
-
- app_data.global_tab_completion = state;
-
- if (state)
- set_status("TAB key completes in all " DDD_NAME " windows.");
- else
- set_status("TAB key completes in " DDD_NAME " debugger console only.");
-
- update_options();
- }
-
- void dddToggleSeparateExecWindowCB (Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.separate_exec_window = info->set;
- string debugged_program_will_be_executed_in =
- "Debugged program will be executed in ";
-
- if (info->set)
- set_status(debugged_program_will_be_executed_in
- + "a separate execution window.");
- else
- set_status(debugged_program_will_be_executed_in
- + "the " DDD_NAME " debugger console.");
-
- update_options();
- }
-
- void dddToggleCheckGrabsCB (Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.check_grabs = info->set;
-
- if (info->set)
- set_status("Checking for grabs.");
- else
- set_status("Not checking for grabs.");
-
- update_options();
- }
-
- void dddToggleSaveHistoryOnExitCB (Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.save_history_on_exit = info->set;
-
- if (info->set)
- set_status("History will be saved when " DDD_NAME " exits.");
- else
- set_status("History will not be saved.");
-
- update_options();
- }
-
- void dddToggleSuppressWarningsCB (Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.suppress_warnings = info->set;
-
- if (info->set)
- set_status("X Warnings are suppressed.");
- else
- set_status("X Warnings are not suppressed.");
-
- update_options();
- }
-
- void dddToggleWarnIfLockedCB (Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.warn_if_locked = info->set;
-
- if (info->set)
- set_status(DDD_NAME " will warn you "
- "when multiple " DDD_NAME " instances are running.");
- else
- set_status(DDD_NAME " will not warn you "
- "when multiple " DDD_NAME " instances are running.");
-
- update_options();
- }
-
- void dddSetBuiltinPlotWindowCB (Widget, XtPointer client_data, XtPointer)
- {
- if ((int)(long)client_data)
- app_data.plot_term_type = "xlib";
- else
- app_data.plot_term_type = "x11";
-
- string plot_term_type = downcase(app_data.plot_term_type);
-
- if (plot_term_type.contains("xlib", 0))
- {
- set_status("Next plot will be done in builtin " DDD_NAME " window.");
- }
- else if (plot_term_type.contains("x11", 0))
- {
- set_status("Next plot will be done in external " +
- cook(app_data.plot_window_class) + " window.");
- }
- else
- {
- set_status("Next plot will be done in an unknown place.");
- }
-
- clear_plot_window_cache();
- update_options();
- }
-
- void dddToggleButtonTipsCB (Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.button_tips = info->set;
-
- if (info->set)
- set_status("Button tips enabled.");
- else
- set_status("Button tips disabled.");
-
- update_options();
- }
-
- void dddToggleValueTipsCB (Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.value_tips = info->set;
-
- if (info->set)
- set_status("Value tips enabled.");
- else
- set_status("Value tips disabled.");
-
- update_options();
- }
-
- void dddToggleButtonDocsCB (Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.button_docs = info->set;
-
- if (info->set)
- set_status("Button docs enabled.");
- else
- set_status("Button docs disabled.");
-
- update_options();
- }
-
- void dddToggleValueDocsCB (Widget, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.value_docs = info->set;
-
- if (info->set)
- set_status("Value docs enabled.");
- else
- set_status("Value docs disabled.");
-
- update_options();
- }
-
-
- //-----------------------------------------------------------------------------
- // Maintenance
- //-----------------------------------------------------------------------------
-
- void dddSetCrashCB(Widget, XtPointer client_data, XtPointer)
- {
- int state = (int)(long)client_data;
- string msg = "When " DDD_NAME " crashes, ";
-
- switch (state)
- {
- case 0:
- app_data.dump_core = False;
- app_data.debug_core_dumps = False;
- msg += "do nothing.";
- break;
-
- case 1:
- app_data.dump_core = True;
- app_data.debug_core_dumps = False;
- msg += "dump core.";
- break;
-
- case 2:
- app_data.dump_core = True;
- app_data.debug_core_dumps = True;
- msg += "dump core and invoke a debugger.";
- break;
- }
-
- set_status(msg);
- update_options();
- }
-
- void dddClearMaintenanceCB(Widget, XtPointer, XtPointer)
- {
- app_data.maintenance = False;
- update_options();
- }
-
-
- //-----------------------------------------------------------------------------
- // Startup Options
- //-----------------------------------------------------------------------------
-
- static void post_startup_warning(Widget w)
- {
- #if 0
- static bool posted = false;
-
- if (!posted)
- post_warning("This change will only be effective\n"
- "after saving options and restarting " DDD_NAME ".",
- "startup_warning", w);
-
- posted = true;
- #endif
- (void) w; // Use it
- }
-
- static string next_ddd_will_start_with =
- "Next " DDD_NAME " invocation will start-up with ";
-
- void dddSetSeparateWindowsCB (Widget w, XtPointer client_data, XtPointer)
- {
- int state = (int)(long)client_data;
- switch (state)
- {
- case 0:
- app_data.separate_data_window = True;
- app_data.separate_source_window = True;
- app_data.common_toolbar = False;
- break;
-
- case 1:
- app_data.separate_data_window = False;
- app_data.separate_source_window = False;
- app_data.common_toolbar = True;
- break;
-
- case 2:
- app_data.separate_data_window = False;
- app_data.separate_source_window = False;
- app_data.common_toolbar = False;
- break;
- }
-
- if (app_data.separate_data_window || app_data.separate_source_window)
- set_status(next_ddd_will_start_with + "separate windows.");
- else if (app_data.common_toolbar)
- set_status(next_ddd_will_start_with + "one window, one toolbar.");
- else
- set_status(next_ddd_will_start_with + "one window, two toolbars.");
-
- update_options();
- post_startup_warning(w);
- }
-
- void dddSetStatusAtBottomCB (Widget w, XtPointer client_data, XtPointer)
- {
- Boolean state = (int)(long)client_data;
-
- app_data.status_at_bottom = state;
-
- if (state)
- set_status(next_ddd_will_start_with + "status line at bottom.");
- else
- set_status(next_ddd_will_start_with + "status line at top.");
-
- update_options();
- post_startup_warning(w);
- }
-
- void dddSetToolBarCB (Widget w, XtPointer client_data, XtPointer)
- {
- Boolean state = (int)(long)client_data;
-
- app_data.command_toolbar = state;
- string tool_buttons_are_located_in = "Tool buttons are located in ";
-
- if (state)
- set_status(tool_buttons_are_located_in + "command toolbar.");
- else
- set_status(tool_buttons_are_located_in + "command tool.");
-
- update_options();
- post_startup_warning(w);
- }
-
- void dddSetKeyboardFocusPolicyCB (Widget w, XtPointer client_data, XtPointer)
- {
- unsigned char policy = (unsigned char)(int)(long)client_data;
-
- if (policy != XmEXPLICIT && policy != XmPOINTER)
- return;
-
- StatusDelay delay(policy == XmEXPLICIT ?
- "Setting click-to-type keyboard focus policy" :
- "Setting pointer-driven keyboard focus policy");
-
- if (policy == XmPOINTER)
- {
- // Leave old focus on the default button
- Widget default_button = 0;
-
- Widget bulletin_board = w;
- while (bulletin_board != 0 &&
- !XtIsSubclass(bulletin_board, xmBulletinBoardWidgetClass))
- bulletin_board = XtParent(bulletin_board);
-
- if (bulletin_board != 0)
- {
- XtVaGetValues(bulletin_board,
- XmNdefaultButton, &default_button, NULL);
- }
-
- if (default_button == 0)
- default_button = w;
-
- XmProcessTraversal(default_button, XmTRAVERSE_CURRENT);
- }
-
- // Apply to existing shells
- const WidgetArray& shells = Delay::shells();
- for (int i = 0; i < shells.size(); i++)
- {
- Widget shell = shells[i];
- while (shell != 0 && !XtIsSubclass(shell, vendorShellWidgetClass))
- shell = XtParent(shell);
- if (shell != 0)
- XtVaSetValues(shell, XmNkeyboardFocusPolicy, policy, NULL);
- }
-
- // Apply to future shells
- string keyboardFocusPolicy = "*" + string(XmNkeyboardFocusPolicy);
- XrmDatabase target = XtDatabase(XtDisplay(w));
- switch (policy)
- {
- case XmEXPLICIT:
- XrmPutStringResource(&target, keyboardFocusPolicy, "EXPLICIT");
- break;
-
- case XmPOINTER:
- XrmPutStringResource(&target, keyboardFocusPolicy, "POINTER");
- break;
- }
-
- if (policy == XmEXPLICIT)
- {
- // Place new focus on this button
- XmProcessTraversal(w, XmTRAVERSE_CURRENT);
- }
-
- update_options();
- }
-
- void dddSetPannerCB (Widget w, XtPointer client_data, XtPointer)
- {
- Boolean state = (int)(long)client_data;
- app_data.panned_graph_editor = state;
-
- if (state)
- set_status(next_ddd_will_start_with + "a panned graph editor.");
- else
- set_status(next_ddd_will_start_with + "a scrolled graph editor.");
-
- update_options();
- post_startup_warning(w);
- }
-
- static void report_debugger_type()
- {
- DebuggerType type;
- bool type_ok = get_debugger_type(app_data.debugger, type);
-
- if (!type_ok || app_data.auto_debugger)
- {
- set_status("Next " DDD_NAME
- " invocation will determine the debugger automatically.");
- }
- else
- {
- string title;
- if (type == PERL)
- title = "Perl";
- else
- title = upcase(app_data.debugger);
- set_status(next_ddd_will_start_with + "a " + title + " debugger.");
- }
- }
-
- void dddSetDebuggerCB (Widget w, XtPointer client_data, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- if (!info->set)
- return;
-
- DebuggerType type = DebuggerType((int)(long)client_data);
- app_data.debugger = default_debugger(type);
- app_data.auto_debugger = false;
-
- report_debugger_type();
-
- update_options();
- post_startup_warning(w);
- }
-
- void dddToggleAutoDebuggerCB(Widget w, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.auto_debugger = info->set;
-
- report_debugger_type();
-
- update_options();
- post_startup_warning(w);
- }
-
- void dddSetCutCopyPasteBindingsCB (Widget, XtPointer client_data,
- XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- if (!info->set)
- return;
-
- BindingStyle style = BindingStyle((int)(long)client_data);
- app_data.cut_copy_paste_bindings = style;
-
- switch (style)
- {
- case KDEBindings:
- set_status(next_ddd_will_start_with +
- "KDE-style Cut/Copy/Paste bindings.");
- break;
- case MotifBindings:
- set_status(next_ddd_will_start_with +
- "Motif-style Cut/Copy/Paste bindings.");
- break;
- }
-
- update_options();
- }
-
- void dddSetSelectAllBindingsCB (Widget, XtPointer client_data,
- XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- if (!info->set)
- return;
-
- BindingStyle style = BindingStyle((int)(long)client_data);
- app_data.select_all_bindings = style;
-
- switch (style)
- {
- case KDEBindings:
- set_status(next_ddd_will_start_with +
- "KDE-style Select All bindings.");
- break;
- case MotifBindings:
- set_status(next_ddd_will_start_with +
- "Motif-style Select All bindings.");
- break;
- }
-
- update_options();
- }
-
- void dddSetUndoBufferSizeCB(Widget w, XtPointer, XtPointer)
- {
- String s = XmTextFieldGetString(w);
- string value = s;
- XtFree(s);
-
- s = value;
- long val = strtol(value.chars(), &s, 0);
- if (s != value)
- {
- app_data.max_undo_size = int(val * 1000);
- undo_buffer.max_history_size = app_data.max_undo_size;
- }
-
- update_reset_preferences();
- }
-
- void dddClearUndoBufferCB(Widget, XtPointer, XtPointer)
- {
- StatusDelay delay("Clearing undo buffer");
- undo_buffer.clear();
- }
-
- static void toggle_button_appearance(Widget w, Boolean& data,
- XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- data = info->set;
-
- string msg = next_ddd_will_start_with;
- if (app_data.button_images && app_data.button_captions)
- {
- msg += " captioned images";
- }
- else if (app_data.button_images && !app_data.button_captions)
- {
- msg += " images only";
- }
- else if (!app_data.button_images && app_data.button_captions)
- {
- msg += " captions only";
- }
- else if (!app_data.button_images && !app_data.button_captions)
- {
- msg += " ordinary labels";
- }
-
- update_options();
- post_startup_warning(w);
- }
-
- void dddToggleButtonCaptionsCB(Widget w, XtPointer, XtPointer call_data)
- {
- toggle_button_appearance(w, app_data.button_captions, call_data);
- }
-
- void dddToggleButtonImagesCB(Widget w, XtPointer, XtPointer call_data)
- {
- toggle_button_appearance(w, app_data.button_images, call_data);
- }
-
- void dddToggleFlatButtonsCB(Widget w, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.flat_toolbar_buttons = info->set;
- app_data.flat_dialog_buttons = info->set;
-
- if (info->set)
- set_status(next_ddd_will_start_with + "flat buttons.");
- else
- set_status(next_ddd_will_start_with + "raised buttons.");
-
- update_options();
- post_startup_warning(w);
- }
-
- void dddToggleColorButtonsCB(Widget w, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- #if XmVersion >= 2000
- switch (info->set)
- {
- case XmSET:
- app_data.button_color_key = "c";
- app_data.active_button_color_key = "c";
- break;
-
- case XmUNSET:
- app_data.button_color_key = "g";
- app_data.active_button_color_key = "g";
- break;
-
- case XmINDETERMINATE:
- app_data.button_color_key = "g";
- app_data.active_button_color_key = "c";
- break;
- }
- #else
- if (info->set)
- app_data.button_color_key = "c";
- else
- app_data.button_color_key = "g";
- #endif
-
- string button_color_key = app_data.button_color_key;
- string active_button_color_key = app_data.active_button_color_key;
-
- if (button_color_key == 'c' && active_button_color_key == 'c')
- set_status(next_ddd_will_start_with + "color buttons.");
- else if (button_color_key == active_button_color_key)
- set_status(next_ddd_will_start_with + "grey buttons.");
- else // indeterminate
- set_status(next_ddd_will_start_with + "grey/color buttons.");
-
- update_options();
- post_startup_warning(w);
- }
-
- void dddToggleToolbarsAtBottomCB(Widget w, XtPointer, XtPointer call_data)
- {
- XmToggleButtonCallbackStruct *info =
- (XmToggleButtonCallbackStruct *)call_data;
-
- app_data.toolbars_at_bottom = info->set;
-
- if (info->set)
- set_status(next_ddd_will_start_with + "toolbars at bottom.");
- else
- set_status(next_ddd_will_start_with + "toolbars at top.");
-
- update_options();
- post_startup_warning(w);
- }
-
-
- // ---------------------------------------------------------------------------
- // Helpers
- // ---------------------------------------------------------------------------
-
- void dddSetEditCommandCB(Widget w, XtPointer, XtPointer)
- {
- String s = XmTextFieldGetString(w);
- static string command;
- command = s;
- XtFree(s);
-
- app_data.edit_command = command;
- // set_status("Edit Sources command is " + quote(command));
- update_reset_preferences();
- }
-
- void dddSetPlotCommandCB(Widget w, XtPointer, XtPointer)
- {
- String s = XmTextFieldGetString(w);
- static string command;
- command = s;
- XtFree(s);
-
- app_data.plot_command = command;
- // set_status("Edit Sources command is " + quote(command));
- update_reset_preferences();
- }
-
-
- void dddSetGetCoreCommandCB(Widget w, XtPointer, XtPointer)
- {
- String s = XmTextFieldGetString(w);
- static string command;
- command = s;
- XtFree(s);
-
- app_data.get_core_command = command;
- // set_status("Get Core command is " + quote(command));
- update_reset_preferences();
- }
-
-
- void dddSetPSCommandCB(Widget w, XtPointer, XtPointer)
- {
- String s = XmTextFieldGetString(w);
- static string command;
- command = s;
- XtFree(s);
-
- app_data.ps_command = command;
- // set_status("List Processes command is " + quote(command));
- update_reset_preferences();
- }
-
-
- void dddSetTermCommandCB(Widget w, XtPointer, XtPointer)
- {
- String s = XmTextFieldGetString(w);
- static string command;
- command = s;
- XtFree(s);
-
- app_data.term_command = command;
- // set_status("Execution Window command is " + quote(command));
- update_reset_preferences();
- }
-
-
- void dddSetUncompressCommandCB(Widget w, XtPointer, XtPointer)
- {
- String s = XmTextFieldGetString(w);
- static string command;
- command = s;
- XtFree(s);
-
- app_data.uncompress_command = command;
- // set_status("Uncompress command is " + quote(command));
- update_reset_preferences();
- }
-
-
- void dddSetWWWCommandCB(Widget w, XtPointer, XtPointer)
- {
- String s = XmTextFieldGetString(w);
- static string command;
- command = s;
- XtFree(s);
-
- app_data.www_command = command;
- // set_status("Web Browser is " + quote(command));
- update_reset_preferences();
- }
-
-
-
-
-
- // ---------------------------------------------------------------------------
- // Get core
- // ---------------------------------------------------------------------------
-
- static bool copy(const string& src, const string& dest)
- {
- FILE *from = fopen(src, "r");
- if (from == NULL)
- return false;
-
- FILE *to = fopen(dest, "w");
- if (to == NULL)
- return false;
-
- int c;
- while ((c = getc(from)) != EOF)
- putc(c, to);
-
- fclose(from);
- if (fclose(to) == EOF)
- {
- unlink(dest);
- return false;
- }
-
- return true;
- }
-
- static bool move(const string& from, const string& to)
- {
- if (rename(from, to) == 0)
- return true;
-
- if (copy(from, to) && unlink(from) == 0)
- return true;
-
- return false;
- }
-
- // Some GDB implementations want a confirmation when detaching:
- // `Was stopped when attached, make it runnable again? (y or n) '
- // Handle this by turning confirmations off.
- static void get_confirm(const string& complete_answer, void *qu_data)
- {
- bool *flag = (bool *)qu_data;
- *flag = complete_answer.contains("is on");
- }
-
- static void detach()
- {
- bool confirm = true;
- gdb_command("show confirm", 0, get_confirm, &confirm);
- syncCommandQueue();
-
- if (confirm)
- gdb_question("set confirm off");
-
- gdb_question("detach");
-
- if (confirm)
- gdb_question("set confirm on");
- }
-
- // Get core from running program
- static bool _get_core(const string& session, unsigned long flags,
- string& target)
- {
- const bool may_kill = (flags & MAY_KILL);
- const bool may_ptrace = (flags & MAY_PTRACE);
- const bool may_gcore = (flags & MAY_GCORE);
- const bool dont_save = (flags & DONT_SAVE);
- const bool dont_reload_core = (flags & DONT_RELOAD_CORE);
-
- if (!gdb->has_core_files())
- return true; // No need to get core files
-
- create_session_dir(session);
- target = session_core_file(session);
-
- ProgramInfo info;
- if (!info.running)
- {
- // The program is not running.
- if (info.core != "" && info.core != NO_GDB_ANSWER)
- {
- // We already have some core file.
- if (dont_save)
- return true; // Fine
-
- StatusDelay delay("Getting core dump from " + quote(info.core));
- if (info.core == target)
- {
- // It is our target.
- return true;
- }
-
- if (flags & DONT_COPY_CORE)
- {
- target = info.core;
- return true; // Don't copy existing core file
- }
-
- // Remove old target, if any
- unlink(target);
-
- #if HAVE_LINK
- // Try a hard link from current core file to target
- if (link(info.core, target) == 0)
- return true;
- #endif
-
- #if HAVE_SYMLINK
- // Try a symlink link from target to current core file
- if (symlink(info.core, target) == 0)
- return true;
- #endif
-
- // Looks as if we have to copy some large core file. Blechhh.
- return copy(info.core, target);
- }
-
- // Program is not running, and we have no core. Quit.
- return false;
- }
-
- if (may_ptrace)
- {
- #if HAVE_PTRACE_DUMPCORE
- if (gdb->type() == GDB && info.pid > 0)
- {
- // Try getting core via ptrace(2) call
- if (dont_save)
- return true; // Will probably work
-
- // Get new core file from running process
- StatusDelay delay("Getting core dump via ptrace()");
-
- // 1. Stop the program being debugged, using a STOP signal.
- kill(info.pid, SIGSTOP);
-
- // 2. Detach GDB from the debuggee. The debuggee is still stopped.
- detach();
-
- // 3. Attach to the process, using the ptrace() call.
- string gcore_target = target + "." + itostring(info.pid);
- int ok = ptrace(PTRACE_ATTACH, info.pid, 0, 0);
- if (ok < 0)
- {
- cerr << ddd_NAME ": PTRACE_ATTACH: "
- << strerror(errno) << '\n';
- }
- else
- {
- // 4. Get a core file from the running process
- ok = ptrace(PTRACE_DUMPCORE, info.pid,
- int(gcore_target.chars()), 0);
-
- if (ok < 0)
- {
- cerr << ddd_NAME ": PTRACE_DUMPCORE: "
- << strerror(errno) << '\n';
- }
-
- // 5. Detach from the debuggee, leaving it stopped
- kill(info.pid, SIGSTOP);
- ok = ptrace(PTRACE_DETACH, info.pid, 0x1, SIGSTOP);
-
- if (ok < 0)
- {
- cerr << ddd_NAME ": PTRACE_DETACH: "
- << strerror(errno) << '\n';
- }
- }
-
- // 6. Attach GDB to the debuggee again.
- sleep(1);
- gdb_command("attach " + itostring(info.pid));
-
- if (is_core_file(gcore_target) && move(gcore_target, target))
- return true;
-
- delay.outcome = "failed";
- }
- else
- #endif
- if (dont_save)
- return false; // unsupported
- }
-
-
- if (may_gcore)
- {
- // Try `gcore' command
- string gcore = app_data.get_core_command;
- if (gcore != "" && gdb->type() == GDB && info.pid > 0)
- {
- if (dont_save)
- return true; // Will probably work
-
- // Get new core file from running process
- StatusDelay delay("Getting core dump via `gcore'");
-
- // 1. Stop the program being debugged, using a STOP signal.
- // (Other signals may be blocked, caught or ignored)
- kill(info.pid, SIGSTOP);
-
- // 2. Detach GDB from the debuggee. The debuggee is still stopped.
- detach();
-
- // 3. Invoke `gcore' command.
- string gcore_target = target + "." + itostring(info.pid);
- gcore.gsub("@FILE@", target);
- gcore.gsub("@PID@", itostring(info.pid));
- string cmd = sh_command(gcore, true) + " 2>&1";
- ostrstream errs;
- FILE *fp = popen(cmd, "r");
- if (fp != 0)
- {
- kill(info.pid, SIGSTOP);
- int c;
- while ((c = getc(fp)) != EOF)
- {
- kill(info.pid, SIGSTOP);
- errs << c;
- }
- }
- int gcore_status = pclose(fp);
-
- // 4. Since `gcore' restarts the debuggee, stop it again.
- kill(info.pid, SIGSTOP);
- if (gcore_status != 0)
- cerr << string(errs);
-
- // 5. Attach GDB again.
- sleep(1);
- gdb_command("attach " + itostring(info.pid));
-
- if (is_core_file(gcore_target) && move(gcore_target, target))
- return true;
-
- delay.outcome = "failed";
- }
- else
- {
- if (dont_save)
- {
- // No `gcore' support
- return false;
- }
- }
- }
-
-
- // Try direct kill.
- if (may_kill)
- {
- if (dont_save)
- return true; // Will probably work
-
- // Get new core file from running process
- StatusDelay delay("Getting core dump via killing debuggee");
-
- string core = SourceView::full_path("core");
- string core_backup = core + "~";
-
- bool had_a_core_file = false;
- if (is_regular_file(core) || is_directory(core))
- {
- // There is already a file named `core'. Preserve it.
- had_a_core_file = true;
-
- // Try `core~', `core1', `core2', etc., until we find a
- // file name that is not being used yet.
- int suffix = 0;
- for (;;)
- {
- if (!is_regular_file(core_backup)
- && !is_directory(core_backup))
- {
- move(core, core_backup);
- break;
- }
-
- core_backup = "core" + itostring(++suffix);
- }
- }
-
- if (gdb->has_system_calls())
- {
- // Kill the process, hopefully leaving a core file.
-
- // Since g77 catches SIGABRT, we disable its handler first.
- ostrstream os;
- os << "signal(" << SIGABRT << ", "
- << (unsigned long)SIG_DFL << ")";
- gdb_question(gdb->print_command(string(os)));
-
- // Send signal
- gdb_question(gdb->signal_command(SIGABRT));
- }
-
- if (is_core_file(core))
- {
- // It worked. Fine! Move generated core file to target.
- bool ok = move(core, target);
-
- if (!ok)
- {
- // Move failed. Sorry.
- unlink(core);
- }
-
- // Restore the old core file, if any.
- if (had_a_core_file)
- move(core_backup, core);
-
- if (ok && gdb->type() == GDB && !dont_reload_core)
- {
- // Load the core file just saved, such that we can
- // keep on examining data in this session.
- Command c("core " + target);
- c.verbose = false;
- c.prompt = false;
- c.check = true;
- c.priority = COMMAND_PRIORITY_AGAIN;
- gdb_command(c);
- c.command = "graph refresh";
- gdb_command(c);
- c.command = "# reset";
- gdb_command(c);
- syncCommandQueue();
- }
-
- return ok;
- }
-
- // No core file. Sorry.
- delay.outcome = "failed";
-
- // Restore the old core file, if any.
- if (had_a_core_file)
- move(core_backup, core);
- }
-
- return false;
- }
-
- static bool get_core(const string& session, unsigned long flags,
- string& target)
- {
- const bool interact = (flags & MAY_INTERACT);
-
- bool ok = _get_core(session, flags, target);
- if (!ok && interact)
- post_warning("Could not save core file.", "core_missing_warning");
-
- return ok;
- }
-
- static bool must_kill_to_get_core()
- {
- string dummy_target;
- return !_get_core(app_data.session, DONT_SAVE, dummy_target);
- }
-
-
- //-----------------------------------------------------------------------------
- // Reload state
- //-----------------------------------------------------------------------------
-
- static bool options_file_has_changed(ChangeMode mode, bool reset)
- {
- static string last_options_file = "";
- static time_t last_access = 0;
- static time_t last_acknowledge = 0;
-
- string options_file = session_state_file(app_data.session);
-
- if (options_file != last_options_file)
- {
- // Name of state file has changed
- last_options_file = options_file;
- mode = ACCESS;
- reset = true;
- }
-
- time_t modification_time = last_modification_time(options_file);
-
- #if 0
- clog << quote(options_file) << " last modified "
- << ctime(&modification_time);
- #endif
-
- if (reset || last_acknowledge == 0)
- last_acknowledge = modification_time;
- if ((reset && mode == ACCESS) || last_access == 0)
- last_access = modification_time;
-
- time_t& last_time = (mode == ACKNOWLEDGE ? last_acknowledge : last_access);
- if (modification_time > last_time)
- {
- // File has been written since last check
- return true;
- }
-
- // File is unchanged
- return false;
- }
-
- inline String str(String s)
- {
- return s != 0 ? s : "";
- }
-
- static Boolean done_if_idle(XtPointer data)
- {
- if (emptyCommandQueue() && gdb->isReadyWithPrompt())
- {
- update_settings(); // Refresh settings and signals
- update_signals();
-
- delete (Delay *)data;
- return True; // Remove from the list of work procs
- }
-
- return False; // Get called again
- }
-
- static void done(const string&, void *data)
- {
- XtAppAddWorkProc(XtWidgetToApplicationContext(command_shell),
- done_if_idle, data);
- }
-
- static void reload_options()
- {
- static string session;
- session = app_data.session;
-
- string file = session_state_file(session);
-
- StatusDelay *delay_ptr =
- new StatusDelay("Loading options from " + quote(file));
-
- XrmDatabase session_db = XrmGetFileDatabase(file);
-
- Widget toplevel = find_shell();
- while (XtParent(toplevel) != 0)
- toplevel = XtParent(toplevel);
-
- if (session_db == 0)
- {
- delay_ptr->outcome = "failed";
- delete delay_ptr;
- return;
- }
-
- XrmDatabase target = XtDatabase(XtDisplay(toplevel));
-
- #if 0 // This causes core dumps. - AZ
- XrmDatabase default_db = app_defaults(XtDisplay(toplevel));
- if (default_db != 0)
- XrmMergeDatabases(default_db, &target);
- #endif
-
- XrmMergeDatabases(session_db, &target);
-
- XtVaGetApplicationResources(toplevel, (XtPointer)&app_data,
- ddd_resources, ddd_resources_size, NULL);
-
- // Keep session ID across reloads
- app_data.session = session;
-
- save_option_state();
- options_file_has_changed(ACCESS, true);
-
- // Set options and buttons
- update_options();
- update_user_buttons();
-
- // Pop down settings and signals panel (such that GDB settings
- // and signals will be updated from scratch)
- reset_settings();
- reset_signals();
-
- // Load GDB settings. Don't care about init or restart commands here.
- string restart = "";
- string settings;
- switch (gdb->type())
- {
- case GDB:
- settings = str(app_data.gdb_settings);
- break;
-
- case DBX:
- settings = str(app_data.dbx_settings);
- break;
-
- case XDB:
- settings = str(app_data.xdb_settings);
- break;
-
- case JDB:
- settings = str(app_data.jdb_settings);
- break;
-
- case PYDB:
- settings = str(app_data.pydb_settings);
- break;
-
- case PERL:
- settings = str(app_data.perl_settings);
- break;
- }
-
- init_session(restart, settings, app_data.source_init_commands);
-
- // One last command to reload the new settings
- Command c("# reset");
- c.callback = done;
- c.data = (void *)(Delay *)delay_ptr;
- c.priority = COMMAND_PRIORITY_BATCH;
- c.verbose = false;
- c.prompt = false;
- c.check = true;
- gdb_command(c);
- }
-
- static void ReloadOptionsCB(Widget, XtPointer, XtPointer)
- {
- reload_options();
- }
-
- static void DontReloadOptionsCB(Widget, XtPointer, XtPointer)
- {
- // Acknowledge change
- options_file_has_changed(ACKNOWLEDGE, true);
- }
-
- // Pending timer
- static XtIntervalId check_options_timer = 0;
-
- static void CheckOptionsFileCB(XtPointer client_data, XtIntervalId *id)
- {
- (void) id; // Use it
-
- assert(*id == check_options_timer);
- check_options_timer = 0;
-
- if (options_file_has_changed(ACKNOWLEDGE))
- {
- // Options file has changed since last acknowledgement -- offer reload
- static Widget dialog = 0;
-
- if (dialog == 0)
- {
- dialog = verify(XmCreateQuestionDialog(find_shell(),
- "reload_options_dialog",
- 0, 0));
- Delay::register_shell(dialog);
- XtAddCallback(dialog, XmNokCallback, ReloadOptionsCB, 0);
- XtAddCallback(dialog, XmNcancelCallback, DontReloadOptionsCB, 0);
- XtAddCallback(dialog, XmNhelpCallback, ImmediateHelpCB, 0);
- }
-
- if (!XtIsManaged(dialog))
- manage_and_raise(dialog);
- }
-
- if (app_data.check_options > 0)
- {
- // Try again later
- check_options_timer =
- XtAppAddTimeOut(XtWidgetToApplicationContext(find_shell()),
- app_data.check_options * 1000,
- CheckOptionsFileCB, client_data);
- }
- }
-
- void check_options_file()
- {
- if (check_options_timer != 0)
- XtRemoveTimeOut(check_options_timer);
-
- check_options_timer =
- XtAppAddTimeOut(XtWidgetToApplicationContext(find_shell()), 0,
- CheckOptionsFileCB, XtPointer(0));
- }
-
-
- //-----------------------------------------------------------------------------
- // Write state
- //-----------------------------------------------------------------------------
-
- static bool is_fallback_value(string resource, string val)
- {
- XrmDatabase default_db = app_defaults(XtDisplay(find_shell()));
-
- static String app_name = 0;
- static String app_class = 0;
-
- if (app_name == 0)
- XtGetApplicationNameAndClass(XtDisplay(find_shell()),
- &app_name, &app_class);
-
- string str_name = string(app_name) + "*" + resource;
- string str_class = string(app_class) + "*" + resource;
-
- char *type;
- XrmValue xrmvalue;
- Bool success = XrmGetResource(default_db, str_name, str_class,
- &type, &xrmvalue);
- string default_val = NO_GDB_ANSWER;
-
- if (success)
- {
- char *str = (char *)xrmvalue.addr;
- int len = xrmvalue.size - 1; // includes the final `\0'
- default_val = string(str, len);
- }
-
- val = uncook(val);
-
- #if 0
- if (val != default_val)
- {
- clog << resource
- << ": val " << quote(val)
- << " != default " << quote(default_val)
- << '\n';
- }
- #endif
-
- return val == default_val;
- }
-
- static string app_value(string resource, const string& value,
- bool check_default)
- {
- static String app_name = 0;
- static String app_class = 0;
-
- if (app_name == 0)
- XtGetApplicationNameAndClass(XtDisplay(find_shell()),
- &app_name, &app_class);
-
- string prefix = "";
- if (check_default && is_fallback_value(resource, value))
- prefix = "! ";
-
- string s = prefix + app_class;
-
- if (resource.contains(string(app_name) + ".", 0))
- s += resource.from(".") + ": " + value;
- else
- s += "*" + resource + ": " + value;
-
- if (prefix != "")
- s.gsub('\n', "\n" + prefix);
-
- return s;
- }
-
- inline String bool_value(bool value)
- {
- // Since GDB uses `on' and `off' for its settings, we do so, too.
- return value ? "on" : "off";
- }
-
- inline String binding_value(BindingStyle value)
- {
- switch (value)
- {
- case KDEBindings:
- return "KDE";
-
- case MotifBindings:
- return "Motif";
- }
-
- return ""; // Never reached
- }
-
- static string bool_app_value(const string& name, bool value,
- bool check_default = false)
- {
- return app_value(name, bool_value(value), check_default);
- }
-
- static string int_app_value(const string& name, int value,
- bool check_default = false)
- {
- return app_value(name, itostring(value), check_default);
- }
-
- static string binding_app_value(const string& name, BindingStyle value,
- bool check_default = false)
- {
- return app_value(name, binding_value(value), check_default);
- }
-
-
- static string string_app_value(const string& name, String v,
- bool check_default = false)
- {
- if (v == 0)
- return "";
-
- string value = cook(v);
-
- // Xt cannot read `\t', so leave it unchanged.
- value.gsub("\\t", '\t');
-
- if (value.contains("\\n"))
- {
- value.gsub("\\n", "\\n\\\n");
- value.gsub("\\\\n\\\n\\n", "\\\\n\\n");
-
- if (value.contains("\\\n", -1))
- value = value.before(int(value.length()) - 2);
- value = "\\\n" + value;
- }
-
- return app_value(name, value, check_default);
- }
-
- static string widget_value(Widget w, String name, bool check_default = false)
- {
- String value = 0;
- XtVaGetValues(w,
- XtVaTypedArg, name, XtRString, &value, sizeof(value),
- NULL);
-
- return string_app_value(string(XtName(w)) + "." + name, value,
- check_default);
- }
-
- static string paned_widget_size(Widget w, bool height_only = false)
- {
- string s;
- const bool check_default = false;
-
- if (XmIsText(w) || XmIsTextField(w))
- {
- // Store rows and columns
- short columns = 0;
- XtVaGetValues(w, XmNcolumns, &columns, NULL);
- if (!height_only && columns > 0)
- {
- if (s != "")
- s += '\n';
- s += int_app_value(string(XtName(w)) + "." + XmNcolumns, columns,
- check_default);
- }
-
- if (XmIsText(w))
- {
- short rows = 0;
- XtVaGetValues(w, XmNrows, &rows, NULL);
- if (rows > 0)
- {
- if (s != "")
- s += '\n';
- s += int_app_value(string(XtName(w)) + "." + XmNrows, rows,
- check_default);
- }
- }
- }
- else
- {
- // We store the size of the paned child, in order to account
- // for scrolled windows etc.
- Widget ref = w;
- while (XtParent(ref) != 0 && !XmIsPanedWindow(XtParent(ref)))
- ref = XtParent(ref);
- if (XtParent(ref) == 0)
- ref = w;
-
- // Store absolute sizes
- Dimension width = 0;
- Dimension height = 0;
- XtVaGetValues(ref, XmNwidth, &width, XmNheight, &height, NULL);
-
- if (!height_only)
- s += int_app_value(string(XtName(w)) + "." + XmNwidth, width,
- check_default);
-
- if (s != "")
- s += '\n';
- s += int_app_value(string(XtName(w)) + "." + XmNheight, height,
- check_default);
- }
-
- return s;
- }
-
- inline string paned_widget_height(Widget w)
- {
- return paned_widget_size(w, true);
- }
-
- static string widget_geometry(Widget w, bool include_size = false)
- {
- const bool check_default = false;
-
- Dimension width, height;
- XtVaGetValues(w, XmNwidth, &width, XmNheight, &height, NULL);
-
- XWindowAttributes attr;
- XGetWindowAttributes(XtDisplay(w), frame(w), &attr);
-
- ostrstream geometry;
- if (include_size)
- geometry << width << "x" << height;
- geometry << "+" << attr.x << "+" << attr.y;
- string geo(geometry);
-
- return string_app_value(string(XtName(w)) + ".geometry", geo,
- check_default);
- }
-
- bool saving_options_kills_program(unsigned long flags)
- {
- ProgramInfo info;
-
- const bool save_session = (flags & SAVE_SESSION);
- const bool may_kill = (flags & MAY_KILL);
- const bool may_gcore = (flags & MAY_GCORE);
- const bool may_ptrace = (flags & MAY_PTRACE);
- const bool save_core = (flags & SAVE_CORE);
-
- return info.running
- && save_session
- && save_core
- && must_kill_to_get_core()
- && !may_kill
- && !may_gcore
- && !may_ptrace;
- }
-
- bool saving_options_excludes_data(unsigned long flags)
- {
- const bool save_session = (flags & SAVE_SESSION);
- const bool save_core = (flags & SAVE_CORE);
-
- return save_session
- && !save_core
- && data_disp->need_core_to_restore();
- }
-
- bool get_restart_commands(string& restart, unsigned long flags)
- {
- bool ok = true;
- const bool interact = (flags & MAY_INTERACT);
- const bool save_core = (flags & SAVE_CORE);
- const bool save_session = (flags & SAVE_SESSION);
-
- string session =
- (save_session ? app_data.session : (char *)DEFAULT_SESSION);
-
- ProgramInfo info;
- if (info.file == NO_GDB_ANSWER)
- {
- if (interact)
- post_warning("Could not save program name.",
- "program_name_missing_warning");
- ok = false;
- }
-
- // Stream to hold data and breakpoints
- ostrstream rs;
-
- // Get breakpoints and cursor position
- bool breakpoints_ok = source_view->get_state(rs);
- if (!breakpoints_ok)
- {
- if (interact)
- post_warning("Could not save all breakpoints",
- "breakpoint_missing_warning");
- ok = false;
- }
-
- bool core_ok = false;
- string core;
- bool have_data =
- info.running || (info.core != "" && info.core != NO_GDB_ANSWER);
-
- bool have_data_displays = (data_disp->count_data_displays() > 0);
-
- IntArray display_numbers;
- data_disp->get_all_display_numbers(display_numbers);
- bool have_displays = display_numbers.size() > 0;
-
- if (have_data || have_displays)
- {
- // Get displays
- StringArray scopes;
- bool displays_ok = true;
-
- if (have_data && have_data_displays && displays_ok)
- displays_ok = data_disp->get_scopes(scopes);
-
- if (have_data && save_core)
- core_ok = get_core(session, flags, core);
-
- if (displays_ok)
- {
- int target_frame = source_view->get_frame();
- if (target_frame < 0)
- target_frame = 0;
- displays_ok = data_disp->get_state(rs, scopes, target_frame);
- }
-
- if (!displays_ok)
- {
- if (interact)
- post_warning("Could not save all data displays.",
- "displays_missing_warning");
- ok = false;
- }
- }
-
- // Stream to hold exec and core file specs
- ostrstream es;
-
- // Get exec and core file
- switch (gdb->type())
- {
- case GDB:
- es << "set confirm off\n";
- if (info.file != "" && info.file != NO_GDB_ANSWER)
- es << "file " << info.file << '\n';
- if (core_ok)
- es << "core " << core << '\n';
- break;
-
- case DBX:
- if (info.file != "" && info.file != NO_GDB_ANSWER)
- {
- string cmd = gdb->debug_command(info.file);
- if (cmd != "")
- {
- es << cmd;
- if (core_ok)
- es << " " << core;
- es << '\n';
- }
- }
- break;
-
- case PERL:
- if (info.file != "" && info.file != NO_GDB_ANSWER)
- {
- string cmd = gdb->debug_command(info.file);
- if (cmd != "")
- es << cmd << '\n';
- }
- break;
-
- case XDB:
- case JDB:
- case PYDB:
- // FIXME
- break;
- }
-
- restart = string(es) + string(rs) + get_signals(gdb->type());
- restart.gsub(app_data.auto_command_prefix, "@AUTO@");
-
- return ok;
- }
-
- bool save_options(unsigned long flags)
- {
- const bool create = (flags & CREATE_OPTIONS);
- const bool save_session = (flags & SAVE_SESSION);
- const bool save_geometry = (flags & SAVE_GEOMETRY);
- const bool interact = (flags & MAY_INTERACT);
-
- string session =
- (save_session ? app_data.session : (char *)DEFAULT_SESSION);
-
- create_session_dir(session);
- const string file = session_state_file(session);
-
- string options = (save_session ? "session" : "options");
- string status = (create ? "Creating " : "Saving ") + options + " in ";
-
- StatusDelay delay(status + quote(file));
-
- const char delimiter[] = "! DO NOT ADD ANYTHING BELOW THIS LINE";
-
- // Read the file contents into memory ...
- string dddinit;
- ifstream is(file);
- if (is.bad())
- {
- // File not found: create a new one
- dddinit =
- "! " DDD_NAME " initialization file\n"
- "! Enter your personal " DDD_NAME " resources here.\n"
- "\n";
- }
- else
- {
- char line[ARG_MAX + BUFSIZ];
- while (is)
- {
- line[0] = '\0';
- is.getline(line, sizeof(line));
- if (string(line).contains(delimiter, 0))
- break;
- dddinit += line;
- dddinit += '\n';
- }
- }
-
- // ... and write them back again
- bool ok = true;
- string workfile = file + "#";
- ofstream os(workfile);
- if (os.bad())
- {
- workfile = file;
- os.open(workfile);
- }
- if (os.bad())
- {
- if (interact)
- post_error("Cannot save " + options + " in " + quote(workfile),
- "options_save_error");
- delay.outcome = "failed";
- return false;
- }
-
- os << dddinit << delimiter << " -- " DDD_NAME " WILL OVERWRITE IT\n";
- os << string_app_value(XtNdddinitVersion, DDD_VERSION) << '\n';
-
- if (create)
- {
- app_data.dddinit_version = DDD_VERSION;
- os.close();
-
- if (workfile != file && rename(workfile, file) != 0)
- {
- if (interact)
- post_error("Cannot rename " + quote(workfile)
- + " to " + quote(file) + ": " + strerror(errno),
- "options_save_error");
- ok = false;
- unlink(workfile);
- }
-
- return ok;
- }
-
- if (app_data.initial_session != 0)
- {
- os << "\n! Session.\n";
- os << string_app_value(XtNinitialSession, app_data.initial_session)
- << '\n';
- }
-
- os << "\n! Debugger settings.\n";
- os << bool_app_value(XtNautoDebugger, app_data.auto_debugger) << '\n';
- os << string_app_value(XtNdebugger, app_data.debugger) << '\n';
- os << bool_app_value(XtNuseSourcePath, app_data.use_source_path) << '\n';
-
- string gdb_settings = app_data.gdb_settings;
- string dbx_settings = app_data.dbx_settings;
- string xdb_settings = app_data.xdb_settings;
- string jdb_settings = app_data.jdb_settings;
- string pydb_settings = app_data.pydb_settings;
- string perl_settings = app_data.perl_settings;
-
- if (need_settings() || need_save_defines())
- {
- string settings;
- settings += get_settings(gdb->type());
- settings += get_defines(gdb->type());
-
- settings.gsub(app_data.auto_command_prefix, "@AUTO@");
-
- switch (gdb->type())
- {
- case GDB:
- gdb_settings = settings;
- break;
-
- case DBX:
- dbx_settings = settings;
- break;
-
- case XDB:
- xdb_settings = settings;
- break;
-
- case JDB:
- jdb_settings = settings;
- break;
-
- case PYDB:
- pydb_settings = settings;
- break;
-
- case PERL:
- perl_settings = settings;
- break;
- }
- }
-
- os << string_app_value(XtNgdbSettings, gdb_settings, true) << '\n';
- os << string_app_value(XtNdbxSettings, dbx_settings, true) << '\n';
- os << string_app_value(XtNxdbSettings, xdb_settings, true) << '\n';
- os << string_app_value(XtNjdbSettings, jdb_settings, true) << '\n';
- os << string_app_value(XtNpydbSettings, pydb_settings, true) << '\n';
- os << string_app_value(XtNperlSettings, perl_settings, true) << '\n';
-
- os << "\n! Source.\n";
- os << bool_app_value(XtNfindWordsOnly,
- app_data.find_words_only) << '\n';
- os << bool_app_value(XtNfindCaseSensitive,
- app_data.find_case_sensitive) << '\n';
- os << int_app_value(XtNtabWidth,
- app_data.tab_width, true) << '\n';
- os << int_app_value(XtNindentSource,
- app_data.indent_source, true) << '\n';
- os << int_app_value(XtNindentCode,
- app_data.indent_code, true) << '\n';
- os << bool_app_value(XtNcacheSourceFiles,
- app_data.cache_source_files) << '\n';
- os << bool_app_value(XtNcacheMachineCode,
- app_data.cache_machine_code) << '\n';
- os << bool_app_value(XtNdisplayGlyphs,
- app_data.display_glyphs) << '\n';
- os << bool_app_value(XtNdisplayLineNumbers,
- app_data.display_line_numbers) << '\n';
- os << bool_app_value(XtNdisassemble,
- app_data.disassemble) << '\n';
- os << bool_app_value(XtNallRegisters,
- app_data.all_registers) << '\n';
-
- os << "\n! Undo Buffer.\n";
- os << int_app_value(XtNmaxUndoDepth,
- app_data.max_undo_depth, true) << '\n';
- os << int_app_value(XtNmaxUndoSize,
- app_data.max_undo_size, true) << '\n';
-
- // Misc stuff
- os << "\n! Misc preferences.\n";
- unsigned char policy = '\0';
- XtVaGetValues(command_shell, XmNkeyboardFocusPolicy, &policy, NULL);
- switch (policy)
- {
- case XmPOINTER:
- os << string_app_value(string(XmNkeyboardFocusPolicy), "POINTER")
- << '\n';
- break;
- case XmEXPLICIT:
- os << string_app_value(string(XmNkeyboardFocusPolicy), "EXPLICIT")
- << '\n';
- break;
- }
-
- os << bool_app_value(XtNstatusAtBottom,
- app_data.status_at_bottom) << '\n';
- os << bool_app_value(XtNsuppressWarnings,
- app_data.suppress_warnings) << '\n';
- os << bool_app_value(XtNwarnIfLocked,
- app_data.warn_if_locked) << '\n';
- os << bool_app_value(XtNcheckGrabs,
- app_data.check_grabs) << '\n';
- os << bool_app_value(XtNsaveHistoryOnExit,
- app_data.save_history_on_exit) << '\n';
- os << string_app_value(XtNpaperSize,
- app_data.paper_size) << '\n';
- os << bool_app_value(XtNblinkWhileBusy,
- app_data.blink_while_busy) << '\n';
- os << bool_app_value(XtNsplashScreen,
- app_data.splash_screen) << '\n';
- os << bool_app_value(XtNstartupTips,
- app_data.startup_tips) << '\n';
-
- // Keys
- os << "\n! Keys.\n";
- os << bool_app_value(XtNglobalTabCompletion,
- app_data.global_tab_completion) << '\n';
- os << binding_app_value(XtNcutCopyPasteBindings,
- app_data.cut_copy_paste_bindings) << '\n';
- os << binding_app_value(XtNselectAllBindings,
- app_data.select_all_bindings) << '\n';
-
- // Graph editor
- os << "\n! Data.\n";
- os << bool_app_value(XtNpannedGraphEditor,
- app_data.panned_graph_editor) << '\n';
- os << widget_value(data_disp->graph_edit, XtNshowGrid) << '\n';
- os << widget_value(data_disp->graph_edit, XtNsnapToGrid) << '\n';
- os << widget_value(data_disp->graph_edit, XtNshowHints) << '\n';
- os << widget_value(data_disp->graph_edit, XtNshowAnnotations) << '\n';
- os << widget_value(data_disp->graph_edit, XtNlayoutMode) << '\n';
- os << widget_value(data_disp->graph_edit, XtNautoLayout) << '\n';
- os << bool_app_value(XtNshowBaseDisplayTitles,
- app_data.show_base_display_titles) << '\n';
- os << bool_app_value(XtNshowDependentDisplayTitles,
- app_data.show_dependent_display_titles) << '\n';
- os << bool_app_value(XtNautoCloseDataWindow,
- app_data.auto_close_data_window) << '\n';
-
- Dimension grid_width, grid_height;
- XtVaGetValues(data_disp->graph_edit,
- XtNgridWidth, &grid_width,
- XtNgridHeight, &grid_height,
- NULL);
- if (grid_width == grid_height)
- {
- os << int_app_value(string(XtName(data_disp->graph_edit)) + "."
- + XtCGridSize, grid_width, true) << '\n';
- }
- else
- {
- os << int_app_value(string(XtName(data_disp->graph_edit)) + "."
- + XtNgridWidth, grid_width, true) << '\n';
- os << int_app_value(string(XtName(data_disp->graph_edit)) + "."
- + XtNgridHeight, grid_height, true) << '\n';
- }
- os << bool_app_value(XtNdetectAliases, app_data.detect_aliases) << '\n';
- os << bool_app_value(XtNclusterDisplays,app_data.cluster_displays) << '\n';
- os << bool_app_value(XtNalign2dArrays, app_data.align_2d_arrays) << '\n';
-
- // Tips
- os << "\n! Tips.\n";
- os << bool_app_value(XtNbuttonTips,
- app_data.button_tips) << '\n';
- os << bool_app_value(XtNvalueTips,
- app_data.value_tips) << '\n';
- os << bool_app_value(XtNbuttonDocs,
- app_data.button_docs) << '\n';
- os << bool_app_value(XtNvalueDocs,
- app_data.value_docs) << '\n';
-
- // Helpers
- os << "\n! Helpers.\n";
- os << string_app_value(XtNeditCommand, app_data.edit_command, true)
- << '\n';
- os << string_app_value(XtNgetCoreCommand, app_data.get_core_command, true)
- << '\n';
- os << string_app_value(XtNpsCommand, app_data.ps_command, true)
- << '\n';
- os << string_app_value(XtNtermCommand, app_data.term_command, true)
- << '\n';
- os << string_app_value(XtNuncompressCommand, app_data.uncompress_command,
- true) << '\n';
- os << string_app_value(XtNwwwCommand, app_data.www_command, true)
- << '\n';
- os << string_app_value(XtNplotCommand, app_data.plot_command, true)
- << '\n';
- os << string_app_value(XtNplotTermType, app_data.plot_term_type)
- << '\n';
- os << string_app_value(XtNprintCommand, app_data.print_command, true)
- << '\n';
-
- // Toolbar
- os << "\n! Tool Bars.\n";
-
- #if 0 // We cannot change this interactively. Don't save.
- os << bool_app_value(XtNcommonToolBar,
- app_data.common_toolbar) << '\n';
- #endif
-
- os << bool_app_value(XtNtoolbarsAtBottom,
- app_data.toolbars_at_bottom) << '\n';
- os << bool_app_value(XtNbuttonImages,
- app_data.button_images) << '\n';
- os << bool_app_value(XtNbuttonCaptions,
- app_data.button_captions) << '\n';
-
- if (app_data.flat_toolbar_buttons == app_data.flat_dialog_buttons)
- {
- os << bool_app_value(XtCFlatButtons,
- app_data.flat_toolbar_buttons) << '\n';
- }
- else
- {
- os << bool_app_value(XtNflatToolbarButtons,
- app_data.flat_toolbar_buttons) << '\n';
- os << bool_app_value(XtNflatDialogButtons,
- app_data.flat_dialog_buttons) << '\n';
- }
- os << string_app_value(XtNbuttonColorKey,
- app_data.button_color_key) << '\n';
- os << string_app_value(XtNactiveButtonColorKey,
- app_data.active_button_color_key) << '\n';
-
- // Command tool
- os << "\n! Command Tool.\n";
- get_tool_offset();
- os << bool_app_value(XtNcommandToolBar,
- app_data.command_toolbar) << '\n';
- os << int_app_value(XtNtoolRightOffset,
- app_data.tool_right_offset, true) << '\n';
- os << int_app_value(XtNtoolTopOffset,
- app_data.tool_top_offset, true) << '\n';
-
- // Buttons
- os << "\n! Buttons.\n";
- os << string_app_value(XtNconsoleButtons, app_data.console_buttons)
- << '\n';
- os << string_app_value(XtNsourceButtons, app_data.source_buttons)
- << '\n';
- os << string_app_value(XtNdataButtons, app_data.data_buttons)
- << '\n';
- os << bool_app_value(XtNverifyButtons, app_data.verify_buttons)
- << '\n';
-
- // Shortcut expressions
- os << "\n! Display shortcuts.\n";
- {
- StringArray exprs;
- StringArray labels;
- data_disp->get_shortcut_menu(exprs, labels);
- string expr = "";
-
- for (int i = 0; i < exprs.size(); i++)
- {
- if (i > 0)
- expr += '\n';
-
- expr += exprs[i];
-
- if (labels[i] != "")
- {
- expr += string('\t') + app_data.label_delimiter + ' ' +
- labels[i];
- }
- }
-
- string gdb_display_shortcuts = app_data.gdb_display_shortcuts;
- string dbx_display_shortcuts = app_data.dbx_display_shortcuts;
- string xdb_display_shortcuts = app_data.xdb_display_shortcuts;
- string jdb_display_shortcuts = app_data.jdb_display_shortcuts;
- string pydb_display_shortcuts = app_data.pydb_display_shortcuts;
- string perl_display_shortcuts = app_data.perl_display_shortcuts;
-
- switch (gdb->type())
- {
- case GDB: gdb_display_shortcuts = expr; break;
- case DBX: dbx_display_shortcuts = expr; break;
- case XDB: xdb_display_shortcuts = expr; break;
- case JDB: jdb_display_shortcuts = expr; break;
- case PYDB: pydb_display_shortcuts = expr; break;
- case PERL: perl_display_shortcuts = expr; break;
- }
-
- os << string_app_value(XtNgdbDisplayShortcuts,
- gdb_display_shortcuts, true) << '\n';
- os << string_app_value(XtNdbxDisplayShortcuts,
- dbx_display_shortcuts, true) << '\n';
- os << string_app_value(XtNxdbDisplayShortcuts,
- xdb_display_shortcuts, true) << '\n';
- os << string_app_value(XtNjdbDisplayShortcuts,
- jdb_display_shortcuts, true) << '\n';
- os << string_app_value(XtNpydbDisplayShortcuts,
- pydb_display_shortcuts, true) << '\n';
- os << string_app_value(XtNperlDisplayShortcuts,
- perl_display_shortcuts, true) << '\n';
- }
-
- // Fonts
- os << "\n! Fonts.\n";
- os << string_app_value(XtNdefaultFont,
- app_data.default_font, true) << '\n';
- os << string_app_value(XtNvariableWidthFont,
- app_data.variable_width_font, true) << '\n';
- os << string_app_value(XtNfixedWidthFont,
- app_data.fixed_width_font, true) << '\n';
- if (app_data.default_font_size == app_data.variable_width_font_size &&
- app_data.default_font_size == app_data.fixed_width_font_size)
- {
- os << int_app_value(XtCFontSize, app_data.default_font_size)
- << '\n';
- }
- else
- {
- os << int_app_value(XtNdefaultFontSize,
- app_data.default_font_size) << '\n';
- os << int_app_value(XtNvariableWidthFontSize,
- app_data.variable_width_font_size) << '\n';
- os << int_app_value(XtNfixedWidthFontSize,
- app_data.fixed_width_font_size) << '\n';
- }
-
- // Windows.
- os << "\n! Windows.\n";
- os << bool_app_value(XtNopenDataWindow,
- app_data.data_window) << '\n';
- os << bool_app_value(XtNopenSourceWindow,
- app_data.source_window) << '\n';
- os << bool_app_value(XtNopenDebuggerConsole,
- app_data.debugger_console) << '\n';
-
- if (!app_data.separate_source_window && !app_data.separate_data_window)
- {
- os << bool_app_value(XtCSeparate, false) << '\n';
- }
- else if (app_data.separate_source_window && app_data.separate_data_window)
- {
- os << bool_app_value(XtCSeparate, true) << '\n';
- }
- else
- {
- os << bool_app_value(XtNseparateSourceWindow,
- app_data.separate_source_window) << '\n';
- os << bool_app_value(XtNseparateDataWindow,
- app_data.separate_data_window) << '\n';
- }
- os << bool_app_value(XtNseparateExecWindow,
- app_data.separate_exec_window) << '\n';
- os << bool_app_value(XtNgroupIconify,
- app_data.group_iconify) << '\n';
- os << bool_app_value(XtNuniconifyWhenReady,
- app_data.uniconify_when_ready) << '\n';
-
- // Maintenance
- os << "\n! Maintenance.\n";
- os << bool_app_value(XtNdumpCore, app_data.dump_core) << '\n';
- os << bool_app_value(XtNdebugCoreDumps, app_data.debug_core_dumps) << '\n';
-
- // Window sizes.
- os << "\n! Window sizes.\n";
-
- os << paned_widget_height(data_disp->graph_edit) << '\n';
- os << paned_widget_size(source_view->source()) << '\n';
- os << paned_widget_size(source_view->code()) << '\n';
- os << paned_widget_size(gdb_w) << '\n';
-
- if (save_geometry)
- {
- // Widget geometry
- os << "\n! Last " DDD_NAME " geometry.\n";
-
- if (command_shell)
- os << widget_geometry(command_shell) << '\n';
- if (source_view_shell)
- os << widget_geometry(source_view_shell) << '\n';
- if (data_disp_shell)
- os << widget_geometry(data_disp_shell) << '\n';
- }
-
- if (save_session)
- {
- // Restart commands
- os << "\n! Last " DDD_NAME " session.\n";
-
- string restart;
- bool restart_ok = get_restart_commands(restart, flags);
- if (!restart_ok)
- ok = false;
-
- os << string_app_value(XtNrestartCommands, restart) << '\n';
- }
-
- bool saved = true;
-
- os.close();
- if (os.bad())
- {
- if (interact)
- post_error("Cannot save " + options + " in " + quote(workfile),
- "options_save_error");
- ok = saved = false;
- unlink(workfile);
- }
-
- if (workfile != file && rename(workfile, file) != 0)
- {
- if (interact)
- post_error("Cannot rename " + quote(workfile)
- + " to " + quote(file) + ": " + strerror(errno),
- "options_save_error");
- ok = saved = false;
- unlink(workfile);
- }
-
- if (saved)
- {
- save_option_state();
- save_settings_state();
- options_file_has_changed(ACCESS, true);
- }
-
- return ok;
- }
-
- // ---------------------------------------------------------------------------
- // Callbacks
- // ---------------------------------------------------------------------------
-
- static void DoSaveOptionsCB(Widget, XtPointer client_data, XtPointer)
- {
- unsigned long flags = (unsigned long)client_data;
- save_options(flags);
- }
-
- // Save options
- void DDDSaveOptionsCB(Widget w, XtPointer client_data, XtPointer call_data)
- {
- unsigned long flags = (unsigned long)client_data;
- if ((flags & SAVE_SESSION) && app_data.session == DEFAULT_SESSION)
- {
- // No current session; cannot save
- return;
- }
- else if (options_file_has_changed(ACCESS))
- {
- // Options file has changed since last access; request confirmation
- static Widget dialog = 0;
- if (dialog)
- DestroyWhenIdle(dialog);
-
- dialog = verify(XmCreateQuestionDialog(find_shell(w),
- "overwrite_options_dialog",
- 0, 0));
- Delay::register_shell(dialog);
- XtAddCallback(dialog, XmNokCallback, DoSaveOptionsCB,
- XtPointer(flags));
- XtAddCallback(dialog, XmNhelpCallback, ImmediateHelpCB, 0);
-
- manage_and_raise(dialog);
- }
- else if (saving_options_kills_program(flags))
- {
- // Saving session would kill program; request confirmation
- static Widget dialog = 0;
- if (dialog)
- DestroyWhenIdle(dialog);
-
- dialog = verify(XmCreateQuestionDialog(find_shell(w),
- "kill_to_save_dialog",
- 0, 0));
- Delay::register_shell(dialog);
- XtAddCallback(dialog, XmNokCallback, DoSaveOptionsCB,
- XtPointer(flags | MAY_KILL));
- XtAddCallback(dialog, XmNhelpCallback, ImmediateHelpCB, 0);
-
- manage_and_raise(dialog);
- }
- else if (saving_options_excludes_data(flags))
- {
- // Saving session results in data loss; request confirmation
- static Widget dialog = 0;
- if (dialog)
- DestroyWhenIdle(dialog);
-
- dialog = verify(XmCreateQuestionDialog(find_shell(w),
- "data_not_saved_dialog",
- 0, 0));
- Delay::register_shell(dialog);
- XtAddCallback(dialog, XmNokCallback, DoSaveOptionsCB,
- XtPointer(flags));
- XtAddCallback(dialog, XmNhelpCallback, ImmediateHelpCB, 0);
-
- manage_and_raise(dialog);
- }
- else
- {
- DoSaveOptionsCB(w, client_data, call_data);
- }
- }
-