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

« back to all changes in this revision

Viewing changes to readline-4.0/terminal.c

  • Committer: Bazaar Package Importer
  • Author(s): Junichi Uekawa
  • Date: 2008-09-26 09:58:52 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20080926095852-k3v9ewhmxpaltusw
Tags: 2.5.2-3
yodl 2.13.1 removed --unique-output option. Remove --unique-output
accordingly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* terminal.c -- controlling the terminal with termcap. */
 
2
 
 
3
/* Copyright (C) 1996 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
#include "posixstat.h"
 
30
#include <fcntl.h>
 
31
#if defined (HAVE_SYS_FILE_H)
 
32
#  include <sys/file.h>
 
33
#endif /* HAVE_SYS_FILE_H */
 
34
 
 
35
#if defined (HAVE_UNISTD_H)
 
36
#  include <unistd.h>
 
37
#endif /* HAVE_UNISTD_H */
 
38
 
 
39
#if defined (HAVE_STDLIB_H)
 
40
#  include <stdlib.h>
 
41
#else
 
42
#  include "ansi_stdlib.h"
 
43
#endif /* HAVE_STDLIB_H */
 
44
 
 
45
#if defined (HAVE_LOCALE_H)
 
46
#  include <locale.h>
 
47
#endif
 
48
 
 
49
#include <signal.h>
 
50
#include <stdio.h>
 
51
#include <setjmp.h>
 
52
 
 
53
/* System-specific feature definitions and include files. */
 
54
#include "rldefs.h"
 
55
 
 
56
#if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ)
 
57
#  include <sys/ioctl.h>
 
58
#endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */
 
59
 
 
60
#include "rltty.h"
 
61
#include "tcap.h"
 
62
 
 
63
/* Some standard library routines. */
 
64
#include "readline.h"
 
65
#include "history.h"
 
66
 
 
67
/* Variables and functions imported from readline.c */
 
68
extern FILE *_rl_in_stream, *_rl_out_stream;
 
69
extern int readline_echoing_p;
 
70
extern int _rl_bell_preference;
 
71
extern Keymap _rl_keymap;
 
72
 
 
73
/* Functions imported from bind.c */
 
74
extern void _rl_bind_if_unbound ();
 
75
 
 
76
/* Functions imported from shell.c */
 
77
extern void set_lines_and_columns ();
 
78
extern char *get_env_value ();
 
79
 
 
80
/* **************************************************************** */
 
81
/*                                                                  */
 
82
/*                      Terminal and Termcap                        */
 
83
/*                                                                  */
 
84
/* **************************************************************** */
 
85
 
 
86
static char *term_buffer = (char *)NULL;
 
87
static char *term_string_buffer = (char *)NULL;
 
88
 
 
89
static int tcap_initialized;
 
90
 
 
91
/* Non-zero means this terminal can't really do anything. */
 
92
static int dumb_term;
 
93
 
 
94
#if !defined (__linux__)
 
95
#  if defined (__EMX__) || defined (NEED_EXTERN_PC)
 
96
extern 
 
97
#  endif /* __EMX__ || NEED_EXTERN_PC */
 
98
char PC, *BC, *UP;
 
99
#endif /* __linux__ */
 
100
 
 
101
/* Some strings to control terminal actions.  These are output by tputs (). */
 
102
char *term_goto, *term_clreol, *term_cr, *term_clrpag, *term_backspace;
 
103
char *term_pc;
 
104
 
 
105
/* Non-zero if we determine that the terminal can do character insertion. */
 
106
int terminal_can_insert = 0;
 
107
 
 
108
/* How to insert characters. */
 
109
char *term_im, *term_ei, *term_ic, *term_ip, *term_IC;
 
110
 
 
111
/* How to delete characters. */
 
112
char *term_dc, *term_DC;
 
113
 
 
114
#if defined (HACK_TERMCAP_MOTION)
 
115
char *term_forward_char;
 
116
#endif  /* HACK_TERMCAP_MOTION */
 
117
 
 
118
/* How to go up a line. */
 
119
char *term_up;
 
120
 
 
121
/* A visible bell, if the terminal can be made to flash the screen. */
 
122
static char *visible_bell;
 
123
 
 
124
/* Non-zero means the terminal can auto-wrap lines. */
 
125
int _rl_term_autowrap;
 
126
 
 
127
/* Non-zero means that this terminal has a meta key. */
 
128
static int term_has_meta;
 
129
 
 
130
/* The sequences to write to turn on and off the meta key, if this
 
131
   terminal    has one. */
 
132
static char *term_mm, *term_mo;
 
133
 
 
134
/* The key sequences output by the arrow keys, if this terminal has any. */
 
135
static char *term_ku, *term_kd, *term_kr, *term_kl;
 
136
 
 
137
/* How to initialize and reset the arrow keys, if this terminal has any. */
 
138
static char *term_ks, *term_ke;
 
139
 
 
140
/* The key sequences sent by the Home and End keys, if any. */
 
141
static char *term_kh, *term_kH;
 
142
 
 
143
/* Variables that hold the screen dimensions, used by the display code. */
 
144
int screenwidth, screenheight, screenchars;
 
145
 
 
146
/* Non-zero means the user wants to enable the keypad. */
 
147
int _rl_enable_keypad;
 
148
 
 
149
/* Non-zero means the user wants to enable a meta key. */
 
150
int _rl_enable_meta = 1;
 
151
 
 
152
/* Get readline's idea of the screen size.  TTY is a file descriptor open
 
153
   to the terminal.  If IGNORE_ENV is true, we do not pay attention to the
 
154
   values of $LINES and $COLUMNS.  The tests for TERM_STRING_BUFFER being
 
155
   non-null serve to check whether or not we have initialized termcap. */
 
156
void
 
157
_rl_get_screen_size (tty, ignore_env)
 
158
     int tty, ignore_env;
 
159
{
 
160
  char *ss;
 
161
#if defined (TIOCGWINSZ)
 
162
  struct winsize window_size;
 
163
#endif /* TIOCGWINSZ */
 
164
#if defined (__EMX__)
 
165
  int sz[2];
 
166
#endif
 
167
 
 
168
#if defined (TIOCGWINSZ)
 
169
  if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
 
170
    {
 
171
      screenwidth = (int) window_size.ws_col;
 
172
      screenheight = (int) window_size.ws_row;
 
173
    }
 
174
#endif /* TIOCGWINSZ */
 
175
 
 
176
#if defined (__EMX__)
 
177
  _scrsize (sz);
 
178
  screenwidth = sz[0];
 
179
  screenheight = sz[1];
 
180
#endif
 
181
 
 
182
  /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
 
183
     is unset. */
 
184
  if (screenwidth <= 0)
 
185
    {
 
186
      if (ignore_env == 0 && (ss = get_env_value ("COLUMNS")))
 
187
        screenwidth = atoi (ss);
 
188
 
 
189
      if (screenwidth <= 0 && term_string_buffer)
 
190
        screenwidth = tgetnum ("co");
 
191
    }
 
192
 
 
193
  /* Environment variable LINES overrides setting of "li" if IGNORE_ENV
 
194
     is unset. */
 
195
  if (screenheight <= 0)
 
196
    {
 
197
      if (ignore_env == 0 && (ss = get_env_value ("LINES")))
 
198
        screenheight = atoi (ss);
 
199
 
 
200
      if (screenheight <= 0 && term_string_buffer)
 
201
        screenheight = tgetnum ("li");
 
202
    }
 
203
 
 
204
  /* If all else fails, default to 80x24 terminal. */
 
205
  if (screenwidth <= 1)
 
206
    screenwidth = 80;
 
207
 
 
208
  if (screenheight <= 0)
 
209
    screenheight = 24;
 
210
 
 
211
  /* If we're being compiled as part of bash, set the environment
 
212
     variables $LINES and $COLUMNS to new values.  Otherwise, just
 
213
     do a pair of putenv () or setenv () calls. */
 
214
  set_lines_and_columns (screenheight, screenwidth);
 
215
 
 
216
  if (!_rl_term_autowrap)
 
217
    screenwidth--;
 
218
 
 
219
  screenchars = screenwidth * screenheight;
 
220
}
 
221
 
 
222
void
 
223
_rl_set_screen_size (rows, cols)
 
224
     int rows, cols;
 
225
{
 
226
  screenheight = rows;
 
227
  screenwidth = cols;
 
228
 
 
229
  if (_rl_term_autowrap == 0)
 
230
    screenwidth--;
 
231
 
 
232
  screenchars = screenwidth * screenheight;
 
233
}
 
234
 
 
235
void
 
236
rl_resize_terminal ()
 
237
{
 
238
  if (readline_echoing_p)
 
239
    {
 
240
      _rl_get_screen_size (fileno (rl_instream), 1);
 
241
      _rl_redisplay_after_sigwinch ();
 
242
    }
 
243
}
 
244
 
 
245
struct _tc_string {
 
246
     char *tc_var;
 
247
     char **tc_value;
 
248
};
 
249
 
 
250
/* This should be kept sorted, just in case we decide to change the
 
251
   search algorithm to something smarter. */
 
252
static struct _tc_string tc_strings[] =
 
253
{
 
254
  "DC", &term_DC,
 
255
  "IC", &term_IC,
 
256
  "ce", &term_clreol,
 
257
  "cl", &term_clrpag,
 
258
  "cr", &term_cr,
 
259
  "dc", &term_dc,
 
260
  "ei", &term_ei,
 
261
  "ic", &term_ic,
 
262
  "im", &term_im,
 
263
  "kd", &term_kd,
 
264
  "kh", &term_kh,       /* home */
 
265
  "kH", &term_kH,       /* end */
 
266
  "kl", &term_kl,
 
267
  "kr", &term_kr,
 
268
  "ku", &term_ku,
 
269
  "ks", &term_ks,
 
270
  "ke", &term_ke,
 
271
  "le", &term_backspace,
 
272
  "mm", &term_mm,
 
273
  "mo", &term_mo,
 
274
#if defined (HACK_TERMCAP_MOTION)
 
275
  "nd", &term_forward_char,
 
276
#endif
 
277
  "pc", &term_pc,
 
278
  "up", &term_up,
 
279
  "vb", &visible_bell,
 
280
};
 
281
 
 
282
#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string))
 
283
 
 
284
/* Read the desired terminal capability strings into BP.  The capabilities
 
285
   are described in the TC_STRINGS table. */
 
286
static void
 
287
get_term_capabilities (bp)
 
288
     char **bp;
 
289
{
 
290
  register int i;
 
291
 
 
292
  for (i = 0; i < NUM_TC_STRINGS; i++)
 
293
    *(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
 
294
  tcap_initialized = 1;
 
295
}
 
296
 
 
297
int
 
298
_rl_init_terminal_io (terminal_name)
 
299
     char *terminal_name;
 
300
{
 
301
#if defined (__GO32__)
 
302
  screenwidth = ScreenCols ();
 
303
  screenheight = ScreenRows ();
 
304
  screenchars = screenwidth * screenheight;
 
305
  term_cr = "\r";
 
306
  term_im = term_ei = term_ic = term_IC = (char *)NULL;
 
307
  term_up = term_dc = term_DC = visible_bell = (char *)NULL;
 
308
 
 
309
  /* Does the __GO32__ have a meta key?  I don't know. */
 
310
  term_has_meta = 0;
 
311
  term_mm = term_mo = (char *)NULL;
 
312
 
 
313
  /* It probably has arrow keys, but I don't know what they are. */
 
314
  term_ku = term_kd = term_kr = term_kl = (char *)NULL;
 
315
 
 
316
#if defined (HACK_TERMCAP_MOTION)
 
317
  term_forward_char = (char *)NULL;
 
318
#endif /* HACK_TERMCAP_MOTION */
 
319
  terminal_can_insert = _rl_term_autowrap = 0;
 
320
  return;
 
321
#else /* !__GO32__ */
 
322
 
 
323
  char *term, *buffer;
 
324
  int tty;
 
325
  Keymap xkeymap;
 
326
 
 
327
  term = terminal_name ? terminal_name : get_env_value ("TERM");
 
328
 
 
329
  if (term_string_buffer == 0)
 
330
    term_string_buffer = xmalloc (2032);
 
331
 
 
332
  if (term_buffer == 0)
 
333
    term_buffer = xmalloc (4080);
 
334
 
 
335
  buffer = term_string_buffer;
 
336
 
 
337
  term_clrpag = term_cr = term_clreol = (char *)NULL;
 
338
 
 
339
  if (term == 0)
 
340
    term = "dumb";
 
341
 
 
342
  if (tgetent (term_buffer, term) <= 0)
 
343
    {
 
344
      dumb_term = 1;
 
345
      screenwidth = 79;
 
346
      screenheight = 24;
 
347
      screenchars = 79 * 24;
 
348
      term_cr = "\r";
 
349
      term_im = term_ei = term_ic = term_IC = (char *)NULL;
 
350
      term_up = term_dc = term_DC = visible_bell = (char *)NULL;
 
351
      term_ku = term_kd = term_kl = term_kr = (char *)NULL;
 
352
#if defined (HACK_TERMCAP_MOTION)
 
353
      term_forward_char = (char *)NULL;
 
354
#endif
 
355
      terminal_can_insert = 0;
 
356
      return 0;
 
357
    }
 
358
 
 
359
  get_term_capabilities (&buffer);
 
360
 
 
361
  /* Set up the variables that the termcap library expects the application
 
362
     to provide. */
 
363
  PC = term_pc ? *term_pc : 0;
 
364
  BC = term_backspace;
 
365
  UP = term_up;
 
366
 
 
367
  if (!term_cr)
 
368
    term_cr = "\r";
 
369
 
 
370
  tty = rl_instream ? fileno (rl_instream) : 0;
 
371
 
 
372
  screenwidth = screenheight = 0;
 
373
 
 
374
  _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn");
 
375
 
 
376
  _rl_get_screen_size (tty, 0);
 
377
 
 
378
  /* "An application program can assume that the terminal can do
 
379
      character insertion if *any one of* the capabilities `IC',
 
380
      `im', `ic' or `ip' is provided."  But we can't do anything if
 
381
      only `ip' is provided, so... */
 
382
  terminal_can_insert = (term_IC || term_im || term_ic);
 
383
 
 
384
  /* Check to see if this terminal has a meta key and clear the capability
 
385
     variables if there is none. */
 
386
  term_has_meta = (tgetflag ("km") || tgetflag ("MT"));
 
387
  if (!term_has_meta)
 
388
    term_mm = term_mo = (char *)NULL;
 
389
 
 
390
  /* Attempt to find and bind the arrow keys.  Do not override already
 
391
     bound keys in an overzealous attempt, however. */
 
392
  xkeymap = _rl_keymap;
 
393
 
 
394
  _rl_keymap = emacs_standard_keymap;
 
395
  _rl_bind_if_unbound (term_ku, rl_get_previous_history);
 
396
  _rl_bind_if_unbound (term_kd, rl_get_next_history);
 
397
  _rl_bind_if_unbound (term_kr, rl_forward);
 
398
  _rl_bind_if_unbound (term_kl, rl_backward);
 
399
 
 
400
  _rl_bind_if_unbound (term_kh, rl_beg_of_line);        /* Home */
 
401
  _rl_bind_if_unbound (term_kH, rl_end_of_line);        /* End */
 
402
 
 
403
#if defined (VI_MODE)
 
404
  _rl_keymap = vi_movement_keymap;
 
405
  _rl_bind_if_unbound (term_ku, rl_get_previous_history);
 
406
  _rl_bind_if_unbound (term_kd, rl_get_next_history);
 
407
  _rl_bind_if_unbound (term_kr, rl_forward);
 
408
  _rl_bind_if_unbound (term_kl, rl_backward);
 
409
 
 
410
  _rl_bind_if_unbound (term_kh, rl_beg_of_line);        /* Home */
 
411
  _rl_bind_if_unbound (term_kH, rl_end_of_line);        /* End */
 
412
#endif /* VI_MODE */
 
413
 
 
414
  _rl_keymap = xkeymap;
 
415
 
 
416
#endif /* !__GO32__ */
 
417
  return 0;
 
418
}
 
419
 
 
420
char *
 
421
rl_get_termcap (cap)
 
422
     char *cap;
 
423
{
 
424
  register int i;
 
425
 
 
426
  if (tcap_initialized == 0)
 
427
    return ((char *)NULL);
 
428
  for (i = 0; i < NUM_TC_STRINGS; i++)
 
429
    {
 
430
      if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
 
431
        return *(tc_strings[i].tc_value);
 
432
    }
 
433
  return ((char *)NULL);
 
434
}
 
435
 
 
436
/* Re-initialize the terminal considering that the TERM/TERMCAP variable
 
437
   has changed. */
 
438
int
 
439
rl_reset_terminal (terminal_name)
 
440
     char *terminal_name;
 
441
{
 
442
  _rl_init_terminal_io (terminal_name);
 
443
  return 0;
 
444
}
 
445
 
 
446
/* A function for the use of tputs () */
 
447
#ifdef _MINIX
 
448
void
 
449
_rl_output_character_function (c)
 
450
     int c;
 
451
{
 
452
  putc (c, _rl_out_stream);
 
453
}
 
454
#else /* !_MINIX */
 
455
int
 
456
_rl_output_character_function (c)
 
457
     int c;
 
458
{
 
459
  return putc (c, _rl_out_stream);
 
460
}
 
461
#endif /* !_MINIX */
 
462
/* Write COUNT characters from STRING to the output stream. */
 
463
void
 
464
_rl_output_some_chars (string, count)
 
465
     char *string;
 
466
     int count;
 
467
{
 
468
  fwrite (string, 1, count, _rl_out_stream);
 
469
}
 
470
 
 
471
/* Move the cursor back. */
 
472
int
 
473
_rl_backspace (count)
 
474
     int count;
 
475
{
 
476
  register int i;
 
477
 
 
478
#if !defined (__GO32__)
 
479
  if (term_backspace)
 
480
    for (i = 0; i < count; i++)
 
481
      tputs (term_backspace, 1, _rl_output_character_function);
 
482
  else
 
483
#endif /* !__GO32__ */
 
484
    for (i = 0; i < count; i++)
 
485
      putc ('\b', _rl_out_stream);
 
486
  return 0;
 
487
}
 
488
 
 
489
/* Move to the start of the next line. */
 
490
int
 
491
crlf ()
 
492
{
 
493
#if defined (NEW_TTY_DRIVER)
 
494
  if (term_cr)
 
495
    tputs (term_cr, 1, _rl_output_character_function);
 
496
#endif /* NEW_TTY_DRIVER */
 
497
  putc ('\n', _rl_out_stream);
 
498
  return 0;
 
499
}
 
500
 
 
501
/* Ring the terminal bell. */
 
502
int
 
503
ding ()
 
504
{
 
505
  if (readline_echoing_p)
 
506
    {
 
507
#if !defined (__GO32__)
 
508
      switch (_rl_bell_preference)
 
509
        {
 
510
        case NO_BELL:
 
511
        default:
 
512
          break;
 
513
        case VISIBLE_BELL:
 
514
          if (visible_bell)
 
515
            {
 
516
              tputs (visible_bell, 1, _rl_output_character_function);
 
517
              break;
 
518
            }
 
519
          /* FALLTHROUGH */
 
520
        case AUDIBLE_BELL:
 
521
          fprintf (stderr, "\007");
 
522
          fflush (stderr);
 
523
          break;
 
524
        }
 
525
#else /* __GO32__ */
 
526
      fprintf (stderr, "\007");
 
527
      fflush (stderr);
 
528
#endif /* __GO32__ */
 
529
      return (0);
 
530
    }
 
531
  return (-1);
 
532
}
 
533
 
 
534
/* **************************************************************** */
 
535
/*                                                                  */
 
536
/*              Controlling the Meta Key and Keypad                 */
 
537
/*                                                                  */
 
538
/* **************************************************************** */
 
539
 
 
540
void
 
541
_rl_enable_meta_key ()
 
542
{
 
543
  if (term_has_meta && term_mm)
 
544
    tputs (term_mm, 1, _rl_output_character_function);
 
545
}
 
546
 
 
547
void
 
548
_rl_control_keypad (on)
 
549
     int on;
 
550
{
 
551
  if (on && term_ks)
 
552
    tputs (term_ks, 1, _rl_output_character_function);
 
553
  else if (!on && term_ke)
 
554
    tputs (term_ke, 1, _rl_output_character_function);
 
555
}