* tuiWin.c, tuiWin.h, tui.c, tui.h, tuiCommand.c: Add FSF copyright.
[deliverable/binutils-gdb.git] / gdb / tui / tuiIO.c
CommitLineData
f377b406
SC
1/* TUI support I/O functions.
2 Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3 Contributed by Hewlett-Packard Company.
4
5 This file is part of GDB.
6
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.
11
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.
16
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. */
c906108c
SS
21
22#include <stdio.h>
23#include "defs.h"
24#include "terminal.h"
25#include "tui.h"
26#include "tuiData.h"
27#include "tuiIO.h"
28#include "tuiCommand.h"
29#include "tuiWin.h"
30
31#ifdef ANSI_PROTOTYPES
32#include <stdarg.h>
33#else
34#include <varargs.h>
35#endif
36
37/* The Solaris header files seem to provide no declaration for this at
38 all when __STDC__ is defined. This shouldn't conflict with
39 anything. */
40extern char *tgoto ();
41
42int insert_mode = 0;
43
44/********************************************
45** LOCAL STATIC FORWARD DECLS **
46********************************************/
a14ed312
KB
47static void _updateCommandInfo (int);
48static unsigned int _tuiHandleResizeDuringIO (unsigned int);
c906108c
SS
49
50
51/*********************************************************************************
52** PUBLIC FUNCTIONS **
53*********************************************************************************/
54
55/*
c5aa993b
JM
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().
63 */
c906108c
SS
64void
65#ifdef __STDC__
66tuiPuts_unfiltered (
67 const char *string,
d9fcf2fb 68 struct ui_file * stream)
c906108c
SS
69#else
70tuiPuts_unfiltered (string, stream)
71 char *string;
d9fcf2fb 72 struct ui_file *stream;
c906108c
SS
73#endif
74{
75 int len = strlen (string);
76 int i, linech;
77
78 for (i = 0; i < len; i++)
79 {
80 if (string[i] == '\n' || string[i] == '\r')
81 m_tuiStartNewLine;
82 else
83 {
84 if ((cmdWin->detail.commandInfo.curch + 1) > cmdWin->generic.width)
85 m_tuiStartNewLine;
86
87 if (insert_mode)
88 {
89 mvwinsch (cmdWin->generic.handle,
90 cmdWin->detail.commandInfo.curLine,
91 cmdWin->detail.commandInfo.curch++,
92 string[i]);
93 wmove (cmdWin->generic.handle,
94 cmdWin->detail.commandInfo.curLine,
95 cmdWin->detail.commandInfo.curch);
96 }
97 else
98 mvwaddch (cmdWin->generic.handle,
99 cmdWin->detail.commandInfo.curLine,
100 cmdWin->detail.commandInfo.curch++,
101 string[i]);
102 }
103 }
104 tuiRefreshWin (&cmdWin->generic);
105
106 return;
107} /* tuiPuts_unfiltered */
108
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.
113 *
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.
118 *
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
125 */
126void
127tui_tputs (str, affcnt, putfunc)
128 char *str;
129 int affcnt;
507f3c78 130 int (*putfunc) (int);
c906108c
SS
131{
132 extern char *rl_prompt; /* the prompt string */
133
134 /* This set of globals are defined and initialized
135 * by the readline package.
136 *
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
144 *
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
147 */
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;
165
166 /* Sanity check - if not TUI, just call tputs() */
167 if (!tui_version)
168 tputs (str, affcnt, putfunc);
169
170 /* The strings we special-case are handled first */
171
172 if (str == term_backspace)
173 {
174 /* Backspace. */
175
176 /* We see this on an emacs control-B.
c5aa993b
JM
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).
181 */
c906108c
SS
182
183 _updateCommandInfo (-1);
184 wmove (cmdWin->generic.handle,
185 cmdWin->detail.commandInfo.curLine,
186 cmdWin->detail.commandInfo.curch);
187 wrefresh (cmdWin->generic.handle);
188
189 }
190 else if (str == term_clreol)
191 {
192
193 /* Clear to end of line. */
194 wclrtoeol (cmdWin->generic.handle);
195 wrefresh (cmdWin->generic.handle);
196
197 }
198 else if (str == term_cr)
199 {
200
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);
207
208 }
209 else if (str == term_goto)
210 {
211
212 /* This is actually a tgoto() specifying a character position,
c5aa993b
JM
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
221 */
c906108c
SS
222
223 }
224 else if (str == term_dc)
225 {
226
227 /* Delete character at current cursor position */
228 wdelch (cmdWin->generic.handle);
229 wrefresh (cmdWin->generic.handle);
230
231 }
232 else if (str == term_im)
233 {
234
235 /* Turn on insert mode. */
236 insert_mode = 1;
237
238 }
239 else if (str == term_ei)
240 {
241
242 /* Turn off insert mode. */
243 insert_mode = 0;
244
245 /* Strings we know about but don't handle
c5aa993b
JM
246 * specially here are just passed along to tputs().
247 *
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.
253 */
c906108c
SS
254 }
255 else if (str == term_ic || /* insert character */
256 str == term_cursor_move || /* cursor move */
c5aa993b 257 str == term_clrpag || /* clear page */
c906108c
SS
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) */
c5aa993b 261 str == term_scroll_region || /* set scroll region */
c906108c 262 str == term_memory_lock || /* lock screen above cursor */
c5aa993b 263 str == term_memory_unlock || /* unlock screen above cursor */
c906108c
SS
264 str == visible_bell)
265 { /* flash screen */
266 tputs (str, affcnt, putfunc);
267 }
268 else
269 { /* something else */
270 tputs (str, affcnt, putfunc);
271 }
272} /* tui_tputs */
273
274
275/*
c5aa993b
JM
276 ** tui_vwgetch()
277 ** Wrapper around wgetch with the window in a va_list
278 */
c906108c
SS
279unsigned int
280#ifdef __STDC__
281tui_vwgetch (va_list args)
282#else
283tui_vwgetch (args)
284 va_list args;
285#endif
286{
287 unsigned int ch;
288 WINDOW *window;
289
290 window = va_arg (args, WINDOW *);
291
292 return ((unsigned int) wgetch (window));
293} /* tui_vwgetch */
294
295
296/*
c5aa993b
JM
297 ** tui_vread()
298 ** Wrapper around read() with paramets in a va_list
299 */
c906108c
SS
300unsigned int
301#ifdef __STDC__
302tui_vread (va_list args)
303#else
304tui_vread (args)
305 va_list args;
306#endif
307{
308 int result = 0;
309 int filedes = va_arg (args, int);
310 char *buf = va_arg (args, char *);
311 int nbytes = va_arg (args, int);
312
313 result = read (filedes, buf, nbytes);
314
315 return result;
316} /* tui_vread() */
317
318/*
c5aa993b
JM
319 ** tuiRead()
320 ** Function to perform a read() catching resize events
321 */
c906108c
SS
322int
323#ifdef __STDC__
324tuiRead (
325 int filedes,
326 char *buf,
327 int nbytes)
328#else
329tuiRead (filedes, buf, nbytes)
330 int filedes;
331 char *buf;
332 int nbytes;
333#endif
334{
335 int result = 0;
336
337 result = (int) vcatch_errors ((OpaqueFuncPtr) tui_vread, filedes, buf, nbytes);
338 *buf = _tuiHandleResizeDuringIO (*buf);
339
340 return result;
341} /* tuiRead */
342
343
344/*
c5aa993b
JM
345 ** tuiGetc().
346 ** Get a character from the command window.
347 ** This is called from the readline package,
348 ** that is, we have:
349 ** tuiGetc() [here], called from
350 ** readline code [in ../readline/], called from
351 ** command_line_input() in top.c
352 */
c906108c
SS
353unsigned int
354#ifdef __STDC__
355tuiGetc (void)
356#else
357tuiGetc ()
358#endif
359{
360 unsigned int ch;
361 extern char *rl_prompt;
362 extern char *rl_line_buffer;
363 extern int rl_point;
364
365 /* Call the curses routine that reads one character */
366#ifndef COMMENT
367 ch = (unsigned int) vcatch_errors ((OpaqueFuncPtr) tui_vwgetch,
368 cmdWin->generic.handle);
369#else
370 ch = wgetch (cmdWin->generic.handle);
371#endif
372 ch = _tuiHandleResizeDuringIO (ch);
373
374 if (m_isCommandChar (ch))
375 { /* Handle prev/next/up/down here */
376 tuiTermSetup (0);
377 ch = tuiDispatchCtrlChar (ch);
378 cmdWin->detail.commandInfo.curch = strlen (rl_prompt) + rl_point;
379 tuiTermUnsetup (0, cmdWin->detail.commandInfo.curch);
380 }
381 if (ch == '\n' || ch == '\r' || ch == '\f')
382 cmdWin->detail.commandInfo.curch = 0;
383 else
384 tuiIncrCommandCharCountBy (1);
385
386 return ch;
387} /* tuiGetc */
388
389
390/*
c5aa993b
JM
391 ** tuiBufferGetc().
392 */
c906108c 393/*elz: this function reads a line of input from the user and
c5aa993b
JM
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 */
c906108c 398/* so far this function is called only from the query function in
c5aa993b 399 utils.c */
c906108c
SS
400
401unsigned int
402#ifdef __STDC__
403tuiBufferGetc (void)
404#else
405tuiBufferGetc ()
406#endif
407{
408 unsigned int ch;
409 static unsigned char _ibuffer[512];
410 static int index_read = -1;
411 static int length_of_answer = -1;
412 int pos = 0;
413
414 if (length_of_answer == -1)
415 {
c5aa993b 416 /* this is the first time through, need to read the answer */
c906108c
SS
417 do
418 {
419 /* Call the curses routine that reads one character */
420 ch = (unsigned int) wgetch (cmdWin->generic.handle);
421 if (ch != '\b')
422 {
423 _ibuffer[pos] = ch;
424 pos++;
425 }
426 else
427 pos--;
428 }
429 while (ch != '\r' && ch != '\n');
430
431 length_of_answer = pos;
432 index_read = 0;
433 }
434
435 ch = _ibuffer[index_read];
436 index_read++;
437
438 if (index_read == length_of_answer)
439 {
c5aa993b 440 /*this is the last time through, reset for next query */
c906108c
SS
441 index_read = -1;
442 length_of_answer = -1;
443 }
444
445 wrefresh (cmdWin->generic.handle);
446
447 return (ch);
448} /* tuiBufferGetc */
449
450
451/*
c5aa993b
JM
452 ** tuiStartNewLines().
453 */
c906108c
SS
454void
455#ifdef __STDC__
456tuiStartNewLines (
457 int numLines)
458#else
459tuiStartNewLines (numLines)
460 int numLines;
461#endif
462{
463 if (numLines > 0)
464 {
465 if (cmdWin->generic.viewportHeight > 1 &&
466 cmdWin->detail.commandInfo.curLine < cmdWin->generic.viewportHeight)
467 cmdWin->detail.commandInfo.curLine += numLines;
468 else
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);
475 }
476
477 return;
478} /* tuiStartNewLines */
479
480
481/*
c5aa993b
JM
482 ** tui_vStartNewLines().
483 ** With numLines in a va_list
484 */
c906108c
SS
485void
486#ifdef __STDC__
487tui_vStartNewLines (
488 va_list args)
489#else
490tui_vStartNewLines (args)
491 va_list args;
492#endif
493{
494 int numLines = va_arg (args, int);
495
496 tuiStartNewLines (numLines);
497
498 return;
499} /* tui_vStartNewLines */
500
501
502/****************************************************************************
503** LOCAL STATIC FUNCTIONS **
504*****************************************************************************/
505
506
507/*
c5aa993b
JM
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.
512 */
c906108c
SS
513static unsigned int
514#ifdef __STDC__
515_tuiHandleResizeDuringIO (
516 unsigned int originalCh) /* the char just read */
517#else
518_tuiHandleResizeDuringIO (originalCh)
519 unsigned int originalCh;
520#endif
521{
522 if (tuiWinResized ())
523 {
524 tuiDo ((TuiOpaqueFuncPtr) tuiRefreshAll);
525 dont_repeat ();
526 tuiSetWinResizedTo (FALSE);
527 rl_reset ();
528 return '\n';
529 }
530 else
531 return originalCh;
532} /* _tuiHandleResizeDuringIO */
533
534
535/*
c5aa993b
JM
536 ** _updateCommandInfo().
537 ** Function to update the command window information.
538 */
c906108c
SS
539static void
540#ifdef __STDC__
541_updateCommandInfo (
542 int sizeOfString)
543#else
544_updateCommandInfo (sizeOfString)
545 int sizeOfString;
546#endif
547{
548
549 if ((sizeOfString +
550 cmdWin->detail.commandInfo.curch) > cmdWin->generic.width)
551 {
552 int newCurch = sizeOfString + cmdWin->detail.commandInfo.curch;
553
554 tuiStartNewLines (1);
555 cmdWin->detail.commandInfo.curch = newCurch - cmdWin->generic.width;
556 }
557 else
558 cmdWin->detail.commandInfo.curch += sizeOfString;
559
560 return;
561} /* _updateCommandInfo */
562
563
564/* Looked at in main.c, fputs_unfiltered(), to decide
565 * if it's safe to do standard output to the command window.
566 */
567int tui_owns_terminal = 0;
568
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.
573 */
574
575void
576#ifdef __STDC__
577tuiTermSetup (
578 int turn_off_echo)
579#else
580tuiTermSetup (turn_off_echo)
581 int turn_off_echo;
582#endif
583{
584 char *buffer;
585 int start;
586 int end;
587 int endcol;
588 extern char *term_scroll_region;
589 extern char *term_cursor_move;
590 extern char *term_memory_lock;
591 extern char *term_memory_unlock;
592
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.
c5aa993b 598 */
c906108c
SS
599 if (turn_off_echo)
600 {
601#ifdef HAVE_TERMIOS
602 struct termios tio;
603 tcgetattr (0, &tio);
604 tio.c_lflag &= ~(ECHO);
605 tcsetattr (0, TCSANOW, &tio);
606#endif
607 }
608
609 /* Compute the start and end lines of the command
610 * region. (Actually we only use end here)
c5aa993b 611 */
c906108c
SS
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;
615
616 if (term_memory_unlock)
617 {
618
619 /* Un-do the effect of the memory lock in terminal_inferior() */
692248f3 620 tputs (term_memory_unlock, 1, (int (*) (int)) putchar);
c906108c
SS
621 fflush (stdout);
622
623 }
624 else if (term_scroll_region)
625 {
626
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, ...
632 */
633
634 /* Set scroll region to be 0..end */
635 buffer = (char *) tgoto (term_scroll_region, end, 0);
692248f3 636 tputs (buffer, 1, (int (*) (int)) putchar);
c906108c
SS
637
638 } /* else we're out of luck */
639
640 /* This is an attempt to keep the logical & physical
c5aa993b
JM
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.
648 */
c906108c 649 /* What's done here is to tell curses to write a ' '
c5aa993b
JM
650 * at the bottom right corner of the screen.
651 * The idea is to wind up with the cursor in a known
652 * place.
653 * Note I'm relying on refresh()
654 * only writing what changed (the space),
655 * not the whole screen.
656 */
c906108c
SS
657 standend ();
658 move (end, endcol - 1);
659 addch (' ');
660 refresh ();
661
662 tui_owns_terminal = 1;
663} /* tuiTermSetup */
664
665
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. */
670void
671#ifdef __STDC__
672tuiTermUnsetup (
673 int turn_on_echo,
674 int to_column)
675#else
676tuiTermUnsetup (turn_on_echo, to_column)
677 int turn_on_echo;
678 int to_column;
679#endif
680{
681 int start;
682 int end;
683 int curline;
684 char *buffer;
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;
691
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.
c5aa993b 695 */
c906108c
SS
696 if (turn_on_echo)
697 {
698#ifdef HAVE_TERMIOS
699 struct termios tio;
700 tcgetattr (0, &tio);
701 tio.c_lflag |= (ECHO);
702 tcsetattr (0, TCSANOW, &tio);
703#endif
704 }
705
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)
c5aa993b 710 */
c906108c
SS
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;
714
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).
c5aa993b 718 */
c906108c
SS
719 if (term_cursor_move && term_memory_lock)
720 {
721
722 /* Memory lock means lock region above cursor.
723 * So first position the cursor, then call memory lock.
724 */
725 buffer = tgoto (term_cursor_move, 0, start);
692248f3
KB
726 tputs (buffer, 1, (int (*) (int)) putchar);
727 tputs (term_memory_lock, 1, (int (*) (int)) putchar);
c906108c
SS
728
729 }
730 else if (term_scroll_region)
731 {
732
733 /* Set the scroll region to the command window */
734 buffer = tgoto (term_scroll_region, end, start);
692248f3 735 tputs (buffer, 1, (int (*) (int)) putchar);
c906108c
SS
736
737 } /* else we can't do anything about target I/O */
738
739 /* Also turn off standout mode, in case it is on */
740 if (term_se != NULL)
692248f3 741 tputs (term_se, 1, (int (*) (int)) putchar);
c906108c
SS
742
743 /* Now go to the appropriate spot on the end line */
744 buffer = tgoto (term_cursor_move, to_column, end);
692248f3 745 tputs (buffer, 1, (int (*) (int)) putchar);
c906108c
SS
746 fflush (stdout);
747
748 tui_owns_terminal = 0;
749} /* tuiTermUnsetup */
This page took 0.173498 seconds and 4 git commands to generate.