OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [gdb/] [tui/] [tui.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* General functions for the WDB TUI.
2
 
3
   Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
4
   Inc.
5
 
6
   Contributed by Hewlett-Packard Company.
7
 
8
   This file is part of GDB.
9
 
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 2 of the License, or
13
   (at your option) any later version.
14
 
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
 
20
   You should have received a copy of the GNU General Public License
21
   along with this program; if not, write to the Free Software
22
   Foundation, Inc., 59 Temple Place - Suite 330,
23
   Boston, MA 02111-1307, USA.  */
24
 
25
/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
26
   "defs.h" should be included first.  Unfortunatly some systems
27
   (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
28
   and they clash with "bfd.h"'s definiton of true/false.  The correct
29
   fix is to remove true/false from "bfd.h", however, until that
30
   happens, hack around it by including "config.h" and <curses.h>
31
   first.  */
32
 
33
#include "config.h"
34
#ifdef HAVE_NCURSES_H       
35
#include <ncurses.h>
36
#else
37
#ifdef HAVE_CURSES_H
38
#include <curses.h>
39
#endif
40
#endif
41
 
42
#include <stdio.h>
43
#include <stdlib.h>
44
#include <ctype.h>
45
#include <malloc.h>
46
#ifdef HAVE_TERM_H
47
#include <term.h>
48
#endif
49
#include <signal.h>
50
#include <fcntl.h>
51
#if 0
52
#include <termio.h>
53
#endif
54
#include <setjmp.h>
55
#include "defs.h"
56
#include "gdbcmd.h"
57
#include "tui.h"
58
#include "tuiData.h"
59
#include "tuiLayout.h"
60
#include "tuiIO.h"
61
#include "tuiRegs.h"
62
#include "tuiStack.h"
63
#include "tuiWin.h"
64
#include "tuiSourceWin.h"
65
#include "readline/readline.h"
66
#include "target.h"
67
#include "frame.h"
68
#include "breakpoint.h"
69
#include "inferior.h"
70
 
71
/* Tells whether the TUI is active or not.  */
72
int tui_active = 0;
73
static int tui_finish_init = 1;
74
 
75
enum tui_key_mode tui_current_key_mode = tui_command_mode;
76
 
77
struct tui_char_command
78
{
79
  unsigned char key;
80
  const char* cmd;
81
};
82
 
83
/* Key mapping to gdb commands when the TUI is using the single key mode.  */
84
static const struct tui_char_command tui_commands[] = {
85
  { 'c', "continue" },
86
  { 'd', "down" },
87
  { 'f', "finish" },
88
  { 'n', "next" },
89
  { 'r', "run" },
90
  { 's', "step" },
91
  { 'u', "up" },
92
  { 'v', "info locals" },
93
  { 'w', "where" },
94
  { 0, 0 },
95
};
96
 
97
static Keymap tui_keymap;
98
static Keymap tui_readline_standard_keymap;
99
 
100
/* TUI readline command.
101
   Switch the output mode between TUI/standard gdb.  */
102
static int
103
tui_rl_switch_mode (void)
104
{
105
  if (tui_active)
106
    {
107
      tui_disable ();
108
      rl_prep_terminal (0);
109
    }
110
  else
111
    {
112
      rl_deprep_terminal ();
113
      tui_enable ();
114
    }
115
 
116
  /* Clear the readline in case switching occurred in middle of something.  */
117
  if (rl_end)
118
    rl_kill_text (0, rl_end);
119
 
120
  /* Since we left the curses mode, the terminal mode is restored to
121
     some previous state.  That state may not be suitable for readline
122
     to work correctly (it may be restored in line mode).  We force an
123
     exit of the current readline so that readline is re-entered and it
124
     will be able to setup the terminal for its needs.  By re-entering
125
     in readline, we also redisplay its prompt in the non-curses mode.  */
126
  rl_newline (1, '\n');
127
 
128
  /* Make sure the \n we are returning does not repeat the last command.  */
129
  dont_repeat ();
130
  return 0;
131
}
132
 
133
/* TUI readline command.
134
   Change the TUI layout to show a next layout.
135
   This function is bound to CTRL-X 2.  It is intended to provide
136
   a functionality close to the Emacs split-window command.  We always
137
   show two windows (src+asm), (src+regs) or (asm+regs).  */
138
static int
139
tui_rl_change_windows (void)
140
{
141
  if (!tui_active)
142
    tui_rl_switch_mode ();
143
 
144
  if (tui_active)
145
    {
146
      TuiLayoutType new_layout;
147
      TuiRegisterDisplayType regs_type = TUI_UNDEFINED_REGS;
148
 
149
      new_layout = currentLayout ();
150
 
151
      /* Select a new layout to have a rolling layout behavior
152
         with always two windows (except when undefined).  */
153
      switch (new_layout)
154
        {
155
        case SRC_COMMAND:
156
          new_layout = SRC_DISASSEM_COMMAND;
157
          break;
158
 
159
        case DISASSEM_COMMAND:
160
          new_layout = SRC_DISASSEM_COMMAND;
161
          break;
162
 
163
        case SRC_DATA_COMMAND:
164
          new_layout = SRC_DISASSEM_COMMAND;
165
          break;
166
 
167
        case SRC_DISASSEM_COMMAND:
168
          new_layout = DISASSEM_DATA_COMMAND;
169
          break;
170
 
171
        case DISASSEM_DATA_COMMAND:
172
          new_layout = SRC_DATA_COMMAND;
173
          break;
174
 
175
        default:
176
          new_layout = SRC_COMMAND;
177
          break;
178
        }
179
      tuiSetLayout (new_layout, regs_type);
180
    }
181
  return 0;
182
}
183
 
184
/* TUI readline command.
185
   Delete the second TUI window to only show one.  */
186
static int
187
tui_rl_delete_other_windows (void)
188
{
189
  if (!tui_active)
190
    tui_rl_switch_mode ();
191
 
192
  if (tui_active)
193
    {
194
      TuiLayoutType new_layout;
195
      TuiRegisterDisplayType regs_type = TUI_UNDEFINED_REGS;
196
 
197
      new_layout = currentLayout ();
198
 
199
      /* Kill one window.  */
200
      switch (new_layout)
201
        {
202
        case SRC_COMMAND:
203
        case SRC_DATA_COMMAND:
204
        case SRC_DISASSEM_COMMAND:
205
        default:
206
          new_layout = SRC_COMMAND;
207
          break;
208
 
209
        case DISASSEM_COMMAND:
210
        case DISASSEM_DATA_COMMAND:
211
          new_layout = DISASSEM_COMMAND;
212
          break;
213
        }
214
      tuiSetLayout (new_layout, regs_type);
215
    }
216
  return 0;
217
}
218
 
219
/* TUI readline command.
220
   Execute the gdb command bound to the specified key.  */
221
static int
222
tui_rl_command_key (int count, int key)
223
{
224
  int i;
225
 
226
  reinitialize_more_filter ();
227
  for (i = 0; tui_commands[i].cmd; i++)
228
    {
229
      if (tui_commands[i].key == key)
230
        {
231
          /* Must save the command because it can be modified
232
             by execute_command.  */
233
          char* cmd = alloca (strlen (tui_commands[i].cmd) + 1);
234
          strcpy (cmd, tui_commands[i].cmd);
235
          execute_command (cmd, TRUE);
236
          return 0;
237
        }
238
    }
239
  return 0;
240
}
241
 
242
/* TUI readline command.
243
   Temporarily leave the TUI SingleKey mode to allow editing
244
   a gdb command with the normal readline.  Once the command
245
   is executed, the TUI SingleKey mode is installed back.  */
246
static int
247
tui_rl_command_mode (int count, int key)
248
{
249
  tui_set_key_mode (tui_one_command_mode);
250
  return rl_insert (count, key);
251
}
252
 
253
/* TUI readline command.
254
   Switch between TUI SingleKey mode and gdb readline editing.  */
255
static int
256
tui_rl_next_keymap (void)
257
{
258
  tui_set_key_mode (tui_current_key_mode == tui_command_mode
259
                    ? tui_single_key_mode : tui_command_mode);
260
  return 0;
261
}
262
 
263
/* Readline hook to redisplay ourself the gdb prompt.
264
   In the SingleKey mode, the prompt is not printed so that
265
   the command window is cleaner.  It will be displayed if
266
   we temporarily leave the SingleKey mode.  */
267
static int
268
tui_rl_startup_hook ()
269
{
270
  rl_already_prompted = 1;
271
  if (tui_current_key_mode != tui_command_mode)
272
    tui_set_key_mode (tui_single_key_mode);
273
  tui_redisplay_readline ();
274
  return 0;
275
}
276
 
277
/* Change the TUI key mode by installing the appropriate readline keymap.  */
278
void
279
tui_set_key_mode (enum tui_key_mode mode)
280
{
281
  tui_current_key_mode = mode;
282
  rl_set_keymap (mode == tui_single_key_mode
283
                 ? tui_keymap : tui_readline_standard_keymap);
284
  tuiShowLocatorContent ();
285
}
286
 
287
/* Initialize readline and configure the keymap for the switching
288
   key shortcut.  */
289
void
290
tui_initialize_readline ()
291
{
292
  int i;
293
  Keymap tui_ctlx_keymap;
294
 
295
  rl_initialize ();
296
 
297
  rl_add_defun ("tui-switch-mode", tui_rl_switch_mode, -1);
298
  rl_add_defun ("gdb-command", tui_rl_command_key, -1);
299
  rl_add_defun ("next-keymap", tui_rl_next_keymap, -1);
300
 
301
  tui_keymap = rl_make_bare_keymap ();
302
  tui_ctlx_keymap = rl_make_bare_keymap ();
303
  tui_readline_standard_keymap = rl_get_keymap ();
304
 
305
  for (i = 0; tui_commands[i].cmd; i++)
306
    rl_bind_key_in_map (tui_commands[i].key, tui_rl_command_key, tui_keymap);
307
 
308
  rl_generic_bind (ISKMAP, "\\C-x", (char*) tui_ctlx_keymap, tui_keymap);
309
 
310
  /* Bind all other keys to tui_rl_command_mode so that we switch
311
     temporarily from SingleKey mode and can enter a gdb command.  */
312
  for (i = ' '; i < 0x7f; i++)
313
    {
314
      int j;
315
 
316
      for (j = 0; tui_commands[j].cmd; j++)
317
        if (tui_commands[j].key == i)
318
          break;
319
 
320
      if (tui_commands[j].cmd)
321
        continue;
322
 
323
      rl_bind_key_in_map (i, tui_rl_command_mode, tui_keymap);
324
    }
325
 
326
  rl_bind_key_in_map ('a', tui_rl_switch_mode, emacs_ctlx_keymap);
327
  rl_bind_key_in_map ('a', tui_rl_switch_mode, tui_ctlx_keymap);
328
  rl_bind_key_in_map ('A', tui_rl_switch_mode, emacs_ctlx_keymap);
329
  rl_bind_key_in_map ('A', tui_rl_switch_mode, tui_ctlx_keymap);
330
  rl_bind_key_in_map (CTRL ('A'), tui_rl_switch_mode, emacs_ctlx_keymap);
331
  rl_bind_key_in_map (CTRL ('A'), tui_rl_switch_mode, tui_ctlx_keymap);
332
  rl_bind_key_in_map ('1', tui_rl_delete_other_windows, emacs_ctlx_keymap);
333
  rl_bind_key_in_map ('1', tui_rl_delete_other_windows, tui_ctlx_keymap);
334
  rl_bind_key_in_map ('2', tui_rl_change_windows, emacs_ctlx_keymap);
335
  rl_bind_key_in_map ('2', tui_rl_change_windows, tui_ctlx_keymap);
336
  rl_bind_key_in_map ('q', tui_rl_next_keymap, tui_keymap);
337
  rl_bind_key_in_map ('s', tui_rl_next_keymap, emacs_ctlx_keymap);
338
  rl_bind_key_in_map ('s', tui_rl_next_keymap, tui_ctlx_keymap);
339
}
340
 
341
/* Enter in the tui mode (curses).
342
   When in normal mode, it installs the tui hooks in gdb, redirects
343
   the gdb output, configures the readline to work in tui mode.
344
   When in curses mode, it does nothing.  */
345
void
346
tui_enable (void)
347
{
348
  if (tui_active)
349
    return;
350
 
351
  /* To avoid to initialize curses when gdb starts, there is a defered
352
     curses initialization.  This initialization is made only once
353
     and the first time the curses mode is entered.  */
354
  if (tui_finish_init)
355
    {
356
      WINDOW *w;
357
 
358
      w = initscr ();
359
 
360
      cbreak ();
361
      noecho ();
362
      /*timeout (1);*/
363
      nodelay(w, FALSE);
364
      nl();
365
      keypad (w, TRUE);
366
      rl_initialize ();
367
      setTermHeightTo (LINES);
368
      setTermWidthTo (COLS);
369
      def_prog_mode ();
370
 
371
      tuiShowFrameInfo (0);
372
      tuiSetLayout (SRC_COMMAND, TUI_UNDEFINED_REGS);
373
      tuiSetWinFocusTo (srcWin);
374
      keypad (cmdWin->generic.handle, TRUE);
375
      wrefresh (cmdWin->generic.handle);
376
      tui_finish_init = 0;
377
    }
378
  else
379
    {
380
     /* Save the current gdb setting of the terminal.
381
        Curses will restore this state when endwin() is called.  */
382
     def_shell_mode ();
383
     clearok (stdscr, TRUE);
384
   }
385
 
386
  /* Install the TUI specific hooks.  */
387
  tui_install_hooks ();
388
  rl_startup_hook = tui_rl_startup_hook;
389
 
390
  tui_update_variables ();
391
 
392
  tui_setup_io (1);
393
 
394
  tui_version = 1;
395
  tui_active = 1;
396
  if (selected_frame)
397
     tuiShowFrameInfo (selected_frame);
398
 
399
  /* Restore TUI keymap.  */
400
  tui_set_key_mode (tui_current_key_mode);
401
  refresh ();
402
 
403
  /* Update gdb's knowledge of its terminal.  */
404
  target_terminal_save_ours ();
405
  tui_update_gdb_sizes ();
406
}
407
 
408
/* Leave the tui mode.
409
   Remove the tui hooks and configure the gdb output and readline
410
   back to their original state.  The curses mode is left so that
411
   the terminal setting is restored to the point when we entered.  */
412
void
413
tui_disable (void)
414
{
415
  if (!tui_active)
416
    return;
417
 
418
  /* Restore initial readline keymap.  */
419
  rl_set_keymap (tui_readline_standard_keymap);
420
 
421
  /* Remove TUI hooks.  */
422
  tui_remove_hooks ();
423
  rl_startup_hook = 0;
424
  rl_already_prompted = 0;
425
 
426
  /* Leave curses and restore previous gdb terminal setting.  */
427
  endwin ();
428
 
429
  /* gdb terminal has changed, update gdb internal copy of it
430
     so that terminal management with the inferior works.  */
431
  tui_setup_io (0);
432
 
433
  /* Update gdb's knowledge of its terminal.  */
434
  target_terminal_save_ours ();
435
 
436
  tui_version = 0;
437
  tui_active = 0;
438
  tui_update_gdb_sizes ();
439
}
440
 
441
/* Wrapper on top of free() to ensure that input address
442
   is greater than 0x0.  */
443
void
444
tuiFree (char *ptr)
445
{
446
  if (ptr != (char *) NULL)
447
    {
448
      xfree (ptr);
449
    }
450
}
451
 
452
void
453
strcat_to_buf (char *buf, int buflen, const char *itemToAdd)
454
{
455
  if (itemToAdd != (char *) NULL && buf != (char *) NULL)
456
    {
457
      if ((strlen (buf) + strlen (itemToAdd)) <= buflen)
458
        strcat (buf, itemToAdd);
459
      else
460
        strncat (buf, itemToAdd, (buflen - strlen (buf)));
461
    }
462
}
463
 
464
#if 0
465
/* Solaris <sys/termios.h> defines CTRL. */
466
#ifndef CTRL
467
#define CTRL(x)         (x & ~0140)
468
#endif
469
 
470
#define FILEDES         2
471
#define CHK(val, dft)   (val<=0 ? dft : val)
472
 
473
static void
474
_tuiReset (void)
475
{
476
  struct termio mode;
477
 
478
  /*
479
     ** reset the teletype mode bits to a sensible state.
480
     ** Copied tset.c
481
   */
482
#if ! defined (USG) && defined (TIOCGETC)
483
  struct tchars tbuf;
484
#endif /* !USG && TIOCGETC */
485
#ifdef UCB_NTTY
486
  struct ltchars ltc;
487
 
488
  if (ldisc == NTTYDISC)
489
    {
490
      ioctl (FILEDES, TIOCGLTC, &ltc);
491
      ltc.t_suspc = CHK (ltc.t_suspc, CTRL ('Z'));
492
      ltc.t_dsuspc = CHK (ltc.t_dsuspc, CTRL ('Y'));
493
      ltc.t_rprntc = CHK (ltc.t_rprntc, CTRL ('R'));
494
      ltc.t_flushc = CHK (ltc.t_flushc, CTRL ('O'));
495
      ltc.t_werasc = CHK (ltc.t_werasc, CTRL ('W'));
496
      ltc.t_lnextc = CHK (ltc.t_lnextc, CTRL ('V'));
497
      ioctl (FILEDES, TIOCSLTC, &ltc);
498
    }
499
#endif /* UCB_NTTY */
500
#ifndef USG
501
#ifdef TIOCGETC
502
  ioctl (FILEDES, TIOCGETC, &tbuf);
503
  tbuf.t_intrc = CHK (tbuf.t_intrc, CTRL ('?'));
504
  tbuf.t_quitc = CHK (tbuf.t_quitc, CTRL ('\\'));
505
  tbuf.t_startc = CHK (tbuf.t_startc, CTRL ('Q'));
506
  tbuf.t_stopc = CHK (tbuf.t_stopc, CTRL ('S'));
507
  tbuf.t_eofc = CHK (tbuf.t_eofc, CTRL ('D'));
508
  /* brkc is left alone */
509
  ioctl (FILEDES, TIOCSETC, &tbuf);
510
#endif /* TIOCGETC */
511
  mode.sg_flags &= ~(RAW
512
#ifdef CBREAK
513
                     | CBREAK
514
#endif /* CBREAK */
515
                     | VTDELAY | ALLDELAY);
516
  mode.sg_flags |= XTABS | ECHO | CRMOD | ANYP;
517
#else /*USG */
518
  ioctl (FILEDES, TCGETA, &mode);
519
  mode.c_cc[VINTR] = CHK (mode.c_cc[VINTR], CTRL ('?'));
520
  mode.c_cc[VQUIT] = CHK (mode.c_cc[VQUIT], CTRL ('\\'));
521
  mode.c_cc[VEOF] = CHK (mode.c_cc[VEOF], CTRL ('D'));
522
 
523
  mode.c_iflag &= ~(IGNBRK | PARMRK | INPCK | INLCR | IGNCR | IUCLC | IXOFF);
524
  mode.c_iflag |= (BRKINT | ISTRIP | ICRNL | IXON);
525
  mode.c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL |
526
                    NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY);
527
  mode.c_oflag |= (OPOST | ONLCR);
528
  mode.c_cflag &= ~(CSIZE | PARODD | CLOCAL);
529
#ifndef hp9000s800
530
  mode.c_cflag |= (CS8 | CREAD);
531
#else /*hp9000s800 */
532
  mode.c_cflag |= (CS8 | CSTOPB | CREAD);
533
#endif /* hp9000s800 */
534
  mode.c_lflag &= ~(XCASE | ECHONL | NOFLSH);
535
  mode.c_lflag |= (ISIG | ICANON | ECHO | ECHOK);
536
  ioctl (FILEDES, TCSETAW, &mode);
537
#endif /* USG */
538
 
539
  return;
540
}                               /* _tuiReset */
541
#endif
542
 
543
void
544
tui_show_source (const char *file, int line)
545
{
546
  /* make sure that the source window is displayed */
547
  tuiAddWinToLayout (SRC_WIN);
548
 
549
  tuiUpdateSourceWindowsWithLine (current_source_symtab, line);
550
  tuiUpdateLocatorFilename (file);
551
}
552
 
553
void
554
tui_show_assembly (CORE_ADDR addr)
555
{
556
  tuiAddWinToLayout (DISASSEM_WIN);
557
  tuiUpdateSourceWindowsWithAddr (addr);
558
}
559
 
560
int
561
tui_is_window_visible (TuiWinType type)
562
{
563
  if (tui_version == 0)
564
    return 0;
565
 
566
  if (winList[type] == 0)
567
    return 0;
568
 
569
  return winList[type]->generic.isVisible;
570
}
571
 
572
int
573
tui_get_command_dimension (int *width, int *height)
574
{
575
  if (!tui_version || !m_winPtrNotNull (cmdWin))
576
    {
577
      return 0;
578
    }
579
 
580
  *width = cmdWin->generic.width;
581
  *height = cmdWin->generic.height;
582
  return 1;
583
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.