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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [readline/] [display.c] - Blame information for rev 106

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

Line No. Rev Author Line
1 106 markom
/* display.c -- readline redisplay facility. */
2
 
3
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
4
 
5
   This file is part of the GNU Readline Library, a library for
6
   reading lines of text with interactive input and history editing.
7
 
8
   The GNU Readline Library is free software; you can redistribute it
9
   and/or modify it under the terms of the GNU General Public License
10
   as published by the Free Software Foundation; either version 1, or
11
   (at your option) any later version.
12
 
13
   The GNU Readline Library is distributed in the hope that it will be
14
   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15
   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   The GNU General Public License is often shipped with GNU software, and
19
   is generally kept in a file called COPYING or LICENSE.  If you do not
20
   have a copy of the license, write to the Free Software Foundation,
21
   675 Mass Ave, Cambridge, MA 02139, USA. */
22
#define READLINE_LIBRARY
23
 
24
#if defined (HAVE_CONFIG_H)
25
#  include <config.h>
26
#endif
27
 
28
#include <sys/types.h>
29
 
30
#if defined (HAVE_UNISTD_H)
31
#  include <unistd.h>
32
#endif /* HAVE_UNISTD_H */
33
 
34
#include "posixstat.h"
35
 
36
#if defined (HAVE_STDLIB_H)
37
#  include <stdlib.h>
38
#else
39
#  include "ansi_stdlib.h"
40
#endif /* HAVE_STDLIB_H */
41
 
42
#include <stdio.h>
43
 
44
#if defined (__GO32__)
45
#  include <go32.h>
46
#  include <pc.h>
47
#endif /* __GO32__ */
48
 
49
/* System-specific feature definitions and include files. */
50
#include "rldefs.h"
51
 
52
/* Termcap library stuff. */
53
#include "tcap.h"
54
 
55
/* Some standard library routines. */
56
#include "readline.h"
57
#include "history.h"
58
 
59
#if !defined (strchr) && !defined (__STDC__)
60
extern char *strchr (), *strrchr ();
61
#endif /* !strchr && !__STDC__ */
62
 
63
/* Global and pseudo-global variables and functions
64
   imported from readline.c. */
65
extern char *rl_prompt;
66
extern int readline_echoing_p;
67
 
68
extern int _rl_output_meta_chars;
69
extern int _rl_horizontal_scroll_mode;
70
extern int _rl_mark_modified_lines;
71
extern int _rl_prefer_visible_bell;
72
 
73
/* Variables and functions imported from terminal.c */
74
extern void _rl_output_some_chars ();
75
#ifdef _MINIX
76
extern void _rl_output_character_function ();
77
#else
78
extern int _rl_output_character_function ();
79
#endif
80
extern int _rl_backspace ();
81
 
82
extern char *term_clreol, *term_clrpag;
83
extern char *term_im, *term_ic,  *term_ei, *term_DC;
84
extern char *term_up, *term_dc, *term_cr, *term_IC;
85
extern int screenheight, screenwidth, screenchars;
86
extern int terminal_can_insert, _rl_term_autowrap;
87
 
88
/* Pseudo-global functions (local to the readline library) exported
89
   by this file. */
90
void _rl_move_cursor_relative (), _rl_output_some_chars ();
91
void _rl_move_vert ();
92
void _rl_clear_to_eol (), _rl_clear_screen ();
93
 
94
static void update_line (), space_to_eol ();
95
static void delete_chars (), insert_some_chars ();
96
static void cr ();
97
 
98
static int *inv_lbreaks, *vis_lbreaks;
99
 
100
extern char *xmalloc (), *xrealloc ();
101
 
102
/* Heuristic used to decide whether it is faster to move from CUR to NEW
103
   by backing up or outputting a carriage return and moving forward. */
104
#define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new)))
105
 
106
/* **************************************************************** */
107
/*                                                                  */
108
/*                      Display stuff                               */
109
/*                                                                  */
110
/* **************************************************************** */
111
 
112
/* This is the stuff that is hard for me.  I never seem to write good
113
   display routines in C.  Let's see how I do this time. */
114
 
115
/* (PWP) Well... Good for a simple line updater, but totally ignores
116
   the problems of input lines longer than the screen width.
117
 
118
   update_line and the code that calls it makes a multiple line,
119
   automatically wrapping line update.  Careful attention needs
120
   to be paid to the vertical position variables. */
121
 
122
/* Keep two buffers; one which reflects the current contents of the
123
   screen, and the other to draw what we think the new contents should
124
   be.  Then compare the buffers, and make whatever changes to the
125
   screen itself that we should.  Finally, make the buffer that we
126
   just drew into be the one which reflects the current contents of the
127
   screen, and place the cursor where it belongs.
128
 
129
   Commands that want to can fix the display themselves, and then let
130
   this function know that the display has been fixed by setting the
131
   RL_DISPLAY_FIXED variable.  This is good for efficiency. */
132
 
133
/* Application-specific redisplay function. */
134
VFunction *rl_redisplay_function = rl_redisplay;
135
 
136
/* Global variables declared here. */
137
/* What YOU turn on when you have handled all redisplay yourself. */
138
int rl_display_fixed = 0;
139
 
140
int _rl_suppress_redisplay = 0;
141
 
142
/* The stuff that gets printed out before the actual text of the line.
143
   This is usually pointing to rl_prompt. */
144
char *rl_display_prompt = (char *)NULL;
145
 
146
/* Pseudo-global variables declared here. */
147
/* The visible cursor position.  If you print some text, adjust this. */
148
int _rl_last_c_pos = 0;
149
int _rl_last_v_pos = 0;
150
 
151
/* Number of lines currently on screen minus 1. */
152
int _rl_vis_botlin = 0;
153
 
154
/* Variables used only in this file. */
155
/* The last left edge of text that was displayed.  This is used when
156
   doing horizontal scrolling.  It shifts in thirds of a screenwidth. */
157
static int last_lmargin;
158
 
159
/* The line display buffers.  One is the line currently displayed on
160
   the screen.  The other is the line about to be displayed. */
161
static char *visible_line = (char *)NULL;
162
static char *invisible_line = (char *)NULL;
163
 
164
/* A buffer for `modeline' messages. */
165
static char msg_buf[128];
166
 
167
/* Non-zero forces the redisplay even if we thought it was unnecessary. */
168
static int forced_display;
169
 
170
/* Default and initial buffer size.  Can grow. */
171
static int line_size = 1024;
172
 
173
static char *local_prompt, *local_prompt_prefix;
174
static int visible_length, prefix_length;
175
 
176
/* The number of invisible characters in the line currently being
177
   displayed on the screen. */
178
static int visible_wrap_offset;
179
 
180
/* static so it can be shared between rl_redisplay and update_line */
181
static int wrap_offset;
182
 
183
/* The index of the last invisible_character in the prompt string. */
184
static int last_invisible;
185
 
186
/* The length (buffer offset) of the first line of the last (possibly
187
   multi-line) buffer displayed on the screen. */
188
static int visible_first_line_len;
189
 
190
/* Expand the prompt string S and return the number of visible
191
   characters in *LP, if LP is not null.  This is currently more-or-less
192
   a placeholder for expansion.  LIP, if non-null is a place to store the
193
   index of the last invisible character in ther eturned string. */
194
 
195
/* Current implementation:
196
        \001 (^A) start non-visible characters
197
        \002 (^B) end non-visible characters
198
   all characters except \001 and \002 (following a \001) are copied to
199
   the returned string; all characters except those between \001 and
200
   \002 are assumed to be `visible'. */
201
 
202
static char *
203
expand_prompt (pmt, lp, lip)
204
     char *pmt;
205
     int *lp, *lip;
206
{
207
  char *r, *ret, *p;
208
  int l, rl, last, ignoring;
209
 
210
  /* Short-circuit if we can. */
211
  if (strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
212
    {
213
      r = savestring (pmt);
214
      if (lp)
215
        *lp = strlen (r);
216
      return r;
217
    }
218
 
219
  l = strlen (pmt);
220
  r = ret = xmalloc (l + 1);
221
 
222
  for (rl = ignoring = last = 0, p = pmt; p && *p; p++)
223
    {
224
      /* This code strips the invisible character string markers
225
         RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
226
      if (*p == RL_PROMPT_START_IGNORE)
227
        {
228
          ignoring++;
229
          continue;
230
        }
231
      else if (ignoring && *p == RL_PROMPT_END_IGNORE)
232
        {
233
          ignoring = 0;
234
          last = r - ret - 1;
235
          continue;
236
        }
237
      else
238
        {
239
          *r++ = *p;
240
          if (!ignoring)
241
            rl++;
242
        }
243
    }
244
 
245
  *r = '\0';
246
  if (lp)
247
    *lp = rl;
248
  if (lip)
249
    *lip = last;
250
  return ret;
251
}
252
 
253
/*
254
 * Expand the prompt string into the various display components, if
255
 * necessary.
256
 *
257
 * local_prompt = expanded last line of string in rl_display_prompt
258
 *                (portion after the final newline)
259
 * local_prompt_prefix = portion before last newline of rl_display_prompt,
260
 *                       expanded via expand_prompt
261
 * visible_length = number of visible characters in local_prompt
262
 * prefix_length = number of visible characters in local_prompt_prefix
263
 *
264
 * This function is called once per call to readline().  It may also be
265
 * called arbitrarily to expand the primary prompt.
266
 *
267
 * The return value is the number of visible characters on the last line
268
 * of the (possibly multi-line) prompt.
269
 */
270
int
271
rl_expand_prompt (prompt)
272
     char *prompt;
273
{
274
  char *p, *t;
275
  int c;
276
 
277
  /* Clear out any saved values. */
278
  if (local_prompt)
279
    free (local_prompt);
280
  if (local_prompt_prefix)
281
    free (local_prompt_prefix);
282
  local_prompt = local_prompt_prefix = (char *)0;
283
  last_invisible = visible_length = 0;
284
 
285
  if (prompt == 0 || *prompt == 0)
286
    return (0);
287
 
288
  p = strrchr (prompt, '\n');
289
  if (!p)
290
    {
291
      /* The prompt is only one line. */
292
      local_prompt = expand_prompt (prompt, &visible_length, &last_invisible);
293
      local_prompt_prefix = (char *)0;
294
      return (visible_length);
295
    }
296
  else
297
    {
298
      /* The prompt spans multiple lines. */
299
      t = ++p;
300
      local_prompt = expand_prompt (p, &visible_length, &last_invisible);
301
      c = *t; *t = '\0';
302
      /* The portion of the prompt string up to and including the
303
         final newline is now null-terminated. */
304
      local_prompt_prefix = expand_prompt (prompt, &prefix_length, (int *)NULL);
305
      *t = c;
306
      return (prefix_length);
307
    }
308
}
309
 
310
/* Basic redisplay algorithm. */
311
void
312
rl_redisplay ()
313
{
314
  register int in, out, c, linenum, cursor_linenum;
315
  register char *line;
316
  int c_pos, inv_botlin, lb_botlin, lb_linenum;
317
  int newlines, lpos, temp;
318
  char *prompt_this_line;
319
 
320
  if (!readline_echoing_p)
321
    return;
322
 
323
  if (!rl_display_prompt)
324
    rl_display_prompt = "";
325
 
326
  if (invisible_line == 0)
327
    {
328
      visible_line = xmalloc (line_size);
329
      invisible_line = xmalloc (line_size);
330
      for (in = 0; in < line_size; in++)
331
        {
332
          visible_line[in] = 0;
333
          invisible_line[in] = 1;
334
        }
335
 
336
      /* should be enough, but then again, this is just for testing. */
337
      inv_lbreaks = (int *)malloc (256 * sizeof (int));
338
      vis_lbreaks = (int *)malloc (256 * sizeof (int));
339
      inv_lbreaks[0] = vis_lbreaks[0] = 0;
340
 
341
      rl_on_new_line ();
342
    }
343
 
344
  /* Draw the line into the buffer. */
345
  c_pos = -1;
346
 
347
  line = invisible_line;
348
  out = inv_botlin = 0;
349
 
350
  /* Mark the line as modified or not.  We only do this for history
351
     lines. */
352
  if (_rl_mark_modified_lines && current_history () && rl_undo_list)
353
    {
354
      line[out++] = '*';
355
      line[out] = '\0';
356
    }
357
 
358
  /* If someone thought that the redisplay was handled, but the currently
359
     visible line has a different modification state than the one about
360
     to become visible, then correct the caller's misconception. */
361
  if (visible_line[0] != invisible_line[0])
362
    rl_display_fixed = 0;
363
 
364
  /* If the prompt to be displayed is the `primary' readline prompt (the
365
     one passed to readline()), use the values we have already expanded.
366
     If not, use what's already in rl_display_prompt.  WRAP_OFFSET is the
367
     number of non-visible characters in the prompt string. */
368
  if (rl_display_prompt == rl_prompt || local_prompt)
369
    {
370
      int local_len = local_prompt ? strlen (local_prompt) : 0;
371
      if (local_prompt_prefix && forced_display)
372
        _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));
373
 
374
      if (local_len > 0)
375
        {
376
          temp = local_len + out + 2;
377
          if (temp >= line_size)
378
            {
379
              line_size = (temp + 1024) - (temp % 1024);
380
              visible_line = xrealloc (visible_line, line_size);
381
              line = invisible_line = xrealloc (invisible_line, line_size);
382
            }
383
          strncpy (line + out, local_prompt, local_len);
384
          out += local_len;
385
        }
386
      line[out] = '\0';
387
      wrap_offset = local_len - visible_length;
388
    }
389
  else
390
    {
391
      int pmtlen;
392
      prompt_this_line = strrchr (rl_display_prompt, '\n');
393
      if (!prompt_this_line)
394
        prompt_this_line = rl_display_prompt;
395
      else
396
        {
397
          prompt_this_line++;
398
          if (forced_display)
399
            {
400
              _rl_output_some_chars (rl_display_prompt, prompt_this_line - rl_display_prompt);
401
              /* Make sure we are at column zero even after a newline,
402
                 regardless of the state of terminal output processing. */
403
              if (prompt_this_line[-2] != '\r')
404
                cr ();
405
            }
406
        }
407
 
408
      pmtlen = strlen (prompt_this_line);
409
      temp = pmtlen + out + 2;
410
      if (temp >= line_size)
411
        {
412
          line_size = (temp + 1024) - (temp % 1024);
413
          visible_line = xrealloc (visible_line, line_size);
414
          line = invisible_line = xrealloc (invisible_line, line_size);
415
        }
416
      strncpy (line + out,  prompt_this_line, pmtlen);
417
      out += pmtlen;
418
      line[out] = '\0';
419
      wrap_offset = 0;
420
    }
421
 
422
#define CHECK_LPOS() \
423
      do { \
424
        lpos++; \
425
        if (lpos >= screenwidth) \
426
          { \
427
            inv_lbreaks[++newlines] = out; \
428
            lpos = 0; \
429
          } \
430
      } while (0)
431
 
432
  /* inv_lbreaks[i] is where line i starts in the buffer. */
433
  inv_lbreaks[newlines = 0] = 0;
434
  lpos = out - wrap_offset;
435
 
436
  /* XXX - what if lpos is already >= screenwidth before we start drawing the
437
     contents of the command line? */
438
  while (lpos >= screenwidth)
439
    {
440
#if 0
441
      temp = ((newlines + 1) * screenwidth) - ((newlines == 0) ? wrap_offset : 0);
442
#else
443
      /* XXX - possible fix from Darin Johnson <darin@acuson.com> for prompt
444
         string with invisible characters that is longer than the screen
445
         width. */
446
      temp = ((newlines + 1) * screenwidth) + ((newlines == 0) ? wrap_offset : 0);
447
#endif
448
      inv_lbreaks[++newlines] = temp;
449
      lpos -= screenwidth;
450
    }
451
 
452
  lb_linenum = 0;
453
  for (in = 0; in < rl_end; in++)
454
    {
455
      c = (unsigned char)rl_line_buffer[in];
456
 
457
      if (out + 8 >= line_size)         /* XXX - 8 for \t */
458
        {
459
          line_size *= 2;
460
          visible_line = xrealloc (visible_line, line_size);
461
          invisible_line = xrealloc (invisible_line, line_size);
462
          line = invisible_line;
463
        }
464
 
465
      if (in == rl_point)
466
        {
467
          c_pos = out;
468
          lb_linenum = newlines;
469
        }
470
 
471
      if (META_CHAR (c))
472
        {
473
          if (_rl_output_meta_chars == 0)
474
            {
475
              sprintf (line + out, "\\%o", c);
476
 
477
              if (lpos + 4 >= screenwidth)
478
                {
479
                  temp = screenwidth - lpos;
480
                  inv_lbreaks[++newlines] = out + temp;
481
                  lpos = 4 - temp;
482
                }
483
              else
484
                lpos += 4;
485
 
486
              out += 4;
487
            }
488
          else
489
            {
490
              line[out++] = c;
491
              CHECK_LPOS();
492
            }
493
        }
494
#if defined (DISPLAY_TABS)
495
      else if (c == '\t')
496
        {
497
          register int temp, newout;
498
 
499
#if 0
500
          newout = (out | (int)7) + 1;
501
#else
502
          newout = out + 8 - lpos % 8;
503
#endif
504
          temp = newout - out;
505
          if (lpos + temp >= screenwidth)
506
            {
507
              register int temp2;
508
              temp2 = screenwidth - lpos;
509
              inv_lbreaks[++newlines] = out + temp2;
510
              lpos = temp - temp2;
511
              while (out < newout)
512
                line[out++] = ' ';
513
            }
514
          else
515
            {
516
              while (out < newout)
517
                line[out++] = ' ';
518
              lpos += temp;
519
            }
520
        }
521
#endif
522
      else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && term_up && *term_up)
523
        {
524
          line[out++] = '\0';   /* XXX - sentinel */
525
          inv_lbreaks[++newlines] = out;
526
          lpos = 0;
527
        }
528
      else if (CTRL_CHAR (c) || c == RUBOUT)
529
        {
530
          line[out++] = '^';
531
          CHECK_LPOS();
532
          line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
533
          CHECK_LPOS();
534
        }
535
      else
536
        {
537
          line[out++] = c;
538
          CHECK_LPOS();
539
        }
540
    }
541
  line[out] = '\0';
542
  if (c_pos < 0)
543
    {
544
      c_pos = out;
545
      lb_linenum = newlines;
546
    }
547
 
548
  inv_botlin = lb_botlin = newlines;
549
  inv_lbreaks[newlines+1] = out;
550
  cursor_linenum = lb_linenum;
551
 
552
  /* C_POS == position in buffer where cursor should be placed. */
553
 
554
  /* PWP: now is when things get a bit hairy.  The visible and invisible
555
     line buffers are really multiple lines, which would wrap every
556
     (screenwidth - 1) characters.  Go through each in turn, finding
557
     the changed region and updating it.  The line order is top to bottom. */
558
 
559
  /* If we can move the cursor up and down, then use multiple lines,
560
     otherwise, let long lines display in a single terminal line, and
561
     horizontally scroll it. */
562
 
563
  if (_rl_horizontal_scroll_mode == 0 && term_up && *term_up)
564
    {
565
      int nleft, pos, changed_screen_line;
566
 
567
      if (!rl_display_fixed || forced_display)
568
        {
569
          forced_display = 0;
570
 
571
          /* If we have more than a screenful of material to display, then
572
             only display a screenful.  We should display the last screen,
573
             not the first.  */
574
          if (out >= screenchars)
575
            out = screenchars - 1;
576
 
577
          /* The first line is at character position 0 in the buffer.  The
578
             second and subsequent lines start at inv_lbreaks[N], offset by
579
             OFFSET (which has already been calculated above).  */
580
 
581
#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
582
#define VIS_LLEN(l)     ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
583
#define INV_LLEN(l)     (inv_lbreaks[l+1] - inv_lbreaks[l])
584
#define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
585
#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
586
#define INV_LINE(line) (invisible_line + inv_lbreaks[line])
587
 
588
          /* For each line in the buffer, do the updating display. */
589
          for (linenum = 0; linenum <= inv_botlin; linenum++)
590
            {
591
              update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
592
                           VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
593
 
594
              /* If this is the line with the prompt, we might need to
595
                 compensate for invisible characters in the new line. Do
596
                 this only if there is not more than one new line (which
597
                 implies that we completely overwrite the old visible line)
598
                 and the new line is shorter than the old.  Make sure we are
599
                 at the end of the new line before clearing. */
600
              if (linenum == 0 &&
601
                  inv_botlin == 0 && _rl_last_c_pos == out &&
602
                  (wrap_offset > visible_wrap_offset) &&
603
                  (_rl_last_c_pos < visible_first_line_len))
604
                {
605
                  nleft = screenwidth + wrap_offset - _rl_last_c_pos;
606
                  if (nleft)
607
                    _rl_clear_to_eol (nleft);
608
                }
609
 
610
              /* Since the new first line is now visible, save its length. */
611
              if (linenum == 0)
612
                visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset;
613
            }
614
 
615
          /* We may have deleted some lines.  If so, clear the left over
616
             blank ones at the bottom out. */
617
          if (_rl_vis_botlin > inv_botlin)
618
            {
619
              char *tt;
620
              for (; linenum <= _rl_vis_botlin; linenum++)
621
                {
622
                  tt = VIS_CHARS (linenum);
623
                  _rl_move_vert (linenum);
624
                  _rl_move_cursor_relative (0, tt);
625
                  _rl_clear_to_eol
626
                    ((linenum == _rl_vis_botlin) ? strlen (tt) : screenwidth);
627
                }
628
            }
629
          _rl_vis_botlin = inv_botlin;
630
 
631
          /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a
632
             different screen line during this redisplay. */
633
          changed_screen_line = _rl_last_v_pos != cursor_linenum;
634
          if (changed_screen_line)
635
            {
636
              _rl_move_vert (cursor_linenum);
637
              /* If we moved up to the line with the prompt using term_up,
638
                 the physical cursor position on the screen stays the same,
639
                 but the buffer position needs to be adjusted to account
640
                 for invisible characters. */
641
              if (cursor_linenum == 0 && wrap_offset)
642
                _rl_last_c_pos += wrap_offset;
643
            }
644
 
645
          /* We have to reprint the prompt if it contains invisible
646
             characters, since it's not generally OK to just reprint
647
             the characters from the current cursor position.  But we
648
             only need to reprint it if the cursor is before the last
649
             invisible character in the prompt string. */
650
          nleft = visible_length + wrap_offset;
651
          if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
652
              _rl_last_c_pos <= last_invisible && local_prompt)
653
            {
654
#if defined (__MSDOS__)
655
              putc ('\r', rl_outstream);
656
#else
657
              if (term_cr)
658
                tputs (term_cr, 1, _rl_output_character_function);
659
#endif
660
              _rl_output_some_chars (local_prompt, nleft);
661
              _rl_last_c_pos = nleft;
662
            }
663
 
664
          /* Where on that line?  And where does that line start
665
             in the buffer? */
666
          pos = inv_lbreaks[cursor_linenum];
667
          /* nleft == number of characters in the line buffer between the
668
             start of the line and the cursor position. */
669
          nleft = c_pos - pos;
670
 
671
          /* Since _rl_backspace() doesn't know about invisible characters in the
672
             prompt, and there's no good way to tell it, we compensate for
673
             those characters here and call _rl_backspace() directly. */
674
          if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
675
            {
676
              _rl_backspace (_rl_last_c_pos - nleft);
677
              _rl_last_c_pos = nleft;
678
            }
679
 
680
          if (nleft != _rl_last_c_pos)
681
            _rl_move_cursor_relative (nleft, &invisible_line[pos]);
682
        }
683
    }
684
  else                          /* Do horizontal scrolling. */
685
    {
686
#define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0)
687
      int lmargin, ndisp, nleft, phys_c_pos, t;
688
 
689
      /* Always at top line. */
690
      _rl_last_v_pos = 0;
691
 
692
      /* Compute where in the buffer the displayed line should start.  This
693
         will be LMARGIN. */
694
 
695
      /* The number of characters that will be displayed before the cursor. */
696
      ndisp = c_pos - wrap_offset;
697
      nleft  = visible_length + wrap_offset;
698
      /* Where the new cursor position will be on the screen.  This can be
699
         longer than SCREENWIDTH; if it is, lmargin will be adjusted. */
700
      phys_c_pos = c_pos - (last_lmargin ? last_lmargin : wrap_offset);
701
      t = screenwidth / 3;
702
 
703
      /* If the number of characters had already exceeded the screenwidth,
704
         last_lmargin will be > 0. */
705
 
706
      /* If the number of characters to be displayed is more than the screen
707
         width, compute the starting offset so that the cursor is about
708
         two-thirds of the way across the screen. */
709
      if (phys_c_pos > screenwidth - 2)
710
        {
711
          lmargin = c_pos - (2 * t);
712
          if (lmargin < 0)
713
            lmargin = 0;
714
          /* If the left margin would be in the middle of a prompt with
715
             invisible characters, don't display the prompt at all. */
716
          if (wrap_offset && lmargin > 0 && lmargin < nleft)
717
            lmargin = nleft;
718
        }
719
      else if (ndisp < screenwidth - 2)         /* XXX - was -1 */
720
        lmargin = 0;
721
      else if (phys_c_pos < 1)
722
        {
723
          /* If we are moving back towards the beginning of the line and
724
             the last margin is no longer correct, compute a new one. */
725
          lmargin = ((c_pos - 1) / t) * t;      /* XXX */
726
          if (wrap_offset && lmargin > 0 && lmargin < nleft)
727
            lmargin = nleft;
728
        }
729
      else
730
        lmargin = last_lmargin;
731
 
732
      /* If the first character on the screen isn't the first character
733
         in the display line, indicate this with a special character. */
734
      if (lmargin > 0)
735
        line[lmargin] = '<';
736
 
737
      /* If SCREENWIDTH characters starting at LMARGIN do not encompass
738
         the whole line, indicate that with a special character at the
739
         right edge of the screen.  If LMARGIN is 0, we need to take the
740
         wrap offset into account. */
741
      t = lmargin + M_OFFSET (lmargin, wrap_offset) + screenwidth;
742
      if (t < out)
743
        line[t - 1] = '>';
744
 
745
      if (!rl_display_fixed || forced_display || lmargin != last_lmargin)
746
        {
747
          forced_display = 0;
748
          update_line (&visible_line[last_lmargin],
749
                       &invisible_line[lmargin],
750
                       0,
751
                       screenwidth + visible_wrap_offset,
752
                       screenwidth + (lmargin ? 0 : wrap_offset),
753
                       0);
754
 
755
          /* If the visible new line is shorter than the old, but the number
756
             of invisible characters is greater, and we are at the end of
757
             the new line, we need to clear to eol. */
758
          t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset);
759
          if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) &&
760
              (_rl_last_c_pos == out) &&
761
              t < visible_first_line_len)
762
            {
763
              nleft = screenwidth - t;
764
              _rl_clear_to_eol (nleft);
765
            }
766
          visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset);
767
          if (visible_first_line_len > screenwidth)
768
            visible_first_line_len = screenwidth;
769
 
770
          _rl_move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);
771
          last_lmargin = lmargin;
772
        }
773
    }
774
  fflush (rl_outstream);
775
 
776
  /* Swap visible and non-visible lines. */
777
  {
778
    char *temp = visible_line;
779
    int *itemp = vis_lbreaks;
780
    visible_line = invisible_line;
781
    invisible_line = temp;
782
    vis_lbreaks = inv_lbreaks;
783
    inv_lbreaks = itemp;
784
    rl_display_fixed = 0;
785
    /* If we are displaying on a single line, and last_lmargin is > 0, we
786
       are not displaying any invisible characters, so set visible_wrap_offset
787
       to 0. */
788
    if (_rl_horizontal_scroll_mode && last_lmargin)
789
      visible_wrap_offset = 0;
790
    else
791
      visible_wrap_offset = wrap_offset;
792
  }
793
}
794
 
795
/* PWP: update_line() is based on finding the middle difference of each
796
   line on the screen; vis:
797
 
798
                             /old first difference
799
        /beginning of line   |        /old last same       /old EOL
800
        v                    v        v             v
801
old:    eddie> Oh, my little gruntle-buggy is to me, as lurgid as
802
new:    eddie> Oh, my little buggy says to me, as lurgid as
803
        ^                    ^  ^                          ^
804
        \beginning of line   |  \new last same     \new end of line
805
                             \new first difference
806
 
807
   All are character pointers for the sake of speed.  Special cases for
808
   no differences, as well as for end of line additions must be handled.
809
 
810
   Could be made even smarter, but this works well enough */
811
static void
812
update_line (old, new, current_line, omax, nmax, inv_botlin)
813
     register char *old, *new;
814
     int current_line, omax, nmax, inv_botlin;
815
{
816
  register char *ofd, *ols, *oe, *nfd, *nls, *ne;
817
  int temp, lendiff, wsatend, od, nd;
818
  int current_invis_chars;
819
 
820
  /* If we're at the right edge of a terminal that supports xn, we're
821
     ready to wrap around, so do so.  This fixes problems with knowing
822
     the exact cursor position and cut-and-paste with certain terminal
823
     emulators.  In this calculation, TEMP is the physical screen
824
     position of the cursor. */
825
  temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
826
  if (temp == screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
827
      && _rl_last_v_pos == current_line - 1)
828
    {
829
      if (new[0])
830
        putc (new[0], rl_outstream);
831
      else
832
        putc (' ', rl_outstream);
833
      _rl_last_c_pos = 1;               /* XXX */
834
      _rl_last_v_pos++;
835
      if (old[0] && new[0])
836
        old[0] = new[0];
837
    }
838
 
839
  /* Find first difference. */
840
  for (ofd = old, nfd = new;
841
       (ofd - old < omax) && *ofd && (*ofd == *nfd);
842
       ofd++, nfd++)
843
    ;
844
 
845
  /* Move to the end of the screen line.  ND and OD are used to keep track
846
     of the distance between ne and new and oe and old, respectively, to
847
     move a subtraction out of each loop. */
848
  for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++);
849
  for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++);
850
 
851
  /* If no difference, continue to next line. */
852
  if (ofd == oe && nfd == ne)
853
    return;
854
 
855
  wsatend = 1;                  /* flag for trailing whitespace */
856
  ols = oe - 1;                 /* find last same */
857
  nls = ne - 1;
858
  while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
859
    {
860
      if (*ols != ' ')
861
        wsatend = 0;
862
      ols--;
863
      nls--;
864
    }
865
 
866
  if (wsatend)
867
    {
868
      ols = oe;
869
      nls = ne;
870
    }
871
  else if (*ols != *nls)
872
    {
873
      if (*ols)                 /* don't step past the NUL */
874
        ols++;
875
      if (*nls)
876
        nls++;
877
    }
878
 
879
  /* count of invisible characters in the current invisible line. */
880
  current_invis_chars = W_OFFSET (current_line, wrap_offset);
881
  if (_rl_last_v_pos != current_line)
882
    {
883
      _rl_move_vert (current_line);
884
      if (current_line == 0 && visible_wrap_offset)
885
        _rl_last_c_pos += visible_wrap_offset;
886
    }
887
 
888
  /* If this is the first line and there are invisible characters in the
889
     prompt string, and the prompt string has not changed, and the current
890
     cursor position is before the last invisible character in the prompt,
891
     and the index of the character to move to is past the end of the prompt
892
     string, then redraw the entire prompt string.  We can only do this
893
     reliably if the terminal supports a `cr' capability.
894
 
895
     This is not an efficiency hack -- there is a problem with redrawing
896
     portions of the prompt string if they contain terminal escape
897
     sequences (like drawing the `unbold' sequence without a corresponding
898
     `bold') that manifests itself on certain terminals. */
899
 
900
  lendiff = local_prompt ? strlen (local_prompt) : 0;
901
  od = ofd - old;       /* index of first difference in visible line */
902
  if (current_line == 0 && !_rl_horizontal_scroll_mode &&
903
      term_cr && lendiff > visible_length && _rl_last_c_pos > 0 &&
904
      od > lendiff && _rl_last_c_pos < last_invisible)
905
    {
906
#if defined (__MSDOS__)
907
      putc ('\r', rl_outstream);
908
#else
909
      tputs (term_cr, 1, _rl_output_character_function);
910
#endif /* !__MSDOS__ */
911
      _rl_output_some_chars (local_prompt, lendiff);
912
      _rl_last_c_pos = lendiff;
913
    }
914
 
915
  _rl_move_cursor_relative (od, old);
916
 
917
  /* if (len (new) > len (old)) */
918
  lendiff = (nls - nfd) - (ols - ofd);
919
 
920
  /* If we are changing the number of invisible characters in a line, and
921
     the spot of first difference is before the end of the invisible chars,
922
     lendiff needs to be adjusted. */
923
  if (current_line == 0 && !_rl_horizontal_scroll_mode &&
924
      current_invis_chars != visible_wrap_offset)
925
    lendiff += visible_wrap_offset - current_invis_chars;
926
 
927
  /* Insert (diff (len (old), len (new)) ch. */
928
  temp = ne - nfd;
929
  if (lendiff > 0)
930
    {
931
      /* Non-zero if we're increasing the number of lines. */
932
      int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
933
      /* Sometimes it is cheaper to print the characters rather than
934
         use the terminal's capabilities.  If we're growing the number
935
         of lines, make sure we actually cause the new line to wrap
936
         around on auto-wrapping terminals. */
937
      if (terminal_can_insert && ((2 * temp) >= lendiff || term_IC) && (!_rl_term_autowrap || !gl))
938
        {
939
          /* If lendiff > visible_length and _rl_last_c_pos == 0 and
940
             _rl_horizontal_scroll_mode == 1, inserting the characters with
941
             term_IC or term_ic will screw up the screen because of the
942
             invisible characters.  We need to just draw them. */
943
          if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 ||
944
                        lendiff <= visible_length || !current_invis_chars))
945
            {
946
              insert_some_chars (nfd, lendiff);
947
              _rl_last_c_pos += lendiff;
948
            }
949
          else if (*ols == 0)
950
            {
951
              /* At the end of a line the characters do not have to
952
                 be "inserted".  They can just be placed on the screen. */
953
              /* However, this screws up the rest of this block, which
954
                 assumes you've done the insert because you can. */
955
              _rl_output_some_chars (nfd, lendiff);
956
              _rl_last_c_pos += lendiff;
957
            }
958
          else
959
            {
960
              /* We have horizontal scrolling and we are not inserting at
961
                 the end.  We have invisible characters in this line.  This
962
                 is a dumb update. */
963
              _rl_output_some_chars (nfd, temp);
964
              _rl_last_c_pos += temp;
965
              return;
966
            }
967
          /* Copy (new) chars to screen from first diff to last match. */
968
          temp = nls - nfd;
969
          if ((temp - lendiff) > 0)
970
            {
971
              _rl_output_some_chars (nfd + lendiff, temp - lendiff);
972
              _rl_last_c_pos += temp - lendiff;
973
            }
974
        }
975
      else
976
        {
977
          /* cannot insert chars, write to EOL */
978
          _rl_output_some_chars (nfd, temp);
979
          _rl_last_c_pos += temp;
980
        }
981
    }
982
  else                          /* Delete characters from line. */
983
    {
984
      /* If possible and inexpensive to use terminal deletion, then do so. */
985
      if (term_dc && (2 * temp) >= -lendiff)
986
        {
987
          /* If all we're doing is erasing the invisible characters in the
988
             prompt string, don't bother.  It screws up the assumptions
989
             about what's on the screen. */
990
          if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 &&
991
              -lendiff == visible_wrap_offset)
992
            lendiff = 0;
993
 
994
          if (lendiff)
995
            delete_chars (-lendiff); /* delete (diff) characters */
996
 
997
          /* Copy (new) chars to screen from first diff to last match */
998
          temp = nls - nfd;
999
          if (temp > 0)
1000
            {
1001
              _rl_output_some_chars (nfd, temp);
1002
              _rl_last_c_pos += temp;
1003
            }
1004
        }
1005
      /* Otherwise, print over the existing material. */
1006
      else
1007
        {
1008
          if (temp > 0)
1009
            {
1010
              _rl_output_some_chars (nfd, temp);
1011
              _rl_last_c_pos += temp;
1012
            }
1013
          lendiff = (oe - old) - (ne - new);
1014
          if (lendiff)
1015
            {
1016
              if (_rl_term_autowrap && current_line < inv_botlin)
1017
                space_to_eol (lendiff);
1018
              else
1019
                _rl_clear_to_eol (lendiff);
1020
            }
1021
        }
1022
    }
1023
}
1024
 
1025
/* Tell the update routines that we have moved onto a new (empty) line. */
1026
int
1027
rl_on_new_line ()
1028
{
1029
  if (visible_line)
1030
    visible_line[0] = '\0';
1031
 
1032
  _rl_last_c_pos = _rl_last_v_pos = 0;
1033
  _rl_vis_botlin = last_lmargin = 0;
1034
  if (vis_lbreaks)
1035
    vis_lbreaks[0] = vis_lbreaks[1] = 0;
1036
  visible_wrap_offset = 0;
1037
  return 0;
1038
}
1039
 
1040
/* Actually update the display, period. */
1041
int
1042
rl_forced_update_display ()
1043
{
1044
  if (visible_line)
1045
    {
1046
      register char *temp = visible_line;
1047
 
1048
      while (*temp)
1049
        *temp++ = '\0';
1050
    }
1051
  rl_on_new_line ();
1052
  forced_display++;
1053
  (*rl_redisplay_function) ();
1054
  return 0;
1055
}
1056
 
1057
/* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices.
1058
   DATA is the contents of the screen line of interest; i.e., where
1059
   the movement is being done. */
1060
void
1061
_rl_move_cursor_relative (new, data)
1062
     int new;
1063
     char *data;
1064
{
1065
  register int i;
1066
 
1067
  /* If we don't have to do anything, then return. */
1068
  if (_rl_last_c_pos == new) return;
1069
 
1070
  /* It may be faster to output a CR, and then move forwards instead
1071
     of moving backwards. */
1072
  /* i == current physical cursor position. */
1073
  i = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
1074
  if (new == 0 || CR_FASTER (new, _rl_last_c_pos) ||
1075
      (_rl_term_autowrap && i == screenwidth))
1076
    {
1077
#if defined (__MSDOS__)
1078
      putc ('\r', rl_outstream);
1079
#else
1080
      tputs (term_cr, 1, _rl_output_character_function);
1081
#endif /* !__MSDOS__ */
1082
      _rl_last_c_pos = 0;
1083
    }
1084
 
1085
  if (_rl_last_c_pos < new)
1086
    {
1087
      /* Move the cursor forward.  We do it by printing the command
1088
         to move the cursor forward if there is one, else print that
1089
         portion of the output buffer again.  Which is cheaper? */
1090
 
1091
      /* The above comment is left here for posterity.  It is faster
1092
         to print one character (non-control) than to print a control
1093
         sequence telling the terminal to move forward one character.
1094
         That kind of control is for people who don't know what the
1095
         data is underneath the cursor. */
1096
#if defined (HACK_TERMCAP_MOTION)
1097
      extern char *term_forward_char;
1098
 
1099
      if (term_forward_char)
1100
        for (i = _rl_last_c_pos; i < new; i++)
1101
          tputs (term_forward_char, 1, _rl_output_character_function);
1102
      else
1103
        for (i = _rl_last_c_pos; i < new; i++)
1104
          putc (data[i], rl_outstream);
1105
#else
1106
      for (i = _rl_last_c_pos; i < new; i++)
1107
        putc (data[i], rl_outstream);
1108
#endif /* HACK_TERMCAP_MOTION */
1109
    }
1110
  else if (_rl_last_c_pos > new)
1111
    _rl_backspace (_rl_last_c_pos - new);
1112
  _rl_last_c_pos = new;
1113
}
1114
 
1115
/* PWP: move the cursor up or down. */
1116
void
1117
_rl_move_vert (to)
1118
     int to;
1119
{
1120
  register int delta, i;
1121
 
1122
  if (_rl_last_v_pos == to || to > screenheight)
1123
    return;
1124
 
1125
#if defined (__GO32__)
1126
  {
1127
    int row, col;
1128
 
1129
    i = fflush (rl_outstream);  /* make sure the cursor pos is current! */
1130
    ScreenGetCursor (&row, &col);
1131
    ScreenSetCursor ((row + to - _rl_last_v_pos), col);
1132
    delta = i;
1133
  }
1134
#else /* !__GO32__ */
1135
 
1136
  if ((delta = to - _rl_last_v_pos) > 0)
1137
    {
1138
      for (i = 0; i < delta; i++)
1139
        putc ('\n', rl_outstream);
1140
      tputs (term_cr, 1, _rl_output_character_function);
1141
      _rl_last_c_pos = 0;
1142
    }
1143
  else
1144
    {                   /* delta < 0 */
1145
      if (term_up && *term_up)
1146
        for (i = 0; i < -delta; i++)
1147
          tputs (term_up, 1, _rl_output_character_function);
1148
    }
1149
#endif /* !__GO32__ */
1150
  _rl_last_v_pos = to;          /* Now TO is here */
1151
}
1152
 
1153
/* Physically print C on rl_outstream.  This is for functions which know
1154
   how to optimize the display.  Return the number of characters output. */
1155
int
1156
rl_show_char (c)
1157
     int c;
1158
{
1159
  int n = 1;
1160
  if (META_CHAR (c) && (_rl_output_meta_chars == 0))
1161
    {
1162
      fprintf (rl_outstream, "M-");
1163
      n += 2;
1164
      c = UNMETA (c);
1165
    }
1166
 
1167
#if defined (DISPLAY_TABS)
1168
  if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT)
1169
#else
1170
  if (CTRL_CHAR (c) || c == RUBOUT)
1171
#endif /* !DISPLAY_TABS */
1172
    {
1173
      fprintf (rl_outstream, "C-");
1174
      n += 2;
1175
      c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
1176
    }
1177
 
1178
  putc (c, rl_outstream);
1179
  fflush (rl_outstream);
1180
  return n;
1181
}
1182
 
1183
int
1184
rl_character_len (c, pos)
1185
     register int c, pos;
1186
{
1187
  unsigned char uc;
1188
 
1189
  uc = (unsigned char)c;
1190
 
1191
  if (META_CHAR (uc))
1192
    return ((_rl_output_meta_chars == 0) ? 4 : 1);
1193
 
1194
  if (uc == '\t')
1195
    {
1196
#if defined (DISPLAY_TABS)
1197
      return (((pos | 7) + 1) - pos);
1198
#else
1199
      return (2);
1200
#endif /* !DISPLAY_TABS */
1201
    }
1202
 
1203
  if (CTRL_CHAR (c) || c == RUBOUT)
1204
    return (2);
1205
 
1206
  return ((isprint (uc)) ? 1 : 2);
1207
}
1208
 
1209
/* How to print things in the "echo-area".  The prompt is treated as a
1210
   mini-modeline. */
1211
 
1212
#if defined (USE_VARARGS)
1213
int
1214
#if defined (PREFER_STDARG)
1215
rl_message (const char *format, ...)
1216
#else
1217
rl_message (va_alist)
1218
     va_dcl
1219
#endif
1220
{
1221
  va_list args;
1222
#if defined (PREFER_VARARGS)
1223
  char *format;
1224
#endif
1225
 
1226
#if defined (PREFER_STDARG)
1227
  va_start (args, format);
1228
#else
1229
  va_start (args);
1230
  format = va_arg (args, char *);
1231
#endif
1232
 
1233
  vsprintf (msg_buf, format, args);
1234
  va_end (args);
1235
 
1236
  rl_display_prompt = msg_buf;
1237
  (*rl_redisplay_function) ();
1238
  return 0;
1239
}
1240
#else /* !USE_VARARGS */
1241
int
1242
rl_message (format, arg1, arg2)
1243
     char *format;
1244
{
1245
  sprintf (msg_buf, format, arg1, arg2);
1246
  rl_display_prompt = msg_buf;
1247
  (*rl_redisplay_function) ();
1248
  return 0;
1249
}
1250
#endif /* !USE_VARARGS */
1251
 
1252
/* How to clear things from the "echo-area". */
1253
int
1254
rl_clear_message ()
1255
{
1256
  rl_display_prompt = rl_prompt;
1257
  (*rl_redisplay_function) ();
1258
  return 0;
1259
}
1260
 
1261
int
1262
rl_reset_line_state ()
1263
{
1264
  rl_on_new_line ();
1265
 
1266
  rl_display_prompt = rl_prompt ? rl_prompt : "";
1267
  forced_display = 1;
1268
  return 0;
1269
}
1270
 
1271
static char *saved_local_prompt;
1272
static char *saved_local_prefix;
1273
static int saved_last_invisible;
1274
static int saved_visible_length;
1275
 
1276
void
1277
rl_save_prompt ()
1278
{
1279
  saved_local_prompt = local_prompt;
1280
  saved_local_prefix = local_prompt_prefix;
1281
  saved_last_invisible = last_invisible;
1282
  saved_visible_length = visible_length;
1283
 
1284
  local_prompt = local_prompt_prefix = (char *)0;
1285
  last_invisible = visible_length = 0;
1286
}
1287
 
1288
void
1289
rl_restore_prompt ()
1290
{
1291
  if (local_prompt)
1292
    free (local_prompt);
1293
  if (local_prompt_prefix)
1294
    free (local_prompt_prefix);
1295
 
1296
  local_prompt = saved_local_prompt;
1297
  local_prompt_prefix = saved_local_prefix;
1298
  last_invisible = saved_last_invisible;
1299
  visible_length = saved_visible_length;
1300
}
1301
 
1302
char *
1303
_rl_make_prompt_for_search (pchar)
1304
     int pchar;
1305
{
1306
  int len;
1307
  char *pmt;
1308
 
1309
  rl_save_prompt ();
1310
 
1311
  if (saved_local_prompt == 0)
1312
    {
1313
      len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
1314
      pmt = xmalloc (len + 2);
1315
      if (len)
1316
        strcpy (pmt, rl_prompt);
1317
      pmt[len] = pchar;
1318
      pmt[len+1] = '\0';
1319
    }
1320
  else
1321
    {
1322
      len = *saved_local_prompt ? strlen (saved_local_prompt) : 0;
1323
      pmt = xmalloc (len + 2);
1324
      if (len)
1325
        strcpy (pmt, saved_local_prompt);
1326
      pmt[len] = pchar;
1327
      pmt[len+1] = '\0';
1328
      local_prompt = savestring (pmt);
1329
      last_invisible = saved_last_invisible;
1330
      visible_length = saved_visible_length + 1;
1331
    }
1332
  return pmt;
1333
}
1334
 
1335
/* Quick redisplay hack when erasing characters at the end of the line. */
1336
void
1337
_rl_erase_at_end_of_line (l)
1338
     int l;
1339
{
1340
  register int i;
1341
 
1342
  _rl_backspace (l);
1343
  for (i = 0; i < l; i++)
1344
    putc (' ', rl_outstream);
1345
  _rl_backspace (l);
1346
  for (i = 0; i < l; i++)
1347
    visible_line[--_rl_last_c_pos] = '\0';
1348
  rl_display_fixed++;
1349
}
1350
 
1351
/* Clear to the end of the line.  COUNT is the minimum
1352
   number of character spaces to clear, */
1353
void
1354
_rl_clear_to_eol (count)
1355
     int count;
1356
{
1357
#if !defined (__GO32__)
1358
  if (term_clreol)
1359
    tputs (term_clreol, 1, _rl_output_character_function);
1360
  else if (count)
1361
#endif /* !__GO32__ */
1362
    space_to_eol (count);
1363
}
1364
 
1365
/* Clear to the end of the line using spaces.  COUNT is the minimum
1366
   number of character spaces to clear, */
1367
static void
1368
space_to_eol (count)
1369
     int count;
1370
{
1371
  register int i;
1372
 
1373
  for (i = 0; i < count; i++)
1374
   putc (' ', rl_outstream);
1375
 
1376
  _rl_last_c_pos += count;
1377
}
1378
 
1379
void
1380
_rl_clear_screen ()
1381
{
1382
#if defined (__GO32__)
1383
  ScreenClear ();       /* FIXME: only works in text modes */
1384
  ScreenSetCursor (0, 0);  /* term_clrpag is "cl" which homes the cursor */
1385
#else
1386
  if (term_clrpag)
1387
    tputs (term_clrpag, 1, _rl_output_character_function);
1388
  else
1389
#endif /* !__GO32__ */
1390
    crlf ();
1391
}
1392
 
1393
/* Insert COUNT characters from STRING to the output stream. */
1394
static void
1395
insert_some_chars (string, count)
1396
     char *string;
1397
     int count;
1398
{
1399
#if defined (__GO32__)
1400
#ifndef __DJGPP__
1401
  int row, col, width;
1402
  char *row_start;
1403
 
1404
  ScreenGetCursor (&row, &col);
1405
  width = ScreenCols ();
1406
  row_start = ScreenPrimary + (row * width);
1407
 
1408
  memcpy (row_start + col + count, row_start + col, width - col - count);
1409
#endif /* !__DJGPP__ */
1410
  /* Place the text on the screen. */
1411
  _rl_output_some_chars (string, count);
1412
#else /* !_GO32 */
1413
 
1414
  /* If IC is defined, then we do not have to "enter" insert mode. */
1415
  if (term_IC)
1416
    {
1417
      char *buffer;
1418
      buffer = tgoto (term_IC, 0, count);
1419
      tputs (buffer, 1, _rl_output_character_function);
1420
      _rl_output_some_chars (string, count);
1421
    }
1422
  else
1423
    {
1424
      register int i;
1425
 
1426
      /* If we have to turn on insert-mode, then do so. */
1427
      if (term_im && *term_im)
1428
        tputs (term_im, 1, _rl_output_character_function);
1429
 
1430
      /* If there is a special command for inserting characters, then
1431
         use that first to open up the space. */
1432
      if (term_ic && *term_ic)
1433
        {
1434
          for (i = count; i--; )
1435
            tputs (term_ic, 1, _rl_output_character_function);
1436
        }
1437
 
1438
      /* Print the text. */
1439
      _rl_output_some_chars (string, count);
1440
 
1441
      /* If there is a string to turn off insert mode, we had best use
1442
         it now. */
1443
      if (term_ei && *term_ei)
1444
        tputs (term_ei, 1, _rl_output_character_function);
1445
    }
1446
#endif /* !__GO32__ */
1447
}
1448
 
1449
/* Delete COUNT characters from the display line. */
1450
static void
1451
delete_chars (count)
1452
     int count;
1453
{
1454
#if !defined (__DJGPP__)
1455
#if defined (__GO32__)
1456
  int row, col, width;
1457
  char *row_start;
1458
 
1459
  ScreenGetCursor (&row, &col);
1460
  width = ScreenCols ();
1461
  row_start = ScreenPrimary + (row * width);
1462
 
1463
  memcpy (row_start + col, row_start + col + count, width - col - count);
1464
  memset (row_start + width - count, 0, count * 2);
1465
#else /* !_GO32 */
1466
 
1467
  if (count > screenwidth)      /* XXX */
1468
    return;
1469
 
1470
  if (term_DC && *term_DC)
1471
    {
1472
      char *buffer;
1473
      buffer = tgoto (term_DC, count, count);
1474
      tputs (buffer, count, _rl_output_character_function);
1475
    }
1476
  else
1477
    {
1478
      if (term_dc && *term_dc)
1479
        while (count--)
1480
          tputs (term_dc, 1, _rl_output_character_function);
1481
    }
1482
#endif /* !__GO32__ */
1483
#endif /* !__DJGPP__ */
1484
}
1485
 
1486
void
1487
_rl_update_final ()
1488
{
1489
  int full_lines;
1490
 
1491
  full_lines = 0;
1492
  /* If the cursor is the only thing on an otherwise-blank last line,
1493
     compensate so we don't print an extra CRLF. */
1494
  if (_rl_vis_botlin && _rl_last_c_pos == 0 &&
1495
        visible_line[vis_lbreaks[_rl_vis_botlin]] == 0)
1496
    {
1497
      _rl_vis_botlin--;
1498
      full_lines = 1;
1499
    }
1500
  _rl_move_vert (_rl_vis_botlin);
1501
  /* If we've wrapped lines, remove the final xterm line-wrap flag. */
1502
  if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == screenwidth))
1503
    {
1504
      char *last_line;
1505
      last_line = &visible_line[inv_lbreaks[_rl_vis_botlin]];
1506
      _rl_move_cursor_relative (screenwidth - 1, last_line);
1507
      _rl_clear_to_eol (0);
1508
      putc (last_line[screenwidth - 1], rl_outstream);
1509
    }
1510
  _rl_vis_botlin = 0;
1511
  crlf ();
1512
  fflush (rl_outstream);
1513
  rl_display_fixed++;
1514
}
1515
 
1516
/* Move to the start of the current line. */
1517
static void
1518
cr ()
1519
{
1520
  if (term_cr)
1521
    {
1522
#if defined (__MSDOS__)
1523
      putc ('\r', rl_outstream);
1524
#else
1525
      tputs (term_cr, 1, _rl_output_character_function);
1526
#endif /* !__MSDOS__ */
1527
      _rl_last_c_pos = 0;
1528
    }
1529
}
1530
 
1531
/* Redisplay the current line after a SIGWINCH is received. */
1532
void
1533
_rl_redisplay_after_sigwinch ()
1534
{
1535
  char *t, *oldp, *oldl, *oldlprefix;
1536
 
1537
  /* Clear the current line and put the cursor at column 0.  Make sure
1538
     the right thing happens if we have wrapped to a new screen line. */
1539
  if (term_cr)
1540
    {
1541
#if defined (__MSDOS__)
1542
      putc ('\r', rl_outstream);
1543
#else
1544
      tputs (term_cr, 1, _rl_output_character_function);
1545
#endif /* !__MSDOS__ */
1546
      _rl_last_c_pos = 0;
1547
#if defined (__MSDOS__)
1548
      space_to_eol (screenwidth);
1549
      putc ('\r', rl_outstream);
1550
#else
1551
      if (term_clreol)
1552
        tputs (term_clreol, 1, _rl_output_character_function);
1553
      else
1554
        {
1555
          space_to_eol (screenwidth);
1556
          tputs (term_cr, 1, _rl_output_character_function);
1557
        }
1558
#endif
1559
      if (_rl_last_v_pos > 0)
1560
        _rl_move_vert (0);
1561
    }
1562
  else
1563
    crlf ();
1564
 
1565
  /* Redraw only the last line of a multi-line prompt. */
1566
  t = strrchr (rl_display_prompt, '\n');
1567
  if (t)
1568
    {
1569
      oldp = rl_display_prompt;
1570
      oldl = local_prompt;
1571
      oldlprefix = local_prompt_prefix;
1572
      rl_display_prompt = ++t;
1573
      local_prompt = local_prompt_prefix = (char *)NULL;
1574
      rl_forced_update_display ();
1575
      rl_display_prompt = oldp;
1576
      local_prompt = oldl;
1577
      local_prompt_prefix = oldlprefix;
1578
    }
1579
  else
1580
    rl_forced_update_display ();
1581
}
1582
 
1583
void
1584
_rl_clean_up_for_exit ()
1585
{
1586
  if (readline_echoing_p)
1587
    {
1588
      _rl_move_vert (_rl_vis_botlin);
1589
      _rl_vis_botlin = 0;
1590
      fflush (rl_outstream);
1591
      rl_restart_output (1, 0);
1592
    }
1593
}
1594
 
1595
void
1596
_rl_erase_entire_line ()
1597
{
1598
  cr ();
1599
  _rl_clear_to_eol (0);
1600
  cr ();
1601
  fflush (rl_outstream);
1602
}

powered by: WebSVN 2.1.0

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