~ubuntu-branches/ubuntu/oneiric/ecasound2.2/oneiric

« back to all changes in this revision

Viewing changes to readline-4.0/display.c

  • Committer: Bazaar Package Importer
  • Author(s): Junichi Uekawa
  • Date: 2008-03-23 21:42:49 UTC
  • mfrom: (3.1.6 hardy)
  • Revision ID: james.westby@ubuntu.com-20080323214249-evlfv3y1o8q747la
Tags: 2.4.6.1-2
* Bug fix: "FTBFS with GCC 4.3: missing #includes", thanks to Martin
  Michlmayr (Closes: #454890).
- 13_gcc4: updated

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 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 (term_cr)
655
 
                tputs (term_cr, 1, _rl_output_character_function);
656
 
              _rl_output_some_chars (local_prompt, nleft);
657
 
              _rl_last_c_pos = nleft;
658
 
            }
659
 
 
660
 
          /* Where on that line?  And where does that line start
661
 
             in the buffer? */
662
 
          pos = inv_lbreaks[cursor_linenum];
663
 
          /* nleft == number of characters in the line buffer between the
664
 
             start of the line and the cursor position. */
665
 
          nleft = c_pos - pos;
666
 
 
667
 
          /* Since _rl_backspace() doesn't know about invisible characters in the
668
 
             prompt, and there's no good way to tell it, we compensate for
669
 
             those characters here and call _rl_backspace() directly. */
670
 
          if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
671
 
            {
672
 
              _rl_backspace (_rl_last_c_pos - nleft);
673
 
              _rl_last_c_pos = nleft;
674
 
            }
675
 
 
676
 
          if (nleft != _rl_last_c_pos)
677
 
            _rl_move_cursor_relative (nleft, &invisible_line[pos]);
678
 
        }
679
 
    }
680
 
  else                          /* Do horizontal scrolling. */
681
 
    {
682
 
#define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0)
683
 
      int lmargin, ndisp, nleft, phys_c_pos, t;
684
 
 
685
 
      /* Always at top line. */
686
 
      _rl_last_v_pos = 0;
687
 
 
688
 
      /* Compute where in the buffer the displayed line should start.  This
689
 
         will be LMARGIN. */
690
 
 
691
 
      /* The number of characters that will be displayed before the cursor. */
692
 
      ndisp = c_pos - wrap_offset;
693
 
      nleft  = visible_length + wrap_offset;
694
 
      /* Where the new cursor position will be on the screen.  This can be
695
 
         longer than SCREENWIDTH; if it is, lmargin will be adjusted. */
696
 
      phys_c_pos = c_pos - (last_lmargin ? last_lmargin : wrap_offset);
697
 
      t = screenwidth / 3;
698
 
 
699
 
      /* If the number of characters had already exceeded the screenwidth,
700
 
         last_lmargin will be > 0. */
701
 
 
702
 
      /* If the number of characters to be displayed is more than the screen
703
 
         width, compute the starting offset so that the cursor is about
704
 
         two-thirds of the way across the screen. */
705
 
      if (phys_c_pos > screenwidth - 2)
706
 
        {
707
 
          lmargin = c_pos - (2 * t);
708
 
          if (lmargin < 0)
709
 
            lmargin = 0;
710
 
          /* If the left margin would be in the middle of a prompt with
711
 
             invisible characters, don't display the prompt at all. */
712
 
          if (wrap_offset && lmargin > 0 && lmargin < nleft)
713
 
            lmargin = nleft;
714
 
        }
715
 
      else if (ndisp < screenwidth - 2)         /* XXX - was -1 */
716
 
        lmargin = 0;
717
 
      else if (phys_c_pos < 1)
718
 
        {
719
 
          /* If we are moving back towards the beginning of the line and
720
 
             the last margin is no longer correct, compute a new one. */
721
 
          lmargin = ((c_pos - 1) / t) * t;      /* XXX */
722
 
          if (wrap_offset && lmargin > 0 && lmargin < nleft)
723
 
            lmargin = nleft;
724
 
        }
725
 
      else
726
 
        lmargin = last_lmargin;
727
 
 
728
 
      /* If the first character on the screen isn't the first character
729
 
         in the display line, indicate this with a special character. */
730
 
      if (lmargin > 0)
731
 
        line[lmargin] = '<';
732
 
 
733
 
      /* If SCREENWIDTH characters starting at LMARGIN do not encompass
734
 
         the whole line, indicate that with a special character at the
735
 
         right edge of the screen.  If LMARGIN is 0, we need to take the
736
 
         wrap offset into account. */
737
 
      t = lmargin + M_OFFSET (lmargin, wrap_offset) + screenwidth;
738
 
      if (t < out)
739
 
        line[t - 1] = '>';
740
 
 
741
 
      if (!rl_display_fixed || forced_display || lmargin != last_lmargin)
742
 
        {
743
 
          forced_display = 0;
744
 
          update_line (&visible_line[last_lmargin],
745
 
                       &invisible_line[lmargin],
746
 
                       0,
747
 
                       screenwidth + visible_wrap_offset,
748
 
                       screenwidth + (lmargin ? 0 : wrap_offset),
749
 
                       0);
750
 
 
751
 
          /* If the visible new line is shorter than the old, but the number
752
 
             of invisible characters is greater, and we are at the end of
753
 
             the new line, we need to clear to eol. */
754
 
          t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset);
755
 
          if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) &&
756
 
              (_rl_last_c_pos == out) &&
757
 
              t < visible_first_line_len)
758
 
            {
759
 
              nleft = screenwidth - t;
760
 
              _rl_clear_to_eol (nleft);
761
 
            }
762
 
          visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset);
763
 
          if (visible_first_line_len > screenwidth)
764
 
            visible_first_line_len = screenwidth;
765
 
 
766
 
          _rl_move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);
767
 
          last_lmargin = lmargin;
768
 
        }
769
 
    }
770
 
  fflush (rl_outstream);
771
 
 
772
 
  /* Swap visible and non-visible lines. */
773
 
  {
774
 
    char *temp = visible_line;
775
 
    int *itemp = vis_lbreaks;
776
 
    visible_line = invisible_line;
777
 
    invisible_line = temp;
778
 
    vis_lbreaks = inv_lbreaks;
779
 
    inv_lbreaks = itemp;
780
 
    rl_display_fixed = 0;
781
 
    /* If we are displaying on a single line, and last_lmargin is > 0, we
782
 
       are not displaying any invisible characters, so set visible_wrap_offset
783
 
       to 0. */
784
 
    if (_rl_horizontal_scroll_mode && last_lmargin)
785
 
      visible_wrap_offset = 0;
786
 
    else
787
 
      visible_wrap_offset = wrap_offset;
788
 
  }
789
 
}
790
 
 
791
 
/* PWP: update_line() is based on finding the middle difference of each
792
 
   line on the screen; vis:
793
 
 
794
 
                             /old first difference
795
 
        /beginning of line   |        /old last same       /old EOL
796
 
        v                    v        v             v
797
 
old:    eddie> Oh, my little gruntle-buggy is to me, as lurgid as
798
 
new:    eddie> Oh, my little buggy says to me, as lurgid as
799
 
        ^                    ^  ^                          ^
800
 
        \beginning of line   |  \new last same     \new end of line
801
 
                             \new first difference
802
 
 
803
 
   All are character pointers for the sake of speed.  Special cases for
804
 
   no differences, as well as for end of line additions must be handled.
805
 
 
806
 
   Could be made even smarter, but this works well enough */
807
 
static void
808
 
update_line (old, new, current_line, omax, nmax, inv_botlin)
809
 
     register char *old, *new;
810
 
     int current_line, omax, nmax, inv_botlin;
811
 
{
812
 
  register char *ofd, *ols, *oe, *nfd, *nls, *ne;
813
 
  int temp, lendiff, wsatend, od, nd;
814
 
  int current_invis_chars;
815
 
 
816
 
  /* If we're at the right edge of a terminal that supports xn, we're
817
 
     ready to wrap around, so do so.  This fixes problems with knowing
818
 
     the exact cursor position and cut-and-paste with certain terminal
819
 
     emulators.  In this calculation, TEMP is the physical screen
820
 
     position of the cursor. */
821
 
  temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
822
 
  if (temp == screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
823
 
      && _rl_last_v_pos == current_line - 1)
824
 
    {
825
 
      if (new[0])
826
 
        putc (new[0], rl_outstream);
827
 
      else
828
 
        putc (' ', rl_outstream);
829
 
      _rl_last_c_pos = 1;               /* XXX */
830
 
      _rl_last_v_pos++;
831
 
      if (old[0] && new[0])
832
 
        old[0] = new[0];
833
 
    }
834
 
      
835
 
  /* Find first difference. */
836
 
  for (ofd = old, nfd = new;
837
 
       (ofd - old < omax) && *ofd && (*ofd == *nfd);
838
 
       ofd++, nfd++)
839
 
    ;
840
 
 
841
 
  /* Move to the end of the screen line.  ND and OD are used to keep track
842
 
     of the distance between ne and new and oe and old, respectively, to
843
 
     move a subtraction out of each loop. */
844
 
  for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++);
845
 
  for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++);
846
 
 
847
 
  /* If no difference, continue to next line. */
848
 
  if (ofd == oe && nfd == ne)
849
 
    return;
850
 
 
851
 
  wsatend = 1;                  /* flag for trailing whitespace */
852
 
  ols = oe - 1;                 /* find last same */
853
 
  nls = ne - 1;
854
 
  while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
855
 
    {
856
 
      if (*ols != ' ')
857
 
        wsatend = 0;
858
 
      ols--;
859
 
      nls--;
860
 
    }
861
 
 
862
 
  if (wsatend)
863
 
    {
864
 
      ols = oe;
865
 
      nls = ne;
866
 
    }
867
 
  else if (*ols != *nls)
868
 
    {
869
 
      if (*ols)                 /* don't step past the NUL */
870
 
        ols++;
871
 
      if (*nls)
872
 
        nls++;
873
 
    }
874
 
 
875
 
  /* count of invisible characters in the current invisible line. */
876
 
  current_invis_chars = W_OFFSET (current_line, wrap_offset);
877
 
  if (_rl_last_v_pos != current_line)
878
 
    {
879
 
      _rl_move_vert (current_line);
880
 
      if (current_line == 0 && visible_wrap_offset)
881
 
        _rl_last_c_pos += visible_wrap_offset;
882
 
    }
883
 
 
884
 
  /* If this is the first line and there are invisible characters in the
885
 
     prompt string, and the prompt string has not changed, and the current
886
 
     cursor position is before the last invisible character in the prompt,
887
 
     and the index of the character to move to is past the end of the prompt
888
 
     string, then redraw the entire prompt string.  We can only do this
889
 
     reliably if the terminal supports a `cr' capability.
890
 
 
891
 
     This is not an efficiency hack -- there is a problem with redrawing
892
 
     portions of the prompt string if they contain terminal escape
893
 
     sequences (like drawing the `unbold' sequence without a corresponding
894
 
     `bold') that manifests itself on certain terminals. */
895
 
 
896
 
  lendiff = local_prompt ? strlen (local_prompt) : 0;
897
 
  od = ofd - old;       /* index of first difference in visible line */
898
 
  if (current_line == 0 && !_rl_horizontal_scroll_mode &&
899
 
      term_cr && lendiff > visible_length && _rl_last_c_pos > 0 &&
900
 
      od > lendiff && _rl_last_c_pos < last_invisible)
901
 
    {
902
 
      tputs (term_cr, 1, _rl_output_character_function);
903
 
      _rl_output_some_chars (local_prompt, lendiff);
904
 
      _rl_last_c_pos = lendiff;
905
 
    }
906
 
 
907
 
  _rl_move_cursor_relative (od, old);
908
 
 
909
 
  /* if (len (new) > len (old)) */
910
 
  lendiff = (nls - nfd) - (ols - ofd);
911
 
 
912
 
  /* If we are changing the number of invisible characters in a line, and
913
 
     the spot of first difference is before the end of the invisible chars,
914
 
     lendiff needs to be adjusted. */
915
 
  if (current_line == 0 && !_rl_horizontal_scroll_mode &&
916
 
      current_invis_chars != visible_wrap_offset)
917
 
    lendiff += visible_wrap_offset - current_invis_chars;
918
 
 
919
 
  /* Insert (diff (len (old), len (new)) ch. */
920
 
  temp = ne - nfd;
921
 
  if (lendiff > 0)
922
 
    {
923
 
      /* Non-zero if we're increasing the number of lines. */
924
 
      int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
925
 
      /* Sometimes it is cheaper to print the characters rather than
926
 
         use the terminal's capabilities.  If we're growing the number
927
 
         of lines, make sure we actually cause the new line to wrap
928
 
         around on auto-wrapping terminals. */
929
 
      if (terminal_can_insert && ((2 * temp) >= lendiff || term_IC) && (!_rl_term_autowrap || !gl))
930
 
        {
931
 
          /* If lendiff > visible_length and _rl_last_c_pos == 0 and
932
 
             _rl_horizontal_scroll_mode == 1, inserting the characters with
933
 
             term_IC or term_ic will screw up the screen because of the
934
 
             invisible characters.  We need to just draw them. */
935
 
          if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 ||
936
 
                        lendiff <= visible_length || !current_invis_chars))
937
 
            {
938
 
              insert_some_chars (nfd, lendiff);
939
 
              _rl_last_c_pos += lendiff;
940
 
            }
941
 
          else if (*ols == 0)
942
 
            {
943
 
              /* At the end of a line the characters do not have to
944
 
                 be "inserted".  They can just be placed on the screen. */
945
 
              /* However, this screws up the rest of this block, which
946
 
                 assumes you've done the insert because you can. */
947
 
              _rl_output_some_chars (nfd, lendiff);
948
 
              _rl_last_c_pos += lendiff;
949
 
            }
950
 
          else
951
 
            {
952
 
              /* We have horizontal scrolling and we are not inserting at
953
 
                 the end.  We have invisible characters in this line.  This
954
 
                 is a dumb update. */
955
 
              _rl_output_some_chars (nfd, temp);
956
 
              _rl_last_c_pos += temp;
957
 
              return;
958
 
            }
959
 
          /* Copy (new) chars to screen from first diff to last match. */
960
 
          temp = nls - nfd;
961
 
          if ((temp - lendiff) > 0)
962
 
            {
963
 
              _rl_output_some_chars (nfd + lendiff, temp - lendiff);
964
 
              _rl_last_c_pos += temp - lendiff;
965
 
            }
966
 
        }
967
 
      else
968
 
        {
969
 
          /* cannot insert chars, write to EOL */
970
 
          _rl_output_some_chars (nfd, temp);
971
 
          _rl_last_c_pos += temp;
972
 
        }
973
 
    }
974
 
  else                          /* Delete characters from line. */
975
 
    {
976
 
      /* If possible and inexpensive to use terminal deletion, then do so. */
977
 
      if (term_dc && (2 * temp) >= -lendiff)
978
 
        {
979
 
          /* If all we're doing is erasing the invisible characters in the
980
 
             prompt string, don't bother.  It screws up the assumptions
981
 
             about what's on the screen. */
982
 
          if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 &&
983
 
              -lendiff == visible_wrap_offset)
984
 
            lendiff = 0;
985
 
 
986
 
          if (lendiff)
987
 
            delete_chars (-lendiff); /* delete (diff) characters */
988
 
 
989
 
          /* Copy (new) chars to screen from first diff to last match */
990
 
          temp = nls - nfd;
991
 
          if (temp > 0)
992
 
            {
993
 
              _rl_output_some_chars (nfd, temp);
994
 
              _rl_last_c_pos += temp;
995
 
            }
996
 
        }
997
 
      /* Otherwise, print over the existing material. */
998
 
      else
999
 
        {
1000
 
          if (temp > 0)
1001
 
            {
1002
 
              _rl_output_some_chars (nfd, temp);
1003
 
              _rl_last_c_pos += temp;
1004
 
            }
1005
 
          lendiff = (oe - old) - (ne - new);
1006
 
          if (lendiff)
1007
 
            {     
1008
 
              if (_rl_term_autowrap && current_line < inv_botlin)
1009
 
                space_to_eol (lendiff);
1010
 
              else
1011
 
                _rl_clear_to_eol (lendiff);
1012
 
            }
1013
 
        }
1014
 
    }
1015
 
}
1016
 
 
1017
 
/* Tell the update routines that we have moved onto a new (empty) line. */
1018
 
int
1019
 
rl_on_new_line ()
1020
 
{
1021
 
  if (visible_line)
1022
 
    visible_line[0] = '\0';
1023
 
 
1024
 
  _rl_last_c_pos = _rl_last_v_pos = 0;
1025
 
  _rl_vis_botlin = last_lmargin = 0;
1026
 
  if (vis_lbreaks)
1027
 
    vis_lbreaks[0] = vis_lbreaks[1] = 0;
1028
 
  visible_wrap_offset = 0;
1029
 
  return 0;
1030
 
}
1031
 
 
1032
 
/* Actually update the display, period. */
1033
 
int
1034
 
rl_forced_update_display ()
1035
 
{
1036
 
  if (visible_line)
1037
 
    {
1038
 
      register char *temp = visible_line;
1039
 
 
1040
 
      while (*temp)
1041
 
        *temp++ = '\0';
1042
 
    }
1043
 
  rl_on_new_line ();
1044
 
  forced_display++;
1045
 
  (*rl_redisplay_function) ();
1046
 
  return 0;
1047
 
}
1048
 
 
1049
 
/* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices.
1050
 
   DATA is the contents of the screen line of interest; i.e., where
1051
 
   the movement is being done. */
1052
 
void
1053
 
_rl_move_cursor_relative (new, data)
1054
 
     int new;
1055
 
     char *data;
1056
 
{
1057
 
  register int i;
1058
 
 
1059
 
  /* If we don't have to do anything, then return. */
1060
 
  if (_rl_last_c_pos == new) return;
1061
 
 
1062
 
  /* It may be faster to output a CR, and then move forwards instead
1063
 
     of moving backwards. */
1064
 
  /* i == current physical cursor position. */
1065
 
  i = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
1066
 
  if (new == 0 || CR_FASTER (new, _rl_last_c_pos) ||
1067
 
      (_rl_term_autowrap && i == screenwidth))
1068
 
    {
1069
 
#if defined (__MSDOS__)
1070
 
      putc ('\r', rl_outstream);
1071
 
#else
1072
 
      tputs (term_cr, 1, _rl_output_character_function);
1073
 
#endif /* !__MSDOS__ */
1074
 
      _rl_last_c_pos = 0;
1075
 
    }
1076
 
 
1077
 
  if (_rl_last_c_pos < new)
1078
 
    {
1079
 
      /* Move the cursor forward.  We do it by printing the command
1080
 
         to move the cursor forward if there is one, else print that
1081
 
         portion of the output buffer again.  Which is cheaper? */
1082
 
 
1083
 
      /* The above comment is left here for posterity.  It is faster
1084
 
         to print one character (non-control) than to print a control
1085
 
         sequence telling the terminal to move forward one character.
1086
 
         That kind of control is for people who don't know what the
1087
 
         data is underneath the cursor. */
1088
 
#if defined (HACK_TERMCAP_MOTION)
1089
 
      extern char *term_forward_char;
1090
 
 
1091
 
      if (term_forward_char)
1092
 
        for (i = _rl_last_c_pos; i < new; i++)
1093
 
          tputs (term_forward_char, 1, _rl_output_character_function);
1094
 
      else
1095
 
        for (i = _rl_last_c_pos; i < new; i++)
1096
 
          putc (data[i], rl_outstream);
1097
 
#else
1098
 
      for (i = _rl_last_c_pos; i < new; i++)
1099
 
        putc (data[i], rl_outstream);
1100
 
#endif /* HACK_TERMCAP_MOTION */
1101
 
    }
1102
 
  else if (_rl_last_c_pos > new)
1103
 
    _rl_backspace (_rl_last_c_pos - new);
1104
 
  _rl_last_c_pos = new;
1105
 
}
1106
 
 
1107
 
/* PWP: move the cursor up or down. */
1108
 
void
1109
 
_rl_move_vert (to)
1110
 
     int to;
1111
 
{
1112
 
  register int delta, i;
1113
 
 
1114
 
  if (_rl_last_v_pos == to || to > screenheight)
1115
 
    return;
1116
 
 
1117
 
#if defined (__GO32__)
1118
 
  {
1119
 
    int row, col;
1120
 
 
1121
 
    ScreenGetCursor (&row, &col);
1122
 
    ScreenSetCursor ((row + to - _rl_last_v_pos), col);
1123
 
  }
1124
 
#else /* !__GO32__ */
1125
 
 
1126
 
  if ((delta = to - _rl_last_v_pos) > 0)
1127
 
    {
1128
 
      for (i = 0; i < delta; i++)
1129
 
        putc ('\n', rl_outstream);
1130
 
      tputs (term_cr, 1, _rl_output_character_function);
1131
 
      _rl_last_c_pos = 0;
1132
 
    }
1133
 
  else
1134
 
    {                   /* delta < 0 */
1135
 
      if (term_up && *term_up)
1136
 
        for (i = 0; i < -delta; i++)
1137
 
          tputs (term_up, 1, _rl_output_character_function);
1138
 
    }
1139
 
#endif /* !__GO32__ */
1140
 
  _rl_last_v_pos = to;          /* Now TO is here */
1141
 
}
1142
 
 
1143
 
/* Physically print C on rl_outstream.  This is for functions which know
1144
 
   how to optimize the display.  Return the number of characters output. */
1145
 
int
1146
 
rl_show_char (c)
1147
 
     int c;
1148
 
{
1149
 
  int n = 1;
1150
 
  if (META_CHAR (c) && (_rl_output_meta_chars == 0))
1151
 
    {
1152
 
      fprintf (rl_outstream, "M-");
1153
 
      n += 2;
1154
 
      c = UNMETA (c);
1155
 
    }
1156
 
 
1157
 
#if defined (DISPLAY_TABS)
1158
 
  if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT)
1159
 
#else
1160
 
  if (CTRL_CHAR (c) || c == RUBOUT)
1161
 
#endif /* !DISPLAY_TABS */
1162
 
    {
1163
 
      fprintf (rl_outstream, "C-");
1164
 
      n += 2;
1165
 
      c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
1166
 
    }
1167
 
 
1168
 
  putc (c, rl_outstream);
1169
 
  fflush (rl_outstream);
1170
 
  return n;
1171
 
}
1172
 
 
1173
 
int
1174
 
rl_character_len (c, pos)
1175
 
     register int c, pos;
1176
 
{
1177
 
  unsigned char uc;
1178
 
 
1179
 
  uc = (unsigned char)c;
1180
 
 
1181
 
  if (META_CHAR (uc))
1182
 
    return ((_rl_output_meta_chars == 0) ? 4 : 1);
1183
 
 
1184
 
  if (uc == '\t')
1185
 
    {
1186
 
#if defined (DISPLAY_TABS)
1187
 
      return (((pos | 7) + 1) - pos);
1188
 
#else
1189
 
      return (2);
1190
 
#endif /* !DISPLAY_TABS */
1191
 
    }
1192
 
 
1193
 
  if (CTRL_CHAR (c) || c == RUBOUT)
1194
 
    return (2);
1195
 
 
1196
 
  return ((isprint (uc)) ? 1 : 2);
1197
 
}
1198
 
 
1199
 
/* How to print things in the "echo-area".  The prompt is treated as a
1200
 
   mini-modeline. */
1201
 
 
1202
 
#if defined (USE_VARARGS)
1203
 
int
1204
 
#if defined (PREFER_STDARG)
1205
 
rl_message (const char *format, ...)
1206
 
#else
1207
 
rl_message (va_alist)
1208
 
     va_dcl
1209
 
#endif
1210
 
{
1211
 
  va_list args;
1212
 
#if defined (PREFER_VARARGS)
1213
 
  char *format;
1214
 
#endif
1215
 
 
1216
 
#if defined (PREFER_STDARG)
1217
 
  va_start (args, format);
1218
 
#else
1219
 
  va_start (args);
1220
 
  format = va_arg (args, char *);
1221
 
#endif
1222
 
 
1223
 
  vsprintf (msg_buf, format, args);
1224
 
  va_end (args);
1225
 
 
1226
 
  rl_display_prompt = msg_buf;
1227
 
  (*rl_redisplay_function) ();
1228
 
  return 0;
1229
 
}
1230
 
#else /* !USE_VARARGS */
1231
 
int
1232
 
rl_message (format, arg1, arg2)
1233
 
     char *format;
1234
 
{
1235
 
  sprintf (msg_buf, format, arg1, arg2);
1236
 
  rl_display_prompt = msg_buf;
1237
 
  (*rl_redisplay_function) ();
1238
 
  return 0;
1239
 
}
1240
 
#endif /* !USE_VARARGS */
1241
 
 
1242
 
/* How to clear things from the "echo-area". */
1243
 
int
1244
 
rl_clear_message ()
1245
 
{
1246
 
  rl_display_prompt = rl_prompt;
1247
 
  (*rl_redisplay_function) ();
1248
 
  return 0;
1249
 
}
1250
 
 
1251
 
int
1252
 
rl_reset_line_state ()
1253
 
{
1254
 
  rl_on_new_line ();
1255
 
 
1256
 
  rl_display_prompt = rl_prompt ? rl_prompt : "";
1257
 
  forced_display = 1;
1258
 
  return 0;
1259
 
}
1260
 
 
1261
 
static char *saved_local_prompt;
1262
 
static char *saved_local_prefix;
1263
 
static int saved_last_invisible;
1264
 
static int saved_visible_length;
1265
 
 
1266
 
void
1267
 
rl_save_prompt ()
1268
 
{
1269
 
  saved_local_prompt = local_prompt;
1270
 
  saved_local_prefix = local_prompt_prefix;
1271
 
  saved_last_invisible = last_invisible;
1272
 
  saved_visible_length = visible_length;
1273
 
 
1274
 
  local_prompt = local_prompt_prefix = (char *)0;
1275
 
  last_invisible = visible_length = 0;
1276
 
}
1277
 
 
1278
 
void
1279
 
rl_restore_prompt ()
1280
 
{
1281
 
  if (local_prompt)
1282
 
    free (local_prompt);
1283
 
  if (local_prompt_prefix)
1284
 
    free (local_prompt_prefix);
1285
 
 
1286
 
  local_prompt = saved_local_prompt;
1287
 
  local_prompt_prefix = saved_local_prefix;
1288
 
  last_invisible = saved_last_invisible;
1289
 
  visible_length = saved_visible_length;
1290
 
}
1291
 
 
1292
 
char *
1293
 
_rl_make_prompt_for_search (pchar)
1294
 
     int pchar;
1295
 
{
1296
 
  int len;
1297
 
  char *pmt;
1298
 
 
1299
 
  rl_save_prompt ();
1300
 
 
1301
 
  if (saved_local_prompt == 0)
1302
 
    {
1303
 
      len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
1304
 
      pmt = xmalloc (len + 2);
1305
 
      if (len)
1306
 
        strcpy (pmt, rl_prompt);
1307
 
      pmt[len] = pchar;
1308
 
      pmt[len+1] = '\0';
1309
 
    }
1310
 
  else
1311
 
    {
1312
 
      len = *saved_local_prompt ? strlen (saved_local_prompt) : 0;
1313
 
      pmt = xmalloc (len + 2);
1314
 
      if (len)
1315
 
        strcpy (pmt, saved_local_prompt);
1316
 
      pmt[len] = pchar;
1317
 
      pmt[len+1] = '\0';
1318
 
      local_prompt = savestring (pmt);
1319
 
      last_invisible = saved_last_invisible;
1320
 
      visible_length = saved_visible_length + 1;
1321
 
    }
1322
 
  return pmt;
1323
 
}
1324
 
 
1325
 
/* Quick redisplay hack when erasing characters at the end of the line. */
1326
 
void
1327
 
_rl_erase_at_end_of_line (l)
1328
 
     int l;
1329
 
{
1330
 
  register int i;
1331
 
 
1332
 
  _rl_backspace (l);
1333
 
  for (i = 0; i < l; i++)
1334
 
    putc (' ', rl_outstream);
1335
 
  _rl_backspace (l);
1336
 
  for (i = 0; i < l; i++)
1337
 
    visible_line[--_rl_last_c_pos] = '\0';
1338
 
  rl_display_fixed++;
1339
 
}
1340
 
 
1341
 
/* Clear to the end of the line.  COUNT is the minimum
1342
 
   number of character spaces to clear, */
1343
 
void
1344
 
_rl_clear_to_eol (count)
1345
 
     int count;
1346
 
{
1347
 
#if !defined (__GO32__)
1348
 
  if (term_clreol)
1349
 
    tputs (term_clreol, 1, _rl_output_character_function);
1350
 
  else if (count)
1351
 
#endif /* !__GO32__ */
1352
 
    space_to_eol (count);
1353
 
}
1354
 
 
1355
 
/* Clear to the end of the line using spaces.  COUNT is the minimum
1356
 
   number of character spaces to clear, */
1357
 
static void
1358
 
space_to_eol (count)
1359
 
     int count;
1360
 
{
1361
 
  register int i;
1362
 
 
1363
 
  for (i = 0; i < count; i++)
1364
 
   putc (' ', rl_outstream);
1365
 
 
1366
 
  _rl_last_c_pos += count;
1367
 
}
1368
 
 
1369
 
void
1370
 
_rl_clear_screen ()
1371
 
{
1372
 
#if !defined (__GO32__)
1373
 
  if (term_clrpag)
1374
 
    tputs (term_clrpag, 1, _rl_output_character_function);
1375
 
  else
1376
 
#endif /* !__GO32__ */
1377
 
    crlf ();
1378
 
}
1379
 
 
1380
 
/* Insert COUNT characters from STRING to the output stream. */
1381
 
static void
1382
 
insert_some_chars (string, count)
1383
 
     char *string;
1384
 
     int count;
1385
 
{
1386
 
#if defined (__GO32__)
1387
 
  int row, col, width;
1388
 
  char *row_start;
1389
 
 
1390
 
  ScreenGetCursor (&row, &col);
1391
 
  width = ScreenCols ();
1392
 
  row_start = ScreenPrimary + (row * width);
1393
 
 
1394
 
  memcpy (row_start + col + count, row_start + col, width - col - count);
1395
 
 
1396
 
  /* Place the text on the screen. */
1397
 
  _rl_output_some_chars (string, count);
1398
 
#else /* !_GO32 */
1399
 
 
1400
 
  /* If IC is defined, then we do not have to "enter" insert mode. */
1401
 
  if (term_IC)
1402
 
    {
1403
 
      char *buffer;
1404
 
      buffer = tgoto (term_IC, 0, count);
1405
 
      tputs (buffer, 1, _rl_output_character_function);
1406
 
      _rl_output_some_chars (string, count);
1407
 
    }
1408
 
  else
1409
 
    {
1410
 
      register int i;
1411
 
 
1412
 
      /* If we have to turn on insert-mode, then do so. */
1413
 
      if (term_im && *term_im)
1414
 
        tputs (term_im, 1, _rl_output_character_function);
1415
 
 
1416
 
      /* If there is a special command for inserting characters, then
1417
 
         use that first to open up the space. */
1418
 
      if (term_ic && *term_ic)
1419
 
        {
1420
 
          for (i = count; i--; )
1421
 
            tputs (term_ic, 1, _rl_output_character_function);
1422
 
        }
1423
 
 
1424
 
      /* Print the text. */
1425
 
      _rl_output_some_chars (string, count);
1426
 
 
1427
 
      /* If there is a string to turn off insert mode, we had best use
1428
 
         it now. */
1429
 
      if (term_ei && *term_ei)
1430
 
        tputs (term_ei, 1, _rl_output_character_function);
1431
 
    }
1432
 
#endif /* !__GO32__ */
1433
 
}
1434
 
 
1435
 
/* Delete COUNT characters from the display line. */
1436
 
static void
1437
 
delete_chars (count)
1438
 
     int count;
1439
 
{
1440
 
#if defined (__GO32__)
1441
 
  int row, col, width;
1442
 
  char *row_start;
1443
 
 
1444
 
  ScreenGetCursor (&row, &col);
1445
 
  width = ScreenCols ();
1446
 
  row_start = ScreenPrimary + (row * width);
1447
 
 
1448
 
  memcpy (row_start + col, row_start + col + count, width - col - count);
1449
 
  memset (row_start + width - count, 0, count * 2);
1450
 
#else /* !_GO32 */
1451
 
 
1452
 
  if (count > screenwidth)      /* XXX */
1453
 
    return;
1454
 
 
1455
 
  if (term_DC && *term_DC)
1456
 
    {
1457
 
      char *buffer;
1458
 
      buffer = tgoto (term_DC, count, count);
1459
 
      tputs (buffer, count, _rl_output_character_function);
1460
 
    }
1461
 
  else
1462
 
    {
1463
 
      if (term_dc && *term_dc)
1464
 
        while (count--)
1465
 
          tputs (term_dc, 1, _rl_output_character_function);
1466
 
    }
1467
 
#endif /* !__GO32__ */
1468
 
}
1469
 
 
1470
 
void
1471
 
_rl_update_final ()
1472
 
{
1473
 
  int full_lines;
1474
 
 
1475
 
  full_lines = 0;
1476
 
  /* If the cursor is the only thing on an otherwise-blank last line,
1477
 
     compensate so we don't print an extra CRLF. */
1478
 
  if (_rl_vis_botlin && _rl_last_c_pos == 0 &&
1479
 
        visible_line[vis_lbreaks[_rl_vis_botlin]] == 0)
1480
 
    {
1481
 
      _rl_vis_botlin--;
1482
 
      full_lines = 1;
1483
 
    }
1484
 
  _rl_move_vert (_rl_vis_botlin);
1485
 
  /* If we've wrapped lines, remove the final xterm line-wrap flag. */
1486
 
  if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == screenwidth))
1487
 
    {
1488
 
      char *last_line;
1489
 
      last_line = &visible_line[inv_lbreaks[_rl_vis_botlin]];
1490
 
      _rl_move_cursor_relative (screenwidth - 1, last_line);
1491
 
      _rl_clear_to_eol (0);
1492
 
      putc (last_line[screenwidth - 1], rl_outstream);
1493
 
    }
1494
 
  _rl_vis_botlin = 0;
1495
 
  crlf ();
1496
 
  fflush (rl_outstream);
1497
 
  rl_display_fixed++;
1498
 
}
1499
 
 
1500
 
/* Move to the start of the current line. */
1501
 
static void
1502
 
cr ()
1503
 
{
1504
 
  if (term_cr)
1505
 
    {
1506
 
      tputs (term_cr, 1, _rl_output_character_function);
1507
 
      _rl_last_c_pos = 0;
1508
 
    }
1509
 
}
1510
 
 
1511
 
/* Redisplay the current line after a SIGWINCH is received. */
1512
 
void
1513
 
_rl_redisplay_after_sigwinch ()
1514
 
{
1515
 
  char *t, *oldp, *oldl, *oldlprefix;
1516
 
 
1517
 
  /* Clear the current line and put the cursor at column 0.  Make sure
1518
 
     the right thing happens if we have wrapped to a new screen line. */
1519
 
  if (term_cr)
1520
 
    {
1521
 
      tputs (term_cr, 1, _rl_output_character_function);
1522
 
      _rl_last_c_pos = 0;
1523
 
      if (term_clreol)
1524
 
        tputs (term_clreol, 1, _rl_output_character_function);
1525
 
      else
1526
 
        {
1527
 
          space_to_eol (screenwidth);
1528
 
          tputs (term_cr, 1, _rl_output_character_function);
1529
 
        }
1530
 
      if (_rl_last_v_pos > 0)
1531
 
        _rl_move_vert (0);
1532
 
    }
1533
 
  else
1534
 
    crlf ();
1535
 
 
1536
 
  /* Redraw only the last line of a multi-line prompt. */
1537
 
  t = strrchr (rl_display_prompt, '\n');
1538
 
  if (t)
1539
 
    {
1540
 
      oldp = rl_display_prompt;
1541
 
      oldl = local_prompt;
1542
 
      oldlprefix = local_prompt_prefix;
1543
 
      rl_display_prompt = ++t;
1544
 
      local_prompt = local_prompt_prefix = (char *)NULL;
1545
 
      rl_forced_update_display ();
1546
 
      rl_display_prompt = oldp;
1547
 
      local_prompt = oldl;
1548
 
      local_prompt_prefix = oldlprefix;
1549
 
    }
1550
 
  else
1551
 
    rl_forced_update_display ();
1552
 
}
1553
 
 
1554
 
void
1555
 
_rl_clean_up_for_exit ()
1556
 
{
1557
 
  if (readline_echoing_p)
1558
 
    {
1559
 
      _rl_move_vert (_rl_vis_botlin);
1560
 
      _rl_vis_botlin = 0;
1561
 
      fflush (rl_outstream);
1562
 
      rl_restart_output (1, 0);
1563
 
    }
1564
 
}
1565
 
 
1566
 
void
1567
 
_rl_erase_entire_line ()
1568
 
{
1569
 
  cr ();
1570
 
  _rl_clear_to_eol (0);
1571
 
  cr ();
1572
 
  fflush (rl_outstream);
1573
 
}