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

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [readline/] [terminal.c] - Blame information for rev 1780

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

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

powered by: WebSVN 2.1.0

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