#include "config.h"
#ifdef HAVE_NCURSES_H
#include <ncurses.h>
#else
#ifdef HAVE_CURSES_H
#include <curses.h>
#endif
#endif
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <malloc.h>
#ifdef HAVE_TERM_H
#include <term.h>
#endif
#include <signal.h>
#include <fcntl.h>
#include <termio.h>
#include <setjmp.h>
#include "defs.h"
#include "gdbcmd.h"
#include "tui.h"
#include "tuiData.h"
#include "tuiLayout.h"
#include "tuiIO.h"
#include "tuiRegs.h"
#include "tuiStack.h"
#include "tuiWin.h"
#include "tuiSourceWin.h"
#include "readline/readline.h"
#include "target.h"
#include "frame.h"
#include "breakpoint.h"
#include "inferior.h"
int tui_active = 0;
static int tui_finish_init = 1;
static int
tui_switch_mode (void)
{
if (tui_active)
{
tui_disable ();
rl_prep_terminal (0);
printf_filtered ("Left the TUI mode\n");
}
else
{
rl_deprep_terminal ();
tui_enable ();
printf_filtered ("Entered the TUI mode\n");
}
if (rl_end)
rl_kill_text (0, rl_end);
rl_newline (1, '\n');
dont_repeat ();
return 0;
}
static int
tui_change_windows (void)
{
if (!tui_active)
tui_switch_mode ();
if (tui_active)
{
TuiLayoutType new_layout;
TuiRegisterDisplayType regs_type = TUI_UNDEFINED_REGS;
new_layout = currentLayout ();
switch (new_layout)
{
case SRC_COMMAND:
new_layout = SRC_DISASSEM_COMMAND;
break;
case DISASSEM_COMMAND:
new_layout = SRC_DISASSEM_COMMAND;
break;
case SRC_DATA_COMMAND:
new_layout = SRC_DISASSEM_COMMAND;
break;
case SRC_DISASSEM_COMMAND:
new_layout = DISASSEM_DATA_COMMAND;
break;
case DISASSEM_DATA_COMMAND:
new_layout = SRC_DATA_COMMAND;
break;
default:
new_layout = SRC_COMMAND;
break;
}
tuiSetLayout (new_layout, regs_type);
}
return 0;
}
static int
tui_delete_other_windows (void)
{
if (!tui_active)
tui_switch_mode ();
if (tui_active)
{
TuiLayoutType new_layout;
TuiRegisterDisplayType regs_type = TUI_UNDEFINED_REGS;
new_layout = currentLayout ();
switch (new_layout)
{
case SRC_COMMAND:
case SRC_DATA_COMMAND:
case SRC_DISASSEM_COMMAND:
default:
new_layout = SRC_COMMAND;
break;
case DISASSEM_COMMAND:
case DISASSEM_DATA_COMMAND:
new_layout = DISASSEM_COMMAND;
break;
}
tuiSetLayout (new_layout, regs_type);
}
return 0;
}
void
tui_initialize_readline ()
{
rl_initialize ();
rl_add_defun ("tui-switch-mode", tui_switch_mode, -1);
rl_bind_key_in_map ('a', tui_switch_mode, emacs_ctlx_keymap);
rl_bind_key_in_map ('A', tui_switch_mode, emacs_ctlx_keymap);
rl_bind_key_in_map (CTRL ('A'), tui_switch_mode, emacs_ctlx_keymap);
rl_bind_key_in_map ('1', tui_delete_other_windows, emacs_ctlx_keymap);
rl_bind_key_in_map ('2', tui_change_windows, emacs_ctlx_keymap);
}
void
tui_enable (void)
{
if (tui_active)
return;
if (tui_finish_init)
{
WINDOW *w;
w = initscr ();
cbreak ();
noecho ();
nodelay(w, FALSE);
nl();
keypad (w, TRUE);
rl_initialize ();
setTermHeightTo (LINES);
setTermWidthTo (COLS);
def_prog_mode ();
tuiSetLocatorContent (0);
showLayout (SRC_COMMAND);
tuiSetWinFocusTo (srcWin);
keypad (cmdWin->generic.handle, TRUE);
wrefresh (cmdWin->generic.handle);
tui_finish_init = 0;
}
else
{
def_shell_mode ();
clearok (stdscr, TRUE);
}
tui_install_hooks ();
tui_update_variables ();
tui_setup_io (1);
tui_version = 1;
tui_active = 1;
refresh ();
}
void
tui_disable (void)
{
if (!tui_active)
return;
tui_remove_hooks ();
endwin ();
tui_setup_io (0);
tui_version = 0;
tui_active = 0;
}
void
tuiFree (char *ptr)
{
if (ptr != (char *) NULL)
{
xfree (ptr);
}
}
CORE_ADDR
tuiGetLowDisassemblyAddress (CORE_ADDR low, CORE_ADDR pc)
{
int line;
CORE_ADDR newLow;
for (line = 0, newLow = pc;
(newLow > low &&
line < (tuiDefaultWinViewportHeight (DISASSEM_WIN,
DISASSEM_COMMAND) / 2));)
{
bfd_byte buffer[4];
newLow -= sizeof (bfd_getb32 (buffer));
line++;
}
return newLow;
}
void
strcat_to_buf (char *buf, int buflen, char *itemToAdd)
{
if (itemToAdd != (char *) NULL && buf != (char *) NULL)
{
if ((strlen (buf) + strlen (itemToAdd)) <= buflen)
strcat (buf, itemToAdd);
else
strncat (buf, itemToAdd, (buflen - strlen (buf)));
}
}
#if 0
#ifndef CTRL
#define CTRL(x) (x & ~0140)
#endif
#define FILEDES 2
#define CHK(val, dft) (val<=0 ? dft : val)
static void
_tuiReset (void)
{
struct termio mode;
#if ! defined (USG) && defined (TIOCGETC)
struct tchars tbuf;
#endif
#ifdef UCB_NTTY
struct ltchars ltc;
if (ldisc == NTTYDISC)
{
ioctl (FILEDES, TIOCGLTC, <c);
ltc.t_suspc = CHK (ltc.t_suspc, CTRL ('Z'));
ltc.t_dsuspc = CHK (ltc.t_dsuspc, CTRL ('Y'));
ltc.t_rprntc = CHK (ltc.t_rprntc, CTRL ('R'));
ltc.t_flushc = CHK (ltc.t_flushc, CTRL ('O'));
ltc.t_werasc = CHK (ltc.t_werasc, CTRL ('W'));
ltc.t_lnextc = CHK (ltc.t_lnextc, CTRL ('V'));
ioctl (FILEDES, TIOCSLTC, <c);
}
#endif
#ifndef USG
#ifdef TIOCGETC
ioctl (FILEDES, TIOCGETC, &tbuf);
tbuf.t_intrc = CHK (tbuf.t_intrc, CTRL ('?'));
tbuf.t_quitc = CHK (tbuf.t_quitc, CTRL ('\\'));
tbuf.t_startc = CHK (tbuf.t_startc, CTRL ('Q'));
tbuf.t_stopc = CHK (tbuf.t_stopc, CTRL ('S'));
tbuf.t_eofc = CHK (tbuf.t_eofc, CTRL ('D'));
ioctl (FILEDES, TIOCSETC, &tbuf);
#endif
mode.sg_flags &= ~(RAW
#ifdef CBREAK
| CBREAK
#endif
| VTDELAY | ALLDELAY);
mode.sg_flags |= XTABS | ECHO | CRMOD | ANYP;
#else
ioctl (FILEDES, TCGETA, &mode);
mode.c_cc[VINTR] = CHK (mode.c_cc[VINTR], CTRL ('?'));
mode.c_cc[VQUIT] = CHK (mode.c_cc[VQUIT], CTRL ('\\'));
mode.c_cc[VEOF] = CHK (mode.c_cc[VEOF], CTRL ('D'));
mode.c_iflag &= ~(IGNBRK | PARMRK | INPCK | INLCR | IGNCR | IUCLC | IXOFF);
mode.c_iflag |= (BRKINT | ISTRIP | ICRNL | IXON);
mode.c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL |
NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY);
mode.c_oflag |= (OPOST | ONLCR);
mode.c_cflag &= ~(CSIZE | PARODD | CLOCAL);
#ifndef hp9000s800
mode.c_cflag |= (CS8 | CREAD);
#else
mode.c_cflag |= (CS8 | CSTOPB | CREAD);
#endif
mode.c_lflag &= ~(XCASE | ECHONL | NOFLSH);
mode.c_lflag |= (ISIG | ICANON | ECHO | ECHOK);
ioctl (FILEDES, TCSETAW, &mode);
#endif
return;
}
#endif
void
tui_show_source (const char *file, int line)
{
tuiAddWinToLayout (SRC_WIN);
tuiUpdateSourceWindowsWithLine (current_source_symtab, line);
tuiUpdateLocatorFilename (file);
}
void
tui_show_assembly (CORE_ADDR addr)
{
tuiAddWinToLayout (DISASSEM_WIN);
tuiUpdateSourceWindowsWithAddr (addr);
}
int
tui_is_window_visible (TuiWinType type)
{
if (tui_version == 0)
return 0;
if (winList[type] == 0)
return 0;
return winList[type]->generic.isVisible;
}
int
tui_get_command_dimension (int *width, int *height)
{
if (!tui_version || !m_winPtrNotNull (cmdWin))
{
return 0;
}
*width = cmdWin->generic.width;
*height = cmdWin->generic.height;
return 1;
}