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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [tui/] [tuiIO.c] - Blame information for rev 578

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
 
2
/*
3
   ** This module contains functions to support i/o in the TUI
4
 */
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.  */
25
extern char *tgoto ();
26
 
27
int insert_mode = 0;
28
 
29
/********************************************
30
**       LOCAL STATIC FORWARD DECLS        **
31
********************************************/
32
static void _updateCommandInfo (int);
33
static unsigned int _tuiHandleResizeDuringIO (unsigned int);
34
 
35
 
36
/*********************************************************************************
37
**                              PUBLIC FUNCTIONS                                **
38
*********************************************************************************/
39
 
40
/*
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
 */
49
void
50
#ifdef __STDC__
51
tuiPuts_unfiltered (
52
                     const char *string,
53
                     struct ui_file * stream)
54
#else
55
tuiPuts_unfiltered (string, stream)
56
     char *string;
57
     struct ui_file *stream;
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
 */
111
void
112
tui_tputs (str, affcnt, putfunc)
113
     char *str;
114
     int affcnt;
115
     int (*putfunc) (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.
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
       */
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
 
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,
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
       */
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
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
       */
239
    }
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 */
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
/*
261
   ** tui_vwgetch()
262
   **        Wrapper around wgetch with the window in a va_list
263
 */
264
unsigned int
265
#ifdef __STDC__
266
tui_vwgetch (va_list args)
267
#else
268
tui_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
/*
282
   ** tui_vread()
283
   **   Wrapper around read() with paramets in a va_list
284
 */
285
unsigned int
286
#ifdef __STDC__
287
tui_vread (va_list args)
288
#else
289
tui_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
/*
304
   ** tuiRead()
305
   **    Function to perform a read() catching resize events
306
 */
307
int
308
#ifdef __STDC__
309
tuiRead (
310
          int filedes,
311
          char *buf,
312
          int nbytes)
313
#else
314
tuiRead (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
/*
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
 */
338
unsigned int
339
#ifdef __STDC__
340
tuiGetc (void)
341
#else
342
tuiGetc ()
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
/*
376
   ** tuiBufferGetc().
377
 */
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
384
   utils.c */
385
 
386
unsigned int
387
#ifdef __STDC__
388
tuiBufferGetc (void)
389
#else
390
tuiBufferGetc ()
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
    {
401
      /* this is the first time through, need to read the answer */
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
    {
425
      /*this is the last time through, reset for next query */
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
/*
437
   ** tuiStartNewLines().
438
 */
439
void
440
#ifdef __STDC__
441
tuiStartNewLines (
442
                   int numLines)
443
#else
444
tuiStartNewLines (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
/*
467
   ** tui_vStartNewLines().
468
   **        With numLines in a va_list
469
 */
470
void
471
#ifdef __STDC__
472
tui_vStartNewLines (
473
                     va_list args)
474
#else
475
tui_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
/*
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
 */
498
static 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
/*
521
   ** _updateCommandInfo().
522
   **        Function to update the command window information.
523
 */
524
static 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
 */
552
int 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
 
560
void
561
#ifdef __STDC__
562
tuiTermSetup (
563
               int turn_off_echo)
564
#else
565
tuiTermSetup (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.
583
   */
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)
596
   */
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 (*) (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 (*) (int)) putchar);
622
 
623
    }                           /* else we're out of luck */
624
 
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.
633
   */
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
637
     * place.
638
     * Note I'm relying on refresh()
639
     * only writing what changed (the space),
640
     * not the whole screen.
641
   */
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.  */
655
void
656
#ifdef __STDC__
657
tuiTermUnsetup (
658
                 int turn_on_echo,
659
                 int to_column)
660
#else
661
tuiTermUnsetup (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.
680
   */
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)
695
   */
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).
703
   */
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 (*) (int)) putchar);
712
      tputs (term_memory_lock, 1, (int (*) (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 (*) (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 (*) (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 (*) (int)) putchar);
731
  fflush (stdout);
732
 
733
  tui_owns_terminal = 0;
734
}                               /* tuiTermUnsetup */

powered by: WebSVN 2.1.0

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