fa1769f2452b1e3658c9b7467cd17196c547c6c3
1 /* TUI support I/O functions.
2 Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3 Contributed by Hewlett-Packard Company.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
28 #include "tuiCommand.h"
31 #ifdef ANSI_PROTOTYPES
37 /* The Solaris header files seem to provide no declaration for this at
38 all when __STDC__ is defined. This shouldn't conflict with
40 extern char *tgoto ();
44 /********************************************
45 ** LOCAL STATIC FORWARD DECLS **
46 ********************************************/
47 static void _updateCommandInfo (int);
48 static unsigned int _tuiHandleResizeDuringIO (unsigned int);
51 /*********************************************************************************
52 ** PUBLIC FUNCTIONS **
53 *********************************************************************************/
56 ** tuiPuts_unfiltered().
57 ** Function to put a string to the command window
58 ** When running in TUI mode, this is the "hook"
59 ** for fputs_unfiltered(). That is, all debugger
60 ** output eventually makes it's way to the bottom-level
61 ** routine fputs_unfiltered (main.c), which (in TUI
62 ** mode), calls tuiPuts_unfiltered().
68 struct ui_file
* stream
)
70 tuiPuts_unfiltered (string
, stream
)
72 struct ui_file
*stream
;
75 int len
= strlen (string
);
78 for (i
= 0; i
< len
; i
++)
80 if (string
[i
] == '\n' || string
[i
] == '\r')
84 if ((cmdWin
->detail
.commandInfo
.curch
+ 1) > cmdWin
->generic
.width
)
89 mvwinsch (cmdWin
->generic
.handle
,
90 cmdWin
->detail
.commandInfo
.curLine
,
91 cmdWin
->detail
.commandInfo
.curch
++,
93 wmove (cmdWin
->generic
.handle
,
94 cmdWin
->detail
.commandInfo
.curLine
,
95 cmdWin
->detail
.commandInfo
.curch
);
98 mvwaddch (cmdWin
->generic
.handle
,
99 cmdWin
->detail
.commandInfo
.curLine
,
100 cmdWin
->detail
.commandInfo
.curch
++,
104 tuiRefreshWin (&cmdWin
->generic
);
107 } /* tuiPuts_unfiltered */
109 /* A cover routine for tputs().
110 * tputs() is called from the readline package to put
111 * out strings representing cursor positioning.
112 * In TUI mode (non-XDB-style), tui_tputs() is called instead.
114 * The reason we need to hook tputs() is:
115 * Since the output is going to curses and not to
116 * a raw terminal, we need to intercept these special
117 * sequences, and handle them them here.
119 * This function seems to be correctly handling all sequences
120 * aimed at hpterm's, but there is additional work to do
121 * for xterm's and dtterm's. I abandoned further work on this
122 * in favor of "XDB style". In "XDB style", the command region
123 * looks like terminal, not a curses window, and this routine
124 * is not called. - RT
127 tui_tputs (str
, affcnt
, putfunc
)
130 int (*putfunc
) (int);
132 extern char *rl_prompt
; /* the prompt string */
134 /* This set of globals are defined and initialized
135 * by the readline package.
137 * Note we're assuming tui_tputs() is being called
138 * by the readline package. That's because we're recognizing
139 * that a given string is being passed by
140 * matching the string address against readline's
141 * term_<whatever> global. To make this more general,
142 * we'd have to actually recognize the termcap sequence
143 * inside the string (more work than I want to do). - RT
145 * We don't see or need to handle every one of these here;
146 * this is just the full list defined in readline/readline.c
148 extern char *term_backspace
;
149 extern char *term_clreol
;
150 extern char *term_clrpag
;
151 extern char *term_cr
;
152 extern char *term_dc
;
153 extern char *term_ei
;
154 extern char *term_goto
;
155 extern char *term_ic
;
156 extern char *term_im
;
157 extern char *term_mm
;
158 extern char *term_mo
;
159 extern char *term_up
;
160 extern char *term_scroll_region
;
161 extern char *term_memory_lock
;
162 extern char *term_memory_unlock
;
163 extern char *term_cursor_move
;
164 extern char *visible_bell
;
166 /* Sanity check - if not TUI, just call tputs() */
168 tputs (str
, affcnt
, putfunc
);
170 /* The strings we special-case are handled first */
172 if (str
== term_backspace
)
176 /* We see this on an emacs control-B.
177 * I.e., it's like the left-arrow key (not like the backspace key).
178 * The effect that readline wants when it transmits this
179 * character to us is simply to back up one character
180 * (but not to write a space over the old character).
183 _updateCommandInfo (-1);
184 wmove (cmdWin
->generic
.handle
,
185 cmdWin
->detail
.commandInfo
.curLine
,
186 cmdWin
->detail
.commandInfo
.curch
);
187 wrefresh (cmdWin
->generic
.handle
);
190 else if (str
== term_clreol
)
193 /* Clear to end of line. */
194 wclrtoeol (cmdWin
->generic
.handle
);
195 wrefresh (cmdWin
->generic
.handle
);
198 else if (str
== term_cr
)
201 /* Carriage return */
202 _updateCommandInfo (-cmdWin
->detail
.commandInfo
.curch
);
203 wmove (cmdWin
->generic
.handle
,
204 cmdWin
->detail
.commandInfo
.curLine
,
205 0 /* readline will rewrite the prompt from 0 */ );
206 wrefresh (cmdWin
->generic
.handle
);
209 else if (str
== term_goto
)
212 /* This is actually a tgoto() specifying a character position,
213 * followed by either a term_IC/term_DC which [I think] means
214 * insert/delete one character at that position.
215 * There are complications with this one - need to either
216 * extract the position from the string, or have a backdoor
217 * means of communicating it from ../readline/display.c.
218 * So this one is not yet implemented.
219 * Not doing it seems to have no ill effects on command-line-editing
220 * that I've noticed so far. - RT
224 else if (str
== term_dc
)
227 /* Delete character at current cursor position */
228 wdelch (cmdWin
->generic
.handle
);
229 wrefresh (cmdWin
->generic
.handle
);
232 else if (str
== term_im
)
235 /* Turn on insert mode. */
239 else if (str
== term_ei
)
242 /* Turn off insert mode. */
245 /* Strings we know about but don't handle
246 * specially here are just passed along to tputs().
248 * These are not handled because (as far as I can tell)
249 * they are not actually emitted by the readline package
250 * in the course of doing command-line editing. Some of them
251 * theoretically could be used in the future, in which case we'd
252 * need to handle them.
255 else if (str
== term_ic
|| /* insert character */
256 str
== term_cursor_move
|| /* cursor move */
257 str
== term_clrpag
|| /* clear page */
258 str
== term_mm
|| /* turn on meta key */
259 str
== term_mo
|| /* turn off meta key */
260 str
== term_up
|| /* up one line (not expected) */
261 str
== term_scroll_region
|| /* set scroll region */
262 str
== term_memory_lock
|| /* lock screen above cursor */
263 str
== term_memory_unlock
|| /* unlock screen above cursor */
266 tputs (str
, affcnt
, putfunc
);
269 { /* something else */
270 tputs (str
, affcnt
, putfunc
);
277 ** Wrapper around wgetch with the window in a va_list
281 tui_vwgetch (va_list args
)
290 window
= va_arg (args
, WINDOW
*);
292 return ((unsigned int) wgetch (window
));
298 ** Wrapper around read() with paramets in a va_list
302 tui_vread (va_list args
)
309 int filedes
= va_arg (args
, int);
310 char *buf
= va_arg (args
, char *);
311 int nbytes
= va_arg (args
, int);
313 result
= read (filedes
, buf
, nbytes
);
320 ** Function to perform a read() catching resize events
329 tuiRead (filedes
, buf
, nbytes
)
337 result
= (int) vcatch_errors ((OpaqueFuncPtr
) tui_vread
, filedes
, buf
, nbytes
);
338 *buf
= _tuiHandleResizeDuringIO (*buf
);
346 ** Get a character from the command window.
347 ** This is called from the readline package,
349 ** tuiGetc() [here], called from
350 ** readline code [in ../readline/], called from
351 ** command_line_input() in top.c
361 extern char *rl_prompt
;
362 extern char *rl_line_buffer
;
365 /* Call the curses routine that reads one character */
367 ch
= (unsigned int) vcatch_errors ((OpaqueFuncPtr
) tui_vwgetch
,
368 cmdWin
->generic
.handle
);
370 ch
= wgetch (cmdWin
->generic
.handle
);
372 ch
= _tuiHandleResizeDuringIO (ch
);
374 if (m_isCommandChar (ch
))
375 { /* Handle prev/next/up/down here */
377 ch
= tuiDispatchCtrlChar (ch
);
378 cmdWin
->detail
.commandInfo
.curch
= strlen (rl_prompt
) + rl_point
;
379 tuiTermUnsetup (0, cmdWin
->detail
.commandInfo
.curch
);
381 if (ch
== '\n' || ch
== '\r' || ch
== '\f')
382 cmdWin
->detail
.commandInfo
.curch
= 0;
384 tuiIncrCommandCharCountBy (1);
393 /*elz: this function reads a line of input from the user and
394 puts it in a static buffer. Subsequent calls to this same function
395 obtain one char at the time, providing the caller with a behavior
396 similar to fgetc. When the input is buffered, the backspaces have
397 the needed effect, i.e. ignore the last char active in the buffer */
398 /* so far this function is called only from the query function in
409 static unsigned char _ibuffer
[512];
410 static int index_read
= -1;
411 static int length_of_answer
= -1;
414 if (length_of_answer
== -1)
416 /* this is the first time through, need to read the answer */
419 /* Call the curses routine that reads one character */
420 ch
= (unsigned int) wgetch (cmdWin
->generic
.handle
);
429 while (ch
!= '\r' && ch
!= '\n');
431 length_of_answer
= pos
;
435 ch
= _ibuffer
[index_read
];
438 if (index_read
== length_of_answer
)
440 /*this is the last time through, reset for next query */
442 length_of_answer
= -1;
445 wrefresh (cmdWin
->generic
.handle
);
448 } /* tuiBufferGetc */
452 ** tuiStartNewLines().
459 tuiStartNewLines (numLines
)
465 if (cmdWin
->generic
.viewportHeight
> 1 &&
466 cmdWin
->detail
.commandInfo
.curLine
< cmdWin
->generic
.viewportHeight
)
467 cmdWin
->detail
.commandInfo
.curLine
+= numLines
;
469 scroll (cmdWin
->generic
.handle
);
470 cmdWin
->detail
.commandInfo
.curch
= 0;
471 wmove (cmdWin
->generic
.handle
,
472 cmdWin
->detail
.commandInfo
.curLine
,
473 cmdWin
->detail
.commandInfo
.curch
);
474 tuiRefreshWin (&cmdWin
->generic
);
478 } /* tuiStartNewLines */
482 ** tui_vStartNewLines().
483 ** With numLines in a va_list
490 tui_vStartNewLines (args
)
494 int numLines
= va_arg (args
, int);
496 tuiStartNewLines (numLines
);
499 } /* tui_vStartNewLines */
502 /****************************************************************************
503 ** LOCAL STATIC FUNCTIONS **
504 *****************************************************************************/
508 ** _tuiHandleResizeDuringIO
509 ** This function manages the cleanup when a resize has occured
510 ** From within a call to getch() or read. Returns the character
511 ** to return from getc or read.
515 _tuiHandleResizeDuringIO (
516 unsigned int originalCh
) /* the char just read */
518 _tuiHandleResizeDuringIO (originalCh
)
519 unsigned int originalCh
;
522 if (tuiWinResized ())
524 tuiDo ((TuiOpaqueFuncPtr
) tuiRefreshAll
);
526 tuiSetWinResizedTo (FALSE
);
532 } /* _tuiHandleResizeDuringIO */
536 ** _updateCommandInfo().
537 ** Function to update the command window information.
544 _updateCommandInfo (sizeOfString
)
550 cmdWin
->detail
.commandInfo
.curch
) > cmdWin
->generic
.width
)
552 int newCurch
= sizeOfString
+ cmdWin
->detail
.commandInfo
.curch
;
554 tuiStartNewLines (1);
555 cmdWin
->detail
.commandInfo
.curch
= newCurch
- cmdWin
->generic
.width
;
558 cmdWin
->detail
.commandInfo
.curch
+= sizeOfString
;
561 } /* _updateCommandInfo */
564 /* Looked at in main.c, fputs_unfiltered(), to decide
565 * if it's safe to do standard output to the command window.
567 int tui_owns_terminal
= 0;
569 /* Called to set up the terminal for TUI (curses) I/O.
570 * We do this either on our way "in" to GDB after target
571 * program execution, or else within tuiDo just before
572 * going off to TUI routines.
580 tuiTermSetup (turn_off_echo
)
588 extern char *term_scroll_region
;
589 extern char *term_cursor_move
;
590 extern char *term_memory_lock
;
591 extern char *term_memory_unlock
;
593 /* Turn off echoing, since the TUI does not
594 * expect echoing. Below I only put in the TERMIOS
595 * case, since that is what applies on HP-UX. turn_off_echo
596 * is 1 except for the case where we're being called
597 * on a "quit", in which case we want to leave echo on.
604 tio
.c_lflag
&= ~(ECHO
);
605 tcsetattr (0, TCSANOW
, &tio
);
609 /* Compute the start and end lines of the command
610 * region. (Actually we only use end here)
612 start
= winList
[CMD_WIN
]->generic
.origin
.y
;
613 end
= start
+ winList
[CMD_WIN
]->generic
.height
- 1;
614 endcol
= winList
[CMD_WIN
]->generic
.width
- 1;
616 if (term_memory_unlock
)
619 /* Un-do the effect of the memory lock in terminal_inferior() */
620 tputs (term_memory_unlock
, 1, (int (*) (int)) putchar
);
624 else if (term_scroll_region
)
627 /* Un-do the effect of setting scroll region in terminal_inferior() */
628 /* I'm actually not sure how to do this (we don't know for
629 * sure what the scroll region was *before* we changed it),
630 * but I'll guess that setting it to the whole screen is
631 * the right thing. So, ...
634 /* Set scroll region to be 0..end */
635 buffer
= (char *) tgoto (term_scroll_region
, end
, 0);
636 tputs (buffer
, 1, (int (*) (int)) putchar
);
638 } /* else we're out of luck */
640 /* This is an attempt to keep the logical & physical
641 * cursor in synch, going into curses. Without this,
642 * curses seems to be confused by the fact that
643 * GDB has physically moved the curser on it. One
644 * visible effect of removing this code is that the
645 * locator window fails to get updated and the line
646 * of text that *should* go into the locator window
647 * often goes to the wrong place.
649 /* What's done here is to tell curses to write a ' '
650 * at the bottom right corner of the screen.
651 * The idea is to wind up with the cursor in a known
653 * Note I'm relying on refresh()
654 * only writing what changed (the space),
655 * not the whole screen.
658 move (end
, endcol
- 1);
662 tui_owns_terminal
= 1;
666 /* Called to set up the terminal for target program I/O, meaning I/O
667 * is confined to the command-window area. We also call this on our
668 * way out of tuiDo, thus setting up the terminal this way for
669 * debugger command I/O. */
676 tuiTermUnsetup (turn_on_echo
, to_column
)
685 /* The next bunch of things are from readline */
686 extern char *term_scroll_region
;
687 extern char *term_cursor_move
;
688 extern char *term_memory_lock
;
689 extern char *term_memory_unlock
;
690 extern char *term_se
;
692 /* We need to turn on echoing, since the TUI turns it off */
693 /* Below I only put in the TERMIOS case, since that
694 * is what applies on HP-UX.
701 tio
.c_lflag
|= (ECHO
);
702 tcsetattr (0, TCSANOW
, &tio
);
706 /* Compute the start and end lines of the command
707 * region, as well as the last "real" line of
708 * the region (normally same as end, except when
709 * we're first populating the region)
711 start
= winList
[CMD_WIN
]->generic
.origin
.y
;
712 end
= start
+ winList
[CMD_WIN
]->generic
.height
- 1;
713 curline
= start
+ winList
[CMD_WIN
]->detail
.commandInfo
.curLine
;
715 /* We want to confine target I/O to the command region.
716 * In order to do so, we must either have "memory lock"
717 * (hpterm's) or "scroll regions" (xterm's).
719 if (term_cursor_move
&& term_memory_lock
)
722 /* Memory lock means lock region above cursor.
723 * So first position the cursor, then call memory lock.
725 buffer
= tgoto (term_cursor_move
, 0, start
);
726 tputs (buffer
, 1, (int (*) (int)) putchar
);
727 tputs (term_memory_lock
, 1, (int (*) (int)) putchar
);
730 else if (term_scroll_region
)
733 /* Set the scroll region to the command window */
734 buffer
= tgoto (term_scroll_region
, end
, start
);
735 tputs (buffer
, 1, (int (*) (int)) putchar
);
737 } /* else we can't do anything about target I/O */
739 /* Also turn off standout mode, in case it is on */
741 tputs (term_se
, 1, (int (*) (int)) putchar
);
743 /* Now go to the appropriate spot on the end line */
744 buffer
= tgoto (term_cursor_move
, to_column
, end
);
745 tputs (buffer
, 1, (int (*) (int)) putchar
);
748 tui_owns_terminal
= 0;
749 } /* tuiTermUnsetup */
This page took 0.04389 seconds and 4 git commands to generate.