]>
git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/tui/tuiIO.c
3 ** This module contains functions to support i/o in the TUI
13 #include "tuiCommand.h"
16 #ifdef ANSI_PROTOTYPES
22 /* The Solaris header files seem to provide no declaration for this at
23 all when __STDC__ is defined. This shouldn't conflict with
25 extern char *tgoto ();
29 /********************************************
30 ** LOCAL STATIC FORWARD DECLS **
31 ********************************************/
32 static void _updateCommandInfo
PARAMS ((int));
33 static unsigned int _tuiHandleResizeDuringIO
PARAMS ((unsigned int));
36 /*********************************************************************************
37 ** PUBLIC FUNCTIONS **
38 *********************************************************************************/
41 ** tuiPuts_unfiltered().
42 ** Function to put a string to the command window
43 ** When running in TUI mode, this is the "hook"
44 ** for fputs_unfiltered(). That is, all debugger
45 ** output eventually makes it's way to the bottom-level
46 ** routine fputs_unfiltered (main.c), which (in TUI
47 ** mode), calls tuiPuts_unfiltered().
55 tuiPuts_unfiltered (string
, stream
)
60 int len
= strlen (string
);
63 for (i
= 0; i
< len
; i
++)
65 if (string
[i
] == '\n' || string
[i
] == '\r')
69 if ((cmdWin
->detail
.commandInfo
.curch
+ 1) > cmdWin
->generic
.width
)
74 mvwinsch (cmdWin
->generic
.handle
,
75 cmdWin
->detail
.commandInfo
.curLine
,
76 cmdWin
->detail
.commandInfo
.curch
++,
78 wmove (cmdWin
->generic
.handle
,
79 cmdWin
->detail
.commandInfo
.curLine
,
80 cmdWin
->detail
.commandInfo
.curch
);
83 mvwaddch (cmdWin
->generic
.handle
,
84 cmdWin
->detail
.commandInfo
.curLine
,
85 cmdWin
->detail
.commandInfo
.curch
++,
89 tuiRefreshWin (&cmdWin
->generic
);
92 } /* tuiPuts_unfiltered */
94 /* A cover routine for tputs().
95 * tputs() is called from the readline package to put
96 * out strings representing cursor positioning.
97 * In TUI mode (non-XDB-style), tui_tputs() is called instead.
99 * The reason we need to hook tputs() is:
100 * Since the output is going to curses and not to
101 * a raw terminal, we need to intercept these special
102 * sequences, and handle them them here.
104 * This function seems to be correctly handling all sequences
105 * aimed at hpterm's, but there is additional work to do
106 * for xterm's and dtterm's. I abandoned further work on this
107 * in favor of "XDB style". In "XDB style", the command region
108 * looks like terminal, not a curses window, and this routine
109 * is not called. - RT
112 tui_tputs (str
, affcnt
, putfunc
)
115 int (*putfunc
) PARAMS ((int));
117 extern char *rl_prompt
; /* the prompt string */
119 /* This set of globals are defined and initialized
120 * by the readline package.
122 * Note we're assuming tui_tputs() is being called
123 * by the readline package. That's because we're recognizing
124 * that a given string is being passed by
125 * matching the string address against readline's
126 * term_<whatever> global. To make this more general,
127 * we'd have to actually recognize the termcap sequence
128 * inside the string (more work than I want to do). - RT
130 * We don't see or need to handle every one of these here;
131 * this is just the full list defined in readline/readline.c
133 extern char *term_backspace
;
134 extern char *term_clreol
;
135 extern char *term_clrpag
;
136 extern char *term_cr
;
137 extern char *term_dc
;
138 extern char *term_ei
;
139 extern char *term_goto
;
140 extern char *term_ic
;
141 extern char *term_im
;
142 extern char *term_mm
;
143 extern char *term_mo
;
144 extern char *term_up
;
145 extern char *term_scroll_region
;
146 extern char *term_memory_lock
;
147 extern char *term_memory_unlock
;
148 extern char *term_cursor_move
;
149 extern char *visible_bell
;
151 /* Sanity check - if not TUI, just call tputs() */
153 tputs (str
, affcnt
, putfunc
);
155 /* The strings we special-case are handled first */
157 if (str
== term_backspace
)
161 /* We see this on an emacs control-B.
162 * I.e., it's like the left-arrow key (not like the backspace key).
163 * The effect that readline wants when it transmits this
164 * character to us is simply to back up one character
165 * (but not to write a space over the old character).
168 _updateCommandInfo (-1);
169 wmove (cmdWin
->generic
.handle
,
170 cmdWin
->detail
.commandInfo
.curLine
,
171 cmdWin
->detail
.commandInfo
.curch
);
172 wrefresh (cmdWin
->generic
.handle
);
175 else if (str
== term_clreol
)
178 /* Clear to end of line. */
179 wclrtoeol (cmdWin
->generic
.handle
);
180 wrefresh (cmdWin
->generic
.handle
);
183 else if (str
== term_cr
)
186 /* Carriage return */
187 _updateCommandInfo (-cmdWin
->detail
.commandInfo
.curch
);
188 wmove (cmdWin
->generic
.handle
,
189 cmdWin
->detail
.commandInfo
.curLine
,
190 0 /* readline will rewrite the prompt from 0 */ );
191 wrefresh (cmdWin
->generic
.handle
);
194 else if (str
== term_goto
)
197 /* This is actually a tgoto() specifying a character position,
198 * followed by either a term_IC/term_DC which [I think] means
199 * insert/delete one character at that position.
200 * There are complications with this one - need to either
201 * extract the position from the string, or have a backdoor
202 * means of communicating it from ../readline/display.c.
203 * So this one is not yet implemented.
204 * Not doing it seems to have no ill effects on command-line-editing
205 * that I've noticed so far. - RT
209 else if (str
== term_dc
)
212 /* Delete character at current cursor position */
213 wdelch (cmdWin
->generic
.handle
);
214 wrefresh (cmdWin
->generic
.handle
);
217 else if (str
== term_im
)
220 /* Turn on insert mode. */
224 else if (str
== term_ei
)
227 /* Turn off insert mode. */
230 /* Strings we know about but don't handle
231 * specially here are just passed along to tputs().
233 * These are not handled because (as far as I can tell)
234 * they are not actually emitted by the readline package
235 * in the course of doing command-line editing. Some of them
236 * theoretically could be used in the future, in which case we'd
237 * need to handle them.
240 else if (str
== term_ic
|| /* insert character */
241 str
== term_cursor_move
|| /* cursor move */
242 str
== term_clrpag
|| /* clear page */
243 str
== term_mm
|| /* turn on meta key */
244 str
== term_mo
|| /* turn off meta key */
245 str
== term_up
|| /* up one line (not expected) */
246 str
== term_scroll_region
|| /* set scroll region */
247 str
== term_memory_lock
|| /* lock screen above cursor */
248 str
== term_memory_unlock
|| /* unlock screen above cursor */
251 tputs (str
, affcnt
, putfunc
);
254 { /* something else */
255 tputs (str
, affcnt
, putfunc
);
262 ** Wrapper around wgetch with the window in a va_list
266 tui_vwgetch (va_list args
)
275 window
= va_arg (args
, WINDOW
*);
277 return ((unsigned int) wgetch (window
));
283 ** Wrapper around read() with paramets in a va_list
287 tui_vread (va_list args
)
294 int filedes
= va_arg (args
, int);
295 char *buf
= va_arg (args
, char *);
296 int nbytes
= va_arg (args
, int);
298 result
= read (filedes
, buf
, nbytes
);
305 ** Function to perform a read() catching resize events
314 tuiRead (filedes
, buf
, nbytes
)
322 result
= (int) vcatch_errors ((OpaqueFuncPtr
) tui_vread
, filedes
, buf
, nbytes
);
323 *buf
= _tuiHandleResizeDuringIO (*buf
);
331 ** Get a character from the command window.
332 ** This is called from the readline package,
334 ** tuiGetc() [here], called from
335 ** readline code [in ../readline/], called from
336 ** command_line_input() in top.c
346 extern char *rl_prompt
;
347 extern char *rl_line_buffer
;
350 /* Call the curses routine that reads one character */
352 ch
= (unsigned int) vcatch_errors ((OpaqueFuncPtr
) tui_vwgetch
,
353 cmdWin
->generic
.handle
);
355 ch
= wgetch (cmdWin
->generic
.handle
);
357 ch
= _tuiHandleResizeDuringIO (ch
);
359 if (m_isCommandChar (ch
))
360 { /* Handle prev/next/up/down here */
362 ch
= tuiDispatchCtrlChar (ch
);
363 cmdWin
->detail
.commandInfo
.curch
= strlen (rl_prompt
) + rl_point
;
364 tuiTermUnsetup (0, cmdWin
->detail
.commandInfo
.curch
);
366 if (ch
== '\n' || ch
== '\r' || ch
== '\f')
367 cmdWin
->detail
.commandInfo
.curch
= 0;
369 tuiIncrCommandCharCountBy (1);
378 /*elz: this function reads a line of input from the user and
379 puts it in a static buffer. Subsequent calls to this same function
380 obtain one char at the time, providing the caller with a behavior
381 similar to fgetc. When the input is buffered, the backspaces have
382 the needed effect, i.e. ignore the last char active in the buffer */
383 /* so far this function is called only from the query function in
394 static unsigned char _ibuffer
[512];
395 static int index_read
= -1;
396 static int length_of_answer
= -1;
399 if (length_of_answer
== -1)
401 /* this is the first time through, need to read the answer */
404 /* Call the curses routine that reads one character */
405 ch
= (unsigned int) wgetch (cmdWin
->generic
.handle
);
414 while (ch
!= '\r' && ch
!= '\n');
416 length_of_answer
= pos
;
420 ch
= _ibuffer
[index_read
];
423 if (index_read
== length_of_answer
)
425 /*this is the last time through, reset for next query */
427 length_of_answer
= -1;
430 wrefresh (cmdWin
->generic
.handle
);
433 } /* tuiBufferGetc */
437 ** tuiStartNewLines().
444 tuiStartNewLines (numLines
)
450 if (cmdWin
->generic
.viewportHeight
> 1 &&
451 cmdWin
->detail
.commandInfo
.curLine
< cmdWin
->generic
.viewportHeight
)
452 cmdWin
->detail
.commandInfo
.curLine
+= numLines
;
454 scroll (cmdWin
->generic
.handle
);
455 cmdWin
->detail
.commandInfo
.curch
= 0;
456 wmove (cmdWin
->generic
.handle
,
457 cmdWin
->detail
.commandInfo
.curLine
,
458 cmdWin
->detail
.commandInfo
.curch
);
459 tuiRefreshWin (&cmdWin
->generic
);
463 } /* tuiStartNewLines */
467 ** tui_vStartNewLines().
468 ** With numLines in a va_list
475 tui_vStartNewLines (args
)
479 int numLines
= va_arg (args
, int);
481 tuiStartNewLines (numLines
);
484 } /* tui_vStartNewLines */
487 /****************************************************************************
488 ** LOCAL STATIC FUNCTIONS **
489 *****************************************************************************/
493 ** _tuiHandleResizeDuringIO
494 ** This function manages the cleanup when a resize has occured
495 ** From within a call to getch() or read. Returns the character
496 ** to return from getc or read.
500 _tuiHandleResizeDuringIO (
501 unsigned int originalCh
) /* the char just read */
503 _tuiHandleResizeDuringIO (originalCh
)
504 unsigned int originalCh
;
507 if (tuiWinResized ())
509 tuiDo ((TuiOpaqueFuncPtr
) tuiRefreshAll
);
511 tuiSetWinResizedTo (FALSE
);
517 } /* _tuiHandleResizeDuringIO */
521 ** _updateCommandInfo().
522 ** Function to update the command window information.
529 _updateCommandInfo (sizeOfString
)
535 cmdWin
->detail
.commandInfo
.curch
) > cmdWin
->generic
.width
)
537 int newCurch
= sizeOfString
+ cmdWin
->detail
.commandInfo
.curch
;
539 tuiStartNewLines (1);
540 cmdWin
->detail
.commandInfo
.curch
= newCurch
- cmdWin
->generic
.width
;
543 cmdWin
->detail
.commandInfo
.curch
+= sizeOfString
;
546 } /* _updateCommandInfo */
549 /* Looked at in main.c, fputs_unfiltered(), to decide
550 * if it's safe to do standard output to the command window.
552 int tui_owns_terminal
= 0;
554 /* Called to set up the terminal for TUI (curses) I/O.
555 * We do this either on our way "in" to GDB after target
556 * program execution, or else within tuiDo just before
557 * going off to TUI routines.
565 tuiTermSetup (turn_off_echo
)
573 extern char *term_scroll_region
;
574 extern char *term_cursor_move
;
575 extern char *term_memory_lock
;
576 extern char *term_memory_unlock
;
578 /* Turn off echoing, since the TUI does not
579 * expect echoing. Below I only put in the TERMIOS
580 * case, since that is what applies on HP-UX. turn_off_echo
581 * is 1 except for the case where we're being called
582 * on a "quit", in which case we want to leave echo on.
589 tio
.c_lflag
&= ~(ECHO
);
590 tcsetattr (0, TCSANOW
, &tio
);
594 /* Compute the start and end lines of the command
595 * region. (Actually we only use end here)
597 start
= winList
[CMD_WIN
]->generic
.origin
.y
;
598 end
= start
+ winList
[CMD_WIN
]->generic
.height
- 1;
599 endcol
= winList
[CMD_WIN
]->generic
.width
- 1;
601 if (term_memory_unlock
)
604 /* Un-do the effect of the memory lock in terminal_inferior() */
605 tputs (term_memory_unlock
, 1, (int (*)PARAMS ((int))) putchar
);
609 else if (term_scroll_region
)
612 /* Un-do the effect of setting scroll region in terminal_inferior() */
613 /* I'm actually not sure how to do this (we don't know for
614 * sure what the scroll region was *before* we changed it),
615 * but I'll guess that setting it to the whole screen is
616 * the right thing. So, ...
619 /* Set scroll region to be 0..end */
620 buffer
= (char *) tgoto (term_scroll_region
, end
, 0);
621 tputs (buffer
, 1, (int (*)PARAMS ((int))) putchar
);
623 } /* else we're out of luck */
625 /* This is an attempt to keep the logical & physical
626 * cursor in synch, going into curses. Without this,
627 * curses seems to be confused by the fact that
628 * GDB has physically moved the curser on it. One
629 * visible effect of removing this code is that the
630 * locator window fails to get updated and the line
631 * of text that *should* go into the locator window
632 * often goes to the wrong place.
634 /* What's done here is to tell curses to write a ' '
635 * at the bottom right corner of the screen.
636 * The idea is to wind up with the cursor in a known
638 * Note I'm relying on refresh()
639 * only writing what changed (the space),
640 * not the whole screen.
643 move (end
, endcol
- 1);
647 tui_owns_terminal
= 1;
651 /* Called to set up the terminal for target program I/O, meaning I/O
652 * is confined to the command-window area. We also call this on our
653 * way out of tuiDo, thus setting up the terminal this way for
654 * debugger command I/O. */
661 tuiTermUnsetup (turn_on_echo
, to_column
)
670 /* The next bunch of things are from readline */
671 extern char *term_scroll_region
;
672 extern char *term_cursor_move
;
673 extern char *term_memory_lock
;
674 extern char *term_memory_unlock
;
675 extern char *term_se
;
677 /* We need to turn on echoing, since the TUI turns it off */
678 /* Below I only put in the TERMIOS case, since that
679 * is what applies on HP-UX.
686 tio
.c_lflag
|= (ECHO
);
687 tcsetattr (0, TCSANOW
, &tio
);
691 /* Compute the start and end lines of the command
692 * region, as well as the last "real" line of
693 * the region (normally same as end, except when
694 * we're first populating the region)
696 start
= winList
[CMD_WIN
]->generic
.origin
.y
;
697 end
= start
+ winList
[CMD_WIN
]->generic
.height
- 1;
698 curline
= start
+ winList
[CMD_WIN
]->detail
.commandInfo
.curLine
;
700 /* We want to confine target I/O to the command region.
701 * In order to do so, we must either have "memory lock"
702 * (hpterm's) or "scroll regions" (xterm's).
704 if (term_cursor_move
&& term_memory_lock
)
707 /* Memory lock means lock region above cursor.
708 * So first position the cursor, then call memory lock.
710 buffer
= tgoto (term_cursor_move
, 0, start
);
711 tputs (buffer
, 1, (int (*)PARAMS ((int))) putchar
);
712 tputs (term_memory_lock
, 1, (int (*)PARAMS ((int))) putchar
);
715 else if (term_scroll_region
)
718 /* Set the scroll region to the command window */
719 buffer
= tgoto (term_scroll_region
, end
, start
);
720 tputs (buffer
, 1, (int (*)PARAMS ((int))) putchar
);
722 } /* else we can't do anything about target I/O */
724 /* Also turn off standout mode, in case it is on */
726 tputs (term_se
, 1, (int (*)PARAMS ((int))) putchar
);
728 /* Now go to the appropriate spot on the end line */
729 buffer
= tgoto (term_cursor_move
, to_column
, end
);
730 tputs (buffer
, 1, (int (*)PARAMS ((int))) putchar
);
733 tui_owns_terminal
= 0;
734 } /* tuiTermUnsetup */