Logo Search packages:      
Sourcecode: ddd version File versions  Download package

editing.C

// $Id$ -*- C++ -*-
// DDD command-line actions

// Copyright (C) 1996-1998 Technische Universitaet Braunschweig, Germany.
// Copyright (C) 2000 Universitaet Passau, Germany.
// Written by Andreas Zeller <zeller@gnu.org>.
// 
// 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.gnu.org/software/ddd/',
// or send a mail to the DDD developers <ddd@gnu.org>.

char editing_rcsid[] = 
    "$Id$";

#include "editing.h"

#include "AppData.h"
#include "ArgField.h"
#include "Command.h"
#include "DataDisp.h"
#include "SourceView.h"
#include "TimeOut.h"
#include "args.h"
#include "cmdtty.h"
#include "complete.h"
#include "cook.h"
#include "ctrl.h"
#include "ddd.h"
#include "history.h"
#include "misc.h"
#include "post.h"
#include "regexps.h"
#include "status.h"
#include "string-fun.h"
#include "windows.h"

#include <iostream>
#include <Xm/Xm.h>
#include <Xm/Text.h>
#include <Xm/TextF.h>
#include <Xm/RowColumn.h>     // XmMenuPosition()

// ANSI C++ doesn't like the XtIsRealized() macro
#ifdef XtIsRealized
#undef XtIsRealized
#endif

// True if last input was at gdb prompt
bool gdb_input_at_prompt = false;


//-----------------------------------------------------------------------------
// Helpers
//-----------------------------------------------------------------------------

static void move_to_end_of_line(XtPointer, XtIntervalId *)
{
    XmTextPosition pos = XmTextGetLastPosition(gdb_w);
    XmTextSetInsertionPosition(gdb_w, pos);
    XmTextShowPosition(gdb_w, pos);
}

static XmTextPosition start_of_line()
{
    String str = XmTextGetString(gdb_w);
    string s = str;
    XtFree(str);

    int start = s.index("\n(", -1);
    if (start < 0)
      start = s.index("\n>", -1);
    if (start < 0 && !s.contains('(', 0) && !s.contains('>', 0))
      return XmTextPosition(-1);

    return start + 1;
}


//-----------------------------------------------------------------------------
// Incremental search
//-----------------------------------------------------------------------------

enum ISearchState { ISEARCH_NONE = 0, ISEARCH_NEXT = 1, ISEARCH_PREV = -1 };
static ISearchState isearch_state = ISEARCH_NONE;
static string isearch_string = "";
static string isearch_line = "";
static bool have_isearch_line = false;
static bool isearch_motion_ok = false;

static const char *isearch_prompt         = "(i-search)";
static const char *reverse_isearch_prompt = "(reverse-i-search)";


// Return current line
string current_line()
{
    if (have_isearch_line)
      return isearch_line;

    String str = XmTextGetString(gdb_w);
    string input(str + promptPosition, 
             XmTextGetLastPosition(gdb_w) - promptPosition);
    XtFree(str);
    return input;
}

// Helpers
static void clear_isearch_after_motion(XtPointer, XtIntervalId *)
{
    clear_isearch(false);
}

static void set_isearch_motion_ok(XtPointer client_data, XtIntervalId *)
{
    isearch_motion_ok = bool((long)client_data);
}

// Show prompt according to current mode
static void show_isearch()
{
    XmTextPosition start = start_of_line();
    if (start == XmTextPosition(-1))
      return;

    string prompt;
    switch (isearch_state)
    {
    case ISEARCH_NONE:
      prompt = gdb->prompt();
      break;

    case ISEARCH_NEXT:
      prompt = isearch_prompt;
      break;

    case ISEARCH_PREV:
      prompt = reverse_isearch_prompt;
      break;
    }

    if (isearch_state != ISEARCH_NONE)
      prompt += "`" + cook(isearch_string) + "': ";
    string input = current_line();
    string line  = prompt + input;

    bool old_private_gdb_output = private_gdb_output;
    private_gdb_output = true;
    XmTextReplace(gdb_w, start, XmTextGetLastPosition(gdb_w), XMST(line.chars()));
    promptPosition = start + prompt.length();

    XmTextPosition pos = promptPosition;
    int index = input.index(isearch_string);
    if (isearch_state == ISEARCH_NONE || index < 0)
    {
      XmTextSetHighlight(gdb_w, 0, XmTextGetLastPosition(gdb_w),
                     XmHIGHLIGHT_NORMAL);
    }
    else
    {
      XmTextSetHighlight(gdb_w,
                     0,
                     pos + index,
                     XmHIGHLIGHT_NORMAL);
      XmTextSetHighlight(gdb_w,
                     pos + index, 
                     pos + index + isearch_string.length(),
                     XmHIGHLIGHT_SECONDARY_SELECTED);
      XmTextSetHighlight(gdb_w, 
                     pos + index + isearch_string.length(),
                     XmTextGetLastPosition(gdb_w),
                     XmHIGHLIGHT_NORMAL);
    }

    if (index >= 0)
      pos += index;

    XmTextSetInsertionPosition(gdb_w, pos);
    XmTextShowPosition(gdb_w, pos);
    have_isearch_line = false;
    private_gdb_output = old_private_gdb_output;
}

// When i-search is done, show history position given in client_data
static void isearch_done(XtPointer client_data, XtIntervalId *)
{
    int history = (int)(long)client_data;

    if (history >= 0)
    {
      bool old_private_gdb_output = private_gdb_output;
      private_gdb_output = true;
      goto_history(history);
      have_isearch_line = false;
      private_gdb_output = old_private_gdb_output;
    }

    show_isearch();
}

static void isearch_again(ISearchState new_isearch_state, XEvent *event)
{
    if (!gdb->isReadyWithPrompt())
      return;

    if (isearch_state == ISEARCH_NONE)
      isearch_string = "";

    if (isearch_state == new_isearch_state)
    {
      // Same state - search again
      int history = search_history(isearch_string, int(isearch_state), true);
      if (history < 0)
          XtCallActionProc(gdb_w, "beep", event, 0, 0);
      else
          isearch_done(XtPointer(history), 0);
    }
    else
    {
      isearch_state = new_isearch_state;
      show_isearch();
    }
}

// Action: enter reverse i-search
void isearch_prevAct(Widget, XEvent *event, String *, Cardinal *)
{
    isearch_again(ISEARCH_PREV, event);
}

// Action: enter forward i-search
void isearch_nextAct(Widget, XEvent *event, String *, Cardinal *)
{
    isearch_again(ISEARCH_NEXT, event);
}

// Action: exit i-search
void isearch_exitAct(Widget, XEvent *, String *, Cardinal *)
{
    clear_isearch();
}

// Exit i-search mode and return to normal mode
void clear_isearch(bool reset, bool show)
{
    if (!gdb->isReadyWithPrompt())
      return;

    if (isearch_state != ISEARCH_NONE)
    {
      isearch_state = ISEARCH_NONE;
      if (show)
          show_isearch();

      if (reset)
      {
          set_history_from_line(current_line());
          goto_history();
      }
    }

    isearch_motion_ok = false;
}

void interruptAct(Widget w, XEvent*, String *, Cardinal *)
{
    if (isearch_state != ISEARCH_NONE)
    {
      clear_isearch();
    }
    else
    {
      gdb_keyboard_command = true;
      gdb_command("\003", w);
      gdb_keyboard_command = true;
    }
}

// Handle incremental searches; return true if processed
static bool do_isearch(Widget, XmTextVerifyCallbackStruct *change)
{
    if (isearch_state == ISEARCH_NONE)
      return false;

    string saved_isearch_string = isearch_string;
    bool processed = false;

    if (change->startPos == change->endPos)
    {
      // Character insertion
      string input = string(change->text->ptr, change->text->length);
      if (!input.contains('\n', -1))
      {
          // Add to current search string
          isearch_string += input;
          processed = true;
      }
    }
    else if (change->endPos - change->startPos == 1)
    {
      // Backspace - remove last character from search string
      if (!isearch_string.empty())
          isearch_string.after(int(isearch_string.length()) - 2) = "";
      else
          clear_isearch(true, false);

      processed = true;
    }

    if (processed)
    {
      int history = -1;
      if (isearch_string.empty() || current_line().contains(isearch_string))
      {
          // Search string found in current line
          history = -1;
      }
      else
      {
          history = search_history(isearch_string, int(isearch_state));
          if (history < 0)
          {
            // Search string not found in history
            if (change->event != 0)
                XtCallActionProc(gdb_w, "beep", change->event, 0, 0);
            isearch_string = saved_isearch_string;
          }
      }

      // Make this a no-op
      if (!have_isearch_line)
      {
          isearch_line = current_line();
          have_isearch_line = true;
      }

      // Redraw current line with appropriate prompt.
      XtAppAddTimeOut(XtWidgetToApplicationContext(gdb_w), 0, 
                  isearch_done, XtPointer(history));

      // Upon the next call to gdbMotionCB(), clear ISearch mode,
      // unless it immediately follows this one.
      isearch_motion_ok = true;
      XtAppAddTimeOut(XtWidgetToApplicationContext(gdb_w), 10,
                  set_isearch_motion_ok, XtPointer(false));
    }

    return processed;
}


//-----------------------------------------------------------------------------
// Misc actions
//-----------------------------------------------------------------------------

static bool from_keyboard(XEvent *ev)
{
    return ev == 0 || (ev->type != ButtonPress && ev->type != ButtonRelease);
}

void controlAct(Widget w, XEvent *ev, String *params, Cardinal *num_params)
{
    clear_isearch();

    if (*num_params != 1)
    {
      std::cerr << "gdb-control: usage: gdb-control(CONTROL-CHARACTER)\n";
      return;
    }

    gdb_keyboard_command = from_keyboard(ev);
    gdb_command(ctrl(params[0]), w);
    gdb_keyboard_command = from_keyboard(ev);
}

void commandAct(Widget w, XEvent *ev, String *params, Cardinal *num_params)
{
    clear_isearch();

    if (*num_params != 1)
    {
      std::cerr << "gdb-command: usage: gdb-command(COMMAND)\n";
      return;
    }

    gdb_keyboard_command = from_keyboard(ev);
    gdb_button_command(params[0], w);
    gdb_keyboard_command = from_keyboard(ev);
}

void processAct(Widget w, XEvent *e, String *params, Cardinal *num_params)
{
    if (app_data.source_editing && w == source_view->source())
    {
      // Process event in source window
      string action = "self-insert";   // Default action
      String *action_params      = 0;
      Cardinal num_action_params = 0;
      if (num_params != 0 && *num_params > 0)
      {
          action = params[0];
          action_params = params + 1;
          num_action_params = *num_params - 1;
      }

      XtCallActionProc(w, action.chars(), e, action_params, num_action_params);
      return;
    }

    if (e->type != KeyPress && e->type != KeyRelease)
      return;                 // Forward only keyboard events

    if (!XtIsRealized(gdb_w))
      return;                 // We don't have a console yet

    if (app_data.console_has_focus == Off)
      return;                 // No forwarding

    if (app_data.console_has_focus == Auto && !have_command_window())
      return;                 // The console is closed

    static bool running = false;

    if (running)
      return;                 // We have already entered this procedure

    running = true;

#if 0
    clear_isearch();          // Why would this be needed?  -AZ
#endif

    // Give focus to GDB console
    XmProcessTraversal(gdb_w, XmTRAVERSE_CURRENT);

    // Forward event to GDB console
    Window old_window = e->xkey.window;
    e->xkey.window = XtWindow(gdb_w);
    XtDispatchEvent(e);
    e->xkey.window = old_window;

    // Return focus to original widget
    XmProcessTraversal(w, XmTRAVERSE_CURRENT);

    running = false;
}

void insert_source_argAct(Widget w, XEvent*, String*, Cardinal*)
{
    clear_isearch();

    string arg = source_arg->get_string();
    if (XmIsText(w)) {
      if (XmTextGetEditable(w)) {
          XmTextPosition pos = XmTextGetInsertionPosition(w);
          XmTextReplace(w, pos, pos, XMST(arg.chars()));
      }
    }
    else if (XmIsTextField(w)) {
      if (XmTextFieldGetEditable(w)) {
          XmTextPosition pos = XmTextFieldGetInsertionPosition(w);
          XmTextFieldReplace(w, pos, pos, XMST(arg.chars()));
      }
    }
}

void insert_graph_argAct (Widget w, XEvent *ev, 
                    String *args, Cardinal *num_args)
{
    // Since both fields are synchronized, it doesn't matter which one
    // we insert.
    insert_source_argAct(w, ev, args, num_args);
}

void next_tab_groupAct (Widget w, XEvent*, String*, Cardinal*)
{
    XmProcessTraversal(w, XmTRAVERSE_NEXT_TAB_GROUP);
}

void prev_tab_groupAct (Widget w, XEvent*, String*, Cardinal*)
{
    XmProcessTraversal(w, XmTRAVERSE_PREV_TAB_GROUP);
}

void get_focusAct (Widget w, XEvent*, String*, Cardinal*)
{
    XmProcessTraversal(w, XmTRAVERSE_CURRENT);
}

void select_allAct (Widget w, XEvent *e, String *params, Cardinal *num_params)
{
    switch (app_data.select_all_bindings)
    {
    case KDEBindings:
      XtCallActionProc(w, "select-all", e, params, *num_params);
      break;

    case MotifBindings:
      if (w == gdb_w)
          XtCallActionProc(w, "gdb-beginning-of-line", 
                       e, params, *num_params);
      else
          XtCallActionProc(w, "beginning-of-line", e, params, *num_params);
      break;
    }
}


//-----------------------------------------------------------------------------
// Editing actions
//-----------------------------------------------------------------------------

void beginning_of_lineAct(Widget, XEvent*, String*, Cardinal*)
{
    clear_isearch();
    XmTextSetInsertionPosition(gdb_w, promptPosition);
}

void end_of_lineAct(Widget, XEvent*, String*, Cardinal*)
{
    clear_isearch();
    XmTextSetInsertionPosition(gdb_w, XmTextGetLastPosition(gdb_w));
}

void forward_characterAct(Widget, XEvent *e, 
                    String *params, Cardinal *num_params)
{
    clear_isearch();
    XtCallActionProc(gdb_w, "forward-character", e, params, *num_params);
}

void backward_characterAct(Widget, XEvent*, String*, Cardinal*)
{
    clear_isearch();
    XmTextPosition pos = XmTextGetInsertionPosition(gdb_w);
    if (pos > promptPosition)
      XmTextSetInsertionPosition(gdb_w, pos - 1);
}

void set_current_line(const string& input)
{
    XmTextReplace(gdb_w, promptPosition, XmTextGetLastPosition(gdb_w), 
              XMST(input.chars()));
}

void set_lineAct(Widget, XEvent*, String* params, Cardinal* num_params)
{
    clear_isearch();
    string input = "";
    if (num_params && *num_params > 0)
      input = params[0];
    set_current_line(input);
}

void delete_or_controlAct(Widget, XEvent *e, 
                    String *params, Cardinal *num_params)
{
    clear_isearch();
    string input = current_line();
    strip_trailing_newlines(input);
    if (input.empty())
      XtCallActionProc(gdb_w, "gdb-control", e, params, *num_params);
    else
      XtCallActionProc(gdb_w, "delete-next-character", e, params, *num_params);
}

//-----------------------------------------------------------------------------
// Popup menus
//-----------------------------------------------------------------------------

static MMDesc gdb_popup[] =
{
    {"clear_line",   MMPush, { gdbClearCB, 0 }, 0, 0, 0, 0},
    {"clear_window", MMPush, { gdbClearWindowCB, 0 }, 0, 0, 0, 0},
    MMEnd
};

void popupAct(Widget, XEvent *event, String*, Cardinal*)
{
    static Widget gdb_popup_w = 0;

    if (gdb_popup_w == 0)
    {
      gdb_popup_w = MMcreatePopupMenu(gdb_w, "gdb_popup", gdb_popup);
      MMaddCallbacks(gdb_popup);
      MMaddHelpCallback(gdb_popup, ImmediateHelpCB);
      InstallButtonTips(gdb_popup_w);
    }

    XmMenuPosition(gdb_popup_w, &event->xbutton);
    XtManageChild(gdb_popup_w);
}

//-----------------------------------------------------------------------------
// Callbacks
//-----------------------------------------------------------------------------

// Veto changes before the current input line
void gdbModifyCB(Widget gdb_w, XtPointer, XtPointer call_data)
{
    if (private_gdb_output)
      return;

    XmTextVerifyCallbackStruct *change = 
      (XmTextVerifyCallbackStruct *)call_data;

    if (do_isearch(gdb_w, change))
      return;

    clear_isearch();

    if (change->startPos < promptPosition)
    {
      // Attempt to change text before prompt
#if 0
      // This only works in LessTif.  
      // With Motif, this causes a core dump on Solaris.  - AZ
      change->doit = false;
#else
      // Make it a no-op
      XmTextPosition lastPos = XmTextGetLastPosition(gdb_w);
      XmTextPosition newPos = lastPos;

      if (change->text->length == 0)
      {
          // Deletion
          newPos = promptPosition;
          if (change->event != 0)
            XtCallActionProc(gdb_w, "beep", change->event, 0, 0);
      }
      else
      {
          // Some character
          XtAppAddTimeOut(XtWidgetToApplicationContext(gdb_w), 0, 
                      move_to_end_of_line, XtPointer(0));
      }
      change->startPos = change->endPos = 
          change->newInsert = change->currInsert = newPos;
#endif
      return;
    }

    // Make sure newlines are always inserted at the end of the line
    if (change->startPos == change->endPos &&
      (change->startPos < promptPosition || 
       (change->text->length == 1 && change->text->ptr[0] == '\n')))
    {
      // Add any text at end of text window
      XmTextPosition lastPos = XmTextGetLastPosition(gdb_w);
      change->newInsert = change->startPos = change->endPos = lastPos;
      
      XtAppAddTimeOut(XtWidgetToApplicationContext(gdb_w), 0, 
                  move_to_end_of_line, XtPointer(0));
    }
}

// Veto key-based cursor movements before current line
void gdbMotionCB(Widget, XtPointer, XtPointer call_data)
{
    if (private_gdb_output)
      return;

    XmTextVerifyCallbackStruct *change = 
      (XmTextVerifyCallbackStruct *)call_data;

    if (isearch_state != ISEARCH_NONE)
    {
      if (!isearch_motion_ok)
      {
          XtAppAddTimeOut(XtWidgetToApplicationContext(gdb_w), 0, 
                      clear_isearch_after_motion, XtPointer(0));
      }
      isearch_motion_ok = false;
    }

    if (change->event != 0
      && (change->event->type == KeyPress 
          || change->event->type == KeyRelease))
    {
      if (change->newInsert < promptPosition)
      {
          // We are before the current prompt: don't change the cursor
          // position if a key was pressed.
#if 0
          // With Motif, this causes a core dump on Solaris.  - AZ
          change->doit = false;
#else
          // Make it a no-op.
          XtCallActionProc(gdb_w, "beep", change->event, 0, 0);
          XtAppAddTimeOut(XtWidgetToApplicationContext(gdb_w), 0, 
                      move_to_end_of_line, 0);
#endif
      }
    }
}

// Send completed lines to GDB
void gdbChangeCB(Widget w, XtPointer, XtPointer)
{
    if (private_gdb_output)
      return;

    string input = current_line();

    bool at_prompt = gdb_input_at_prompt;
    if (at_prompt)
      input.gsub("\\\n", "");

    int newlines = input.freq('\n');
    string *lines = new string[newlines + 1];
    split(input, lines, newlines, '\n');

    private_gdb_input = true;

    if (newlines == 0 || (gdb_input_at_prompt && input.contains('\\', -1)))
    {
      // No newline found - line is still incomplete
      set_history_from_line(input, true);
    }
    else
    {
      // Process entered lines
      clear_isearch();
      promptPosition = XmTextGetLastPosition(w);
      for (int i = 0; i < newlines; i++)
      {
          string cmd = lines[i];
          tty_out(cmd + "\n");

          if (gdb_input_at_prompt)
          {
            if (cmd.matches(rxwhite) || cmd.empty())
            {
                // Empty line: repeat last command
                cmd = last_command_from_history();
            }
            else
            {
                // Add new command to history
                add_to_history(cmd);
            }
          }

          if (at_prompt)
          {
            // We're typing at the GDB prompt: place CMD in command queue
            gdb_command(cmd, w);
          }
          else
          {
            // Pass anything else right to GDB, clearing the command queue.
            clearCommandQueue();
            gdb->send_user_ctrl_cmd(cmd + "\n");
          }
      }
    }

    private_gdb_input = false;

    delete[] lines;
}

//-----------------------------------------------------------------------------
// Callbacks
//-----------------------------------------------------------------------------

void gdbCommandCB(Widget w, XtPointer client_data, XtPointer call_data)
{
    clear_isearch();
    XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct *)call_data;
    if (cbs->event == 0)
      return;

    gdb_button_command((String)client_data, w);

    gdb_keyboard_command = from_keyboard(cbs->event);
}

void gdb_button_command(const string& command, Widget origin)
{
    if (command.contains("..."))
    {
      set_current_line(command.before("...") + " ");
    }
    else
    {
      string c = command;
      c.gsub("()", source_arg->get_string());
      if (add_running_arguments(c, origin))
          gdb_command(c, origin);
    }
}

void gdbPrevCB  (Widget w, XtPointer, XtPointer call_data)
{
    XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct *)call_data;
    if (cbs->event == 0)
      return;

    Cardinal zero = 0;
    prev_historyAct(w, cbs->event, 0, &zero);
}

void gdbNextCB  (Widget w, XtPointer, XtPointer call_data)
{
    XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct *)call_data;
    if (cbs->event == 0)
      return;

    Cardinal zero = 0;
    next_historyAct(w, cbs->event, 0, &zero);
}

void gdbISearchPrevCB  (Widget w, XtPointer, XtPointer call_data)
{
    XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct *)call_data;
    if (cbs->event == 0)
      return;

    Cardinal zero = 0;
    isearch_prevAct(w, cbs->event, 0, &zero);
}

void gdbISearchNextCB  (Widget w, XtPointer, XtPointer call_data)
{
    XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct *)call_data;
    if (cbs->event == 0)
      return;

    Cardinal zero = 0;
    isearch_nextAct(w, cbs->event, 0, &zero);
}

void gdbISearchExitCB  (Widget w, XtPointer, XtPointer call_data)
{
    XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct *)call_data;
    if (cbs->event == 0)
      return;

    Cardinal zero = 0;
    isearch_exitAct(w, cbs->event, 0, &zero);
}

void gdbClearCB  (Widget, XtPointer, XtPointer)
{
    set_current_line("");
}

// Remove any text up to the last GDB prompt
void gdbClearWindowCB(Widget, XtPointer, XtPointer)
{
    XmTextPosition start = start_of_line();
    if (start == XmTextPosition(-1))
      return;

    private_gdb_output = true;

    XmTextReplace(gdb_w, 0, start, XMST(""));

    promptPosition  -= start;
    messagePosition -= start;
    XmTextSetInsertionPosition(gdb_w, XmTextGetLastPosition(gdb_w));

    private_gdb_output = false;
}

void gdbCompleteCB  (Widget w, XtPointer, XtPointer call_data)
{
    if (!gdb->isReadyWithPrompt())
    {
      post_gdb_busy(w);
      return;
    }

    clear_isearch();
    XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct *)call_data;
    if (cbs->event == 0)
      return;

    Cardinal zero = 0;
    end_of_lineAct(gdb_w, cbs->event, 0, &zero);
    complete_commandAct(gdb_w, cbs->event, 0, &zero);
}

// Use this for push buttons
void gdbApplyCB(Widget w, XtPointer, XtPointer call_data)
{
    if (!gdb->isReadyWithPrompt())
    {
      post_gdb_busy(w);
      return;
    }

    clear_isearch();
    XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct *)call_data;
    if (cbs->event == 0)
      return;

    Cardinal zero = 0;
    end_of_lineAct(gdb_w, cbs->event, 0, &zero);
    XtCallActionProc(gdb_w, "process-return", cbs->event, 0, zero);
}

// Use this for selection boxes
void gdbApplySelectionCB(Widget w, XtPointer, XtPointer call_data)
{
    if (!gdb->isReadyWithPrompt())
    {
      post_gdb_busy(w);
      return;
    }

    clear_isearch();
    XmSelectionBoxCallbackStruct *cbs = 
      (XmSelectionBoxCallbackStruct *)call_data;
    if (cbs->event == 0)
      return;

    Cardinal zero = 0;
    end_of_lineAct(gdb_w, cbs->event, 0, &zero);
    XtCallActionProc(gdb_w, "process-return", cbs->event, 0, zero);
}

Generated by  Doxygen 1.6.0   Back to index