void backward_characterAct(Widget, XEvent*, String*, Cardinal*) { clear_isearch(); XmTextPosition pos = XmTextGetInsertionPosition(gdb_w); if (pos > promptPosition) XmTextSetInsertionPosition(gdb_w, pos - 1); }
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); }
// History viewer static void SelectHistoryCB(Widget, XtPointer, XtPointer call_data) { XmListCallbackStruct *cbs = (XmListCallbackStruct *)call_data; gdb_current_history = cbs->item_position - 1; clear_isearch(); set_line_from_history(); }
// 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)); } }
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 next_historyAct(Widget, XEvent*, String*, Cardinal*) { if (gdb_current_history >= gdb_history.size() - 1) return; gdb_current_history++; clear_isearch(); set_line_from_history(); }
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); }
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); }
// History actions void prev_historyAct(Widget, XEvent*, String*, Cardinal*) { if (gdb_current_history == 0) return; while (gdb_current_history >= gdb_history.size()) gdb_current_history--; gdb_current_history--; clear_isearch(); set_line_from_history(); }
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; } }
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 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); }
// 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); }
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); }
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 beginning_of_lineAct(Widget, XEvent*, String*, Cardinal*) { clear_isearch(); XmTextSetInsertionPosition(gdb_w, promptPosition); }
// Helpers static void clear_isearch_after_motion(XtPointer, XtIntervalId *) { clear_isearch(false); }
// 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; }
// Action: exit i-search void isearch_exitAct(Widget, XEvent *, String *, Cardinal *) { clear_isearch(); }
// 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; }
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); }