PARAMS removal.
[deliverable/binutils-gdb.git] / gdb / tui / tuiIO.c
CommitLineData
c906108c
SS
1
2/*
c5aa993b
JM
3 ** This module contains functions to support i/o in the TUI
4 */
c906108c
SS
5
6
7#include <stdio.h>
8#include "defs.h"
9#include "terminal.h"
10#include "tui.h"
11#include "tuiData.h"
12#include "tuiIO.h"
13#include "tuiCommand.h"
14#include "tuiWin.h"
15
16#ifdef ANSI_PROTOTYPES
17#include <stdarg.h>
18#else
19#include <varargs.h>
20#endif
21
22/* The Solaris header files seem to provide no declaration for this at
23 all when __STDC__ is defined. This shouldn't conflict with
24 anything. */
25extern char *tgoto ();
26
27int insert_mode = 0;
28
29/********************************************
30** LOCAL STATIC FORWARD DECLS **
31********************************************/
a14ed312
KB
32static void _updateCommandInfo (int);
33static unsigned int _tuiHandleResizeDuringIO (unsigned int);
c906108c
SS
34
35
36/*********************************************************************************
37** PUBLIC FUNCTIONS **
38*********************************************************************************/
39
40/*
c5aa993b
JM
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().
48 */
c906108c
SS
49void
50#ifdef __STDC__
51tuiPuts_unfiltered (
52 const char *string,
d9fcf2fb 53 struct ui_file * stream)
c906108c
SS
54#else
55tuiPuts_unfiltered (string, stream)
56 char *string;
d9fcf2fb 57 struct ui_file *stream;
c906108c
SS
58#endif
59{
60 int len = strlen (string);
61 int i, linech;
62
63 for (i = 0; i < len; i++)
64 {
65 if (string[i] == '\n' || string[i] == '\r')
66 m_tuiStartNewLine;
67 else
68 {
69 if ((cmdWin->detail.commandInfo.curch + 1) > cmdWin->generic.width)
70 m_tuiStartNewLine;
71
72 if (insert_mode)
73 {
74 mvwinsch (cmdWin->generic.handle,
75 cmdWin->detail.commandInfo.curLine,
76 cmdWin->detail.commandInfo.curch++,
77 string[i]);
78 wmove (cmdWin->generic.handle,
79 cmdWin->detail.commandInfo.curLine,
80 cmdWin->detail.commandInfo.curch);
81 }
82 else
83 mvwaddch (cmdWin->generic.handle,
84 cmdWin->detail.commandInfo.curLine,
85 cmdWin->detail.commandInfo.curch++,
86 string[i]);
87 }
88 }
89 tuiRefreshWin (&cmdWin->generic);
90
91 return;
92} /* tuiPuts_unfiltered */
93
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.
98 *
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.
103 *
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
110 */
111void
112tui_tputs (str, affcnt, putfunc)
113 char *str;
114 int affcnt;
115 int (*putfunc) PARAMS ((int));
116{
117 extern char *rl_prompt; /* the prompt string */
118
119 /* This set of globals are defined and initialized
120 * by the readline package.
121 *
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
129 *
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
132 */
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;
150
151 /* Sanity check - if not TUI, just call tputs() */
152 if (!tui_version)
153 tputs (str, affcnt, putfunc);
154
155 /* The strings we special-case are handled first */
156
157 if (str == term_backspace)
158 {
159 /* Backspace. */
160
161 /* We see this on an emacs control-B.
c5aa993b
JM
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).
166 */
c906108c
SS
167
168 _updateCommandInfo (-1);
169 wmove (cmdWin->generic.handle,
170 cmdWin->detail.commandInfo.curLine,
171 cmdWin->detail.commandInfo.curch);
172 wrefresh (cmdWin->generic.handle);
173
174 }
175 else if (str == term_clreol)
176 {
177
178 /* Clear to end of line. */
179 wclrtoeol (cmdWin->generic.handle);
180 wrefresh (cmdWin->generic.handle);
181
182 }
183 else if (str == term_cr)
184 {
185
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);
192
193 }
194 else if (str == term_goto)
195 {
196
197 /* This is actually a tgoto() specifying a character position,
c5aa993b
JM
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
206 */
c906108c
SS
207
208 }
209 else if (str == term_dc)
210 {
211
212 /* Delete character at current cursor position */
213 wdelch (cmdWin->generic.handle);
214 wrefresh (cmdWin->generic.handle);
215
216 }
217 else if (str == term_im)
218 {
219
220 /* Turn on insert mode. */
221 insert_mode = 1;
222
223 }
224 else if (str == term_ei)
225 {
226
227 /* Turn off insert mode. */
228 insert_mode = 0;
229
230 /* Strings we know about but don't handle
c5aa993b
JM
231 * specially here are just passed along to tputs().
232 *
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.
238 */
c906108c
SS
239 }
240 else if (str == term_ic || /* insert character */
241 str == term_cursor_move || /* cursor move */
c5aa993b 242 str == term_clrpag || /* clear page */
c906108c
SS
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) */
c5aa993b 246 str == term_scroll_region || /* set scroll region */
c906108c 247 str == term_memory_lock || /* lock screen above cursor */
c5aa993b 248 str == term_memory_unlock || /* unlock screen above cursor */
c906108c
SS
249 str == visible_bell)
250 { /* flash screen */
251 tputs (str, affcnt, putfunc);
252 }
253 else
254 { /* something else */
255 tputs (str, affcnt, putfunc);
256 }
257} /* tui_tputs */
258
259
260/*
c5aa993b
JM
261 ** tui_vwgetch()
262 ** Wrapper around wgetch with the window in a va_list
263 */
c906108c
SS
264unsigned int
265#ifdef __STDC__
266tui_vwgetch (va_list args)
267#else
268tui_vwgetch (args)
269 va_list args;
270#endif
271{
272 unsigned int ch;
273 WINDOW *window;
274
275 window = va_arg (args, WINDOW *);
276
277 return ((unsigned int) wgetch (window));
278} /* tui_vwgetch */
279
280
281/*
c5aa993b
JM
282 ** tui_vread()
283 ** Wrapper around read() with paramets in a va_list
284 */
c906108c
SS
285unsigned int
286#ifdef __STDC__
287tui_vread (va_list args)
288#else
289tui_vread (args)
290 va_list args;
291#endif
292{
293 int result = 0;
294 int filedes = va_arg (args, int);
295 char *buf = va_arg (args, char *);
296 int nbytes = va_arg (args, int);
297
298 result = read (filedes, buf, nbytes);
299
300 return result;
301} /* tui_vread() */
302
303/*
c5aa993b
JM
304 ** tuiRead()
305 ** Function to perform a read() catching resize events
306 */
c906108c
SS
307int
308#ifdef __STDC__
309tuiRead (
310 int filedes,
311 char *buf,
312 int nbytes)
313#else
314tuiRead (filedes, buf, nbytes)
315 int filedes;
316 char *buf;
317 int nbytes;
318#endif
319{
320 int result = 0;
321
322 result = (int) vcatch_errors ((OpaqueFuncPtr) tui_vread, filedes, buf, nbytes);
323 *buf = _tuiHandleResizeDuringIO (*buf);
324
325 return result;
326} /* tuiRead */
327
328
329/*
c5aa993b
JM
330 ** tuiGetc().
331 ** Get a character from the command window.
332 ** This is called from the readline package,
333 ** that is, we have:
334 ** tuiGetc() [here], called from
335 ** readline code [in ../readline/], called from
336 ** command_line_input() in top.c
337 */
c906108c
SS
338unsigned int
339#ifdef __STDC__
340tuiGetc (void)
341#else
342tuiGetc ()
343#endif
344{
345 unsigned int ch;
346 extern char *rl_prompt;
347 extern char *rl_line_buffer;
348 extern int rl_point;
349
350 /* Call the curses routine that reads one character */
351#ifndef COMMENT
352 ch = (unsigned int) vcatch_errors ((OpaqueFuncPtr) tui_vwgetch,
353 cmdWin->generic.handle);
354#else
355 ch = wgetch (cmdWin->generic.handle);
356#endif
357 ch = _tuiHandleResizeDuringIO (ch);
358
359 if (m_isCommandChar (ch))
360 { /* Handle prev/next/up/down here */
361 tuiTermSetup (0);
362 ch = tuiDispatchCtrlChar (ch);
363 cmdWin->detail.commandInfo.curch = strlen (rl_prompt) + rl_point;
364 tuiTermUnsetup (0, cmdWin->detail.commandInfo.curch);
365 }
366 if (ch == '\n' || ch == '\r' || ch == '\f')
367 cmdWin->detail.commandInfo.curch = 0;
368 else
369 tuiIncrCommandCharCountBy (1);
370
371 return ch;
372} /* tuiGetc */
373
374
375/*
c5aa993b
JM
376 ** tuiBufferGetc().
377 */
c906108c 378/*elz: this function reads a line of input from the user and
c5aa993b
JM
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 */
c906108c 383/* so far this function is called only from the query function in
c5aa993b 384 utils.c */
c906108c
SS
385
386unsigned int
387#ifdef __STDC__
388tuiBufferGetc (void)
389#else
390tuiBufferGetc ()
391#endif
392{
393 unsigned int ch;
394 static unsigned char _ibuffer[512];
395 static int index_read = -1;
396 static int length_of_answer = -1;
397 int pos = 0;
398
399 if (length_of_answer == -1)
400 {
c5aa993b 401 /* this is the first time through, need to read the answer */
c906108c
SS
402 do
403 {
404 /* Call the curses routine that reads one character */
405 ch = (unsigned int) wgetch (cmdWin->generic.handle);
406 if (ch != '\b')
407 {
408 _ibuffer[pos] = ch;
409 pos++;
410 }
411 else
412 pos--;
413 }
414 while (ch != '\r' && ch != '\n');
415
416 length_of_answer = pos;
417 index_read = 0;
418 }
419
420 ch = _ibuffer[index_read];
421 index_read++;
422
423 if (index_read == length_of_answer)
424 {
c5aa993b 425 /*this is the last time through, reset for next query */
c906108c
SS
426 index_read = -1;
427 length_of_answer = -1;
428 }
429
430 wrefresh (cmdWin->generic.handle);
431
432 return (ch);
433} /* tuiBufferGetc */
434
435
436/*
c5aa993b
JM
437 ** tuiStartNewLines().
438 */
c906108c
SS
439void
440#ifdef __STDC__
441tuiStartNewLines (
442 int numLines)
443#else
444tuiStartNewLines (numLines)
445 int numLines;
446#endif
447{
448 if (numLines > 0)
449 {
450 if (cmdWin->generic.viewportHeight > 1 &&
451 cmdWin->detail.commandInfo.curLine < cmdWin->generic.viewportHeight)
452 cmdWin->detail.commandInfo.curLine += numLines;
453 else
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);
460 }
461
462 return;
463} /* tuiStartNewLines */
464
465
466/*
c5aa993b
JM
467 ** tui_vStartNewLines().
468 ** With numLines in a va_list
469 */
c906108c
SS
470void
471#ifdef __STDC__
472tui_vStartNewLines (
473 va_list args)
474#else
475tui_vStartNewLines (args)
476 va_list args;
477#endif
478{
479 int numLines = va_arg (args, int);
480
481 tuiStartNewLines (numLines);
482
483 return;
484} /* tui_vStartNewLines */
485
486
487/****************************************************************************
488** LOCAL STATIC FUNCTIONS **
489*****************************************************************************/
490
491
492/*
c5aa993b
JM
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.
497 */
c906108c
SS
498static unsigned int
499#ifdef __STDC__
500_tuiHandleResizeDuringIO (
501 unsigned int originalCh) /* the char just read */
502#else
503_tuiHandleResizeDuringIO (originalCh)
504 unsigned int originalCh;
505#endif
506{
507 if (tuiWinResized ())
508 {
509 tuiDo ((TuiOpaqueFuncPtr) tuiRefreshAll);
510 dont_repeat ();
511 tuiSetWinResizedTo (FALSE);
512 rl_reset ();
513 return '\n';
514 }
515 else
516 return originalCh;
517} /* _tuiHandleResizeDuringIO */
518
519
520/*
c5aa993b
JM
521 ** _updateCommandInfo().
522 ** Function to update the command window information.
523 */
c906108c
SS
524static void
525#ifdef __STDC__
526_updateCommandInfo (
527 int sizeOfString)
528#else
529_updateCommandInfo (sizeOfString)
530 int sizeOfString;
531#endif
532{
533
534 if ((sizeOfString +
535 cmdWin->detail.commandInfo.curch) > cmdWin->generic.width)
536 {
537 int newCurch = sizeOfString + cmdWin->detail.commandInfo.curch;
538
539 tuiStartNewLines (1);
540 cmdWin->detail.commandInfo.curch = newCurch - cmdWin->generic.width;
541 }
542 else
543 cmdWin->detail.commandInfo.curch += sizeOfString;
544
545 return;
546} /* _updateCommandInfo */
547
548
549/* Looked at in main.c, fputs_unfiltered(), to decide
550 * if it's safe to do standard output to the command window.
551 */
552int tui_owns_terminal = 0;
553
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.
558 */
559
560void
561#ifdef __STDC__
562tuiTermSetup (
563 int turn_off_echo)
564#else
565tuiTermSetup (turn_off_echo)
566 int turn_off_echo;
567#endif
568{
569 char *buffer;
570 int start;
571 int end;
572 int endcol;
573 extern char *term_scroll_region;
574 extern char *term_cursor_move;
575 extern char *term_memory_lock;
576 extern char *term_memory_unlock;
577
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.
c5aa993b 583 */
c906108c
SS
584 if (turn_off_echo)
585 {
586#ifdef HAVE_TERMIOS
587 struct termios tio;
588 tcgetattr (0, &tio);
589 tio.c_lflag &= ~(ECHO);
590 tcsetattr (0, TCSANOW, &tio);
591#endif
592 }
593
594 /* Compute the start and end lines of the command
595 * region. (Actually we only use end here)
c5aa993b 596 */
c906108c
SS
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;
600
601 if (term_memory_unlock)
602 {
603
604 /* Un-do the effect of the memory lock in terminal_inferior() */
605 tputs (term_memory_unlock, 1, (int (*)PARAMS ((int))) putchar);
606 fflush (stdout);
607
608 }
609 else if (term_scroll_region)
610 {
611
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, ...
617 */
618
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);
622
623 } /* else we're out of luck */
624
625 /* This is an attempt to keep the logical & physical
c5aa993b
JM
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.
633 */
c906108c 634 /* What's done here is to tell curses to write a ' '
c5aa993b
JM
635 * at the bottom right corner of the screen.
636 * The idea is to wind up with the cursor in a known
637 * place.
638 * Note I'm relying on refresh()
639 * only writing what changed (the space),
640 * not the whole screen.
641 */
c906108c
SS
642 standend ();
643 move (end, endcol - 1);
644 addch (' ');
645 refresh ();
646
647 tui_owns_terminal = 1;
648} /* tuiTermSetup */
649
650
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. */
655void
656#ifdef __STDC__
657tuiTermUnsetup (
658 int turn_on_echo,
659 int to_column)
660#else
661tuiTermUnsetup (turn_on_echo, to_column)
662 int turn_on_echo;
663 int to_column;
664#endif
665{
666 int start;
667 int end;
668 int curline;
669 char *buffer;
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;
676
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.
c5aa993b 680 */
c906108c
SS
681 if (turn_on_echo)
682 {
683#ifdef HAVE_TERMIOS
684 struct termios tio;
685 tcgetattr (0, &tio);
686 tio.c_lflag |= (ECHO);
687 tcsetattr (0, TCSANOW, &tio);
688#endif
689 }
690
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)
c5aa993b 695 */
c906108c
SS
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;
699
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).
c5aa993b 703 */
c906108c
SS
704 if (term_cursor_move && term_memory_lock)
705 {
706
707 /* Memory lock means lock region above cursor.
708 * So first position the cursor, then call memory lock.
709 */
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);
713
714 }
715 else if (term_scroll_region)
716 {
717
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);
721
722 } /* else we can't do anything about target I/O */
723
724 /* Also turn off standout mode, in case it is on */
725 if (term_se != NULL)
726 tputs (term_se, 1, (int (*)PARAMS ((int))) putchar);
727
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);
731 fflush (stdout);
732
733 tui_owns_terminal = 0;
734} /* tuiTermUnsetup */
This page took 0.086648 seconds and 4 git commands to generate.