/* terminal control module for terminals described by TERMCAP
- Copyright (C) 1985, 1986, 1987, 1993, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1985, 86, 87, 93, 94, 95 Free Software Foundation, Inc.
This file is part of GNU Emacs.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#include <config.h>
#include <stdio.h>
#include <ctype.h>
-#include <config.h>
#include "termchar.h"
#include "termopts.h"
#include "cm.h"
#undef NULL
#include "lisp.h"
+#include "charset.h"
+#include "coding.h"
#include "frame.h"
#include "disptab.h"
#include "termhooks.h"
#include "keyboard.h"
+#include "dispextern.h"
+#ifdef HAVE_X_WINDOWS
+#include "xterm.h"
+#endif
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
-#define OUTPUT(a) tputs (a, FRAME_HEIGHT (selected_frame) - curY, cmputc)
+#define OUTPUT(a) tputs (a, (int) (FRAME_HEIGHT (selected_frame) - curY), cmputc)
#define OUTPUT1(a) tputs (a, 1, cmputc)
#define OUTPUTL(a, lines) tputs (a, lines, cmputc)
-#define OUTPUT_IF(a) { if (a) tputs (a, FRAME_HEIGHT (selected_frame) - curY, cmputc); }
+#define OUTPUT_IF(a) { if (a) tputs (a, (int) (FRAME_HEIGHT (selected_frame) - curY), cmputc); }
#define OUTPUT1_IF(a) { if (a) tputs (a, 1, cmputc); }
+/* Function to use to ring the bell. */
+Lisp_Object Vring_bell_function;
+
/* Terminal characteristics that higher levels want to look at.
These are all extern'd in termchar.h */
int char_ins_del_ok; /* Terminal can insert and delete chars */
int scroll_region_ok; /* Terminal supports setting the
scroll window */
+int scroll_region_cost; /* Cost of setting a scroll window,
+ measured in characters */
int memory_below_frame; /* Terminal remembers lines
scrolled off bottom */
int fast_clear_end_of_line; /* Terminal has a `ce' string */
-int dont_calculate_costs; /* Nonzero means don't bother computing */
- /* various cost tables; we won't use them. */
-
/* Nonzero means no need to redraw the entire frame on resuming
a suspended Emacs. This is useful on terminals with multiple pages,
where one page is used for Emacs and another for all else. */
/* Hook functions that you can set to snap out the functions in this file.
These are all extern'd in termhooks.h */
-int (*cursor_to_hook) ();
-int (*raw_cursor_to_hook) ();
+void (*cursor_to_hook) P_ ((int, int));
+void (*raw_cursor_to_hook) P_ ((int, int));
-int (*clear_to_end_hook) ();
-int (*clear_frame_hook) ();
-int (*clear_end_of_line_hook) ();
+void (*clear_to_end_hook) P_ ((void));
+void (*clear_frame_hook) P_ ((void));
+void (*clear_end_of_line_hook) P_ ((int));
-int (*ins_del_lines_hook) ();
+void (*ins_del_lines_hook) P_ ((int, int));
-int (*change_line_highlight_hook) ();
-int (*reassert_line_highlight_hook) ();
+void (*change_line_highlight_hook) P_ ((int, int, int));
+void (*reassert_line_highlight_hook) P_ ((int, int));
-int (*insert_glyphs_hook) ();
-int (*write_glyphs_hook) ();
-int (*delete_glyphs_hook) ();
+void (*insert_glyphs_hook) P_ ((GLYPH *, int));
+void (*write_glyphs_hook) P_ ((GLYPH *, int));
+void (*delete_glyphs_hook) P_ ((int));
-int (*ring_bell_hook) ();
+void (*ring_bell_hook) P_ ((void));
-int (*reset_terminal_modes_hook) ();
-int (*set_terminal_modes_hook) ();
-int (*update_begin_hook) ();
-int (*update_end_hook) ();
-int (*set_terminal_window_hook) ();
+void (*reset_terminal_modes_hook) P_ ((void));
+void (*set_terminal_modes_hook) P_ ((void));
+void (*update_begin_hook) P_ ((struct frame *));
+void (*update_end_hook) P_ ((struct frame *));
+void (*set_terminal_window_hook) P_ ((int));
-int (*read_socket_hook) ();
+int (*read_socket_hook) P_ ((int, struct input_event *, int, int));
-int (*frame_up_to_date_hook) ();
+void (*frame_up_to_date_hook) P_ ((struct frame *));
/* Return the current position of the mouse.
This should clear mouse_moved until the next motion
event arrives. */
-void (*mouse_position_hook) ( /* FRAME_PTR *f,
+void (*mouse_position_hook) P_ ((FRAME_PTR *f, int insist,
Lisp_Object *bar_window,
enum scroll_bar_part *part,
Lisp_Object *x,
Lisp_Object *y,
- unsigned long *time */ );
+ unsigned long *time));
/* When reading from a minibuffer in a different frame, Emacs wants
to shift the highlight from the selected frame to the minibuffer's
frame; under X, this means it lies about where the focus is.
This hook tells the window system code to re-decide where to put
the highlight. */
-void (*frame_rehighlight_hook) ( /* FRAME_PTR f */ );
+void (*frame_rehighlight_hook) P_ ((FRAME_PTR f));
/* If we're displaying frames using a window system that can stack
frames on top of each other, this hook allows you to bring a frame
If RAISE is non-zero, F is brought to the front, before all other
windows. If RAISE is zero, F is sent to the back, behind all other
windows. */
-void (*frame_raise_lower_hook) ( /* FRAME_PTR f, int raise */ );
+void (*frame_raise_lower_hook) P_ ((FRAME_PTR f, int raise));
/* Set the vertical scroll bar for WINDOW to have its upper left corner
at (TOP, LEFT), and be LENGTH rows high. Set its handle to
of WHOLE characters, starting at POSITION. If WINDOW doesn't yet
have a scroll bar, create one for it. */
void (*set_vertical_scroll_bar_hook)
- ( /* struct window *window,
- int portion, int whole, int position */ );
+ P_ ((struct window *window,
+ int portion, int whole, int position));
/* The following three hooks are used when we're doing a thorough
away is a real pain - can you say set-window-configuration?
Instead, we just assert at the beginning of redisplay that *all*
scroll bars are to be removed, and then save scroll bars from the
- firey pit when we actually redisplay their window. */
+ fiery pit when we actually redisplay their window. */
/* Arrange for all scroll bars on FRAME to be removed at the next call
to `*judge_scroll_bars_hook'. A scroll bar may be spared if
If non-zero, this hook should be safe to apply to any frame,
whether or not it can support scroll bars, and whether or not it is
currently displaying them. */
-void (*condemn_scroll_bars_hook)( /* FRAME_PTR *frame */ );
+void (*condemn_scroll_bars_hook) P_ ((FRAME_PTR frame));
/* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
Note that it's okay to redeem a scroll bar that is not condemned. */
-void (*redeem_scroll_bar_hook)( /* struct window *window */ );
+void (*redeem_scroll_bar_hook) P_ ((struct window *window));
/* Remove all scroll bars on FRAME that haven't been saved since the
last call to `*condemn_scroll_bars_hook'.
If non-zero, this hook should be safe to apply to any frame,
whether or not it can support scroll bars, and whether or not it is
currently displaying them. */
-void (*judge_scroll_bars_hook)( /* FRAME_PTR *FRAME */ );
+void (*judge_scroll_bars_hook) P_ ((FRAME_PTR FRAME));
/* Strings, numbers and flags taken from the termcap entry. */
-char *TS_ins_line; /* termcap "al" */
+char *TS_end_italic_mode; /* termcap "ae" */
+char *TS_ins_line; /* "al" */
+char *TS_italic_mode; /* "as" */
char *TS_ins_multi_lines; /* "AL" (one parameter, # lines to insert) */
char *TS_bell; /* "bl" */
char *TS_clr_to_bottom; /* "cd" */
char *TS_pad_inserted_char; /* "ip". Just padding, no commands. */
char *TS_end_keypad_mode; /* "ke" */
char *TS_keypad_mode; /* "ks" */
+char *TS_bold_mode; /* "md" */
+char *TS_end_bold_mode; /* "me" */
char *TS_pad_char; /* "pc", char to use as padding */
char *TS_repeat; /* "rp" (2 params, # times to repeat
and character to be repeated) */
char *TS_rev_scroll; /* "sr" */
char *TS_end_termcap_modes; /* "te" */
char *TS_termcap_modes; /* "ti" */
+char *TS_end_underscore_mode; /* "ue" */
+char *TS_underscore_mode; /* "us" */
char *TS_visible_bell; /* "vb" */
char *TS_end_visual_mode; /* "ve" */
char *TS_visual_mode; /* "vi" */
/* internal state */
+/* The largest frame width in any call to calculate_costs. */
+int max_frame_width;
+/* The largest frame height in any call to calculate_costs. */
+int max_frame_height;
+
/* Number of chars of space used for standout marker at beginning of line,
or'd with 0100. Zero if no standout marker at all.
+ The length of these vectors is max_frame_height.
Used IFF TN_standout_width >= 0. */
static int system_uses_terminfo;
char *tparam ();
+
+extern char *tgetstr ();
\f
+
+#ifdef WINDOWSNT
+/* We aren't X windows, but we aren't termcap either. This makes me
+ uncertain as to what value to use for frame.output_method. For
+ this file, we'll define FRAME_TERMCAP_P to be zero so that our
+ output hooks get called instead of the termcap functions. Probably
+ the best long-term solution is to define an output_windows_nt... */
+
+#undef FRAME_TERMCAP_P
+#define FRAME_TERMCAP_P(_f_) 0
+#endif /* WINDOWSNT */
+
+void
ring_bell ()
{
+ if (! NILP (Vring_bell_function))
+ {
+ Lisp_Object function;
+
+ /* Temporarily set the global variable to nil
+ so that if we get an error, it stays nil
+ and we don't call it over and over.
+
+ We don't specbind it, because that would carefully
+ restore the bad value if there's an error
+ and make the loop of errors happen anyway. */
+ function = Vring_bell_function;
+ Vring_bell_function = Qnil;
+
+ call0 (function);
+
+ Vring_bell_function = function;
+ return;
+ }
+
if (! FRAME_TERMCAP_P (selected_frame))
{
(*ring_bell_hook) ();
OUTPUT (TS_visible_bell && visible_bell ? TS_visible_bell : TS_bell);
}
+void
set_terminal_modes ()
{
if (! FRAME_TERMCAP_P (selected_frame))
losecursor ();
}
+void
reset_terminal_modes ()
{
if (! FRAME_TERMCAP_P (selected_frame))
cmputc ('\r');
}
+void
update_begin (f)
FRAME_PTR f;
{
(*update_begin_hook) (f);
}
+void
update_end (f)
FRAME_PTR f;
{
updating_frame = 0;
}
+void
set_terminal_window (size)
int size;
{
set_scroll_region (0, specified_window);
}
+void
set_scroll_region (start, stop)
int start, stop;
{
losecursor ();
}
\f
+void
turn_on_insert ()
{
if (!insert_mode)
insert_mode = 1;
}
+void
turn_off_insert ()
{
if (insert_mode)
These functions are called on all terminals, but do nothing
on terminals whose standout mode does not work that way. */
+void
turn_off_highlight ()
{
if (TN_standout_width < 0)
}
}
+void
turn_on_highlight ()
{
if (TN_standout_width < 0)
empty space inside windows. What this is,
depends on the user option inverse-video. */
+void
background_highlight ()
{
if (TN_standout_width >= 0)
/* Set standout mode to the mode specified for the text to be output. */
-static
+static void
highlight_if_desired ()
{
if (TN_standout_width >= 0)
/* Write a standout marker or end-standout marker at the front of the line
at vertical position vpos. */
+void
write_standout_marker (flag, vpos)
int flag, vpos;
{
Call this when about to modify line at position VPOS
and not change whether it is highlighted. */
+void
reassert_line_highlight (highlight, vpos)
int highlight;
int vpos;
/* Call this when about to modify line at position VPOS
and change whether it is highlighted. */
+void
change_line_highlight (new_highlight, vpos, first_unused_hpos)
int new_highlight, vpos, first_unused_hpos;
{
/* Move to absolute position, specified origin 0 */
+void
cursor_to (row, col)
int row, col;
{
return;
}
+ /* Detect the case where we are called from reset_sys_modes
+ and the costs have never been calculated. Do nothing. */
+ if (chars_wasted == 0)
+ return;
+
col += chars_wasted[row] & 077;
if (curY == row && curX == col)
return;
/* Similar but don't take any account of the wasted characters. */
+void
raw_cursor_to (row, col)
int row, col;
{
/* Erase operations */
/* clear from cursor to end of frame */
+void
clear_to_end ()
{
register int i;
- if (clear_to_end_hook && FRAME_TERMCAP_P (updating_frame))
+ if (clear_to_end_hook && ! FRAME_TERMCAP_P (updating_frame))
{
(*clear_to_end_hook) ();
return;
/* Clear entire frame */
+void
clear_frame ()
{
if (clear_frame_hook
Note that the cursor may be moved. */
+void
clear_end_of_line (first_unused_hpos)
int first_unused_hpos;
{
static GLYPH buf = SPACEGLYPH;
if (FRAME_TERMCAP_P (selected_frame)
+ && chars_wasted != 0
&& TN_standout_width == 0 && curX == 0 && chars_wasted[curY] != 0)
write_glyphs (&buf, 1);
clear_end_of_line_raw (first_unused_hpos);
Note that the cursor may be moved, on terminals lacking a `ce' string. */
+void
clear_end_of_line_raw (first_unused_hpos)
int first_unused_hpos;
{
return;
}
+ /* Detect the case where we are called from reset_sys_modes
+ and the costs have never been calculated. Do nothing. */
+ if (chars_wasted == 0)
+ return;
+
first_unused_hpos += chars_wasted[curY] & 077;
if (curX >= first_unused_hpos)
return;
}
}
\f
+/* Encode SRC_LEN glyphs starting at SRC to terminal output codes and
+ store them at DST. Do not write more than DST_LEN bytes. That may
+ require stopping before all SRC_LEN input glyphs have been
+ converted.
+
+ We store the number of glyphs actually converted in *CONSUMED. The
+ return value is the number of bytes store in DST. */
+
+int
+encode_terminal_code (src, dst, src_len, dst_len, consumed)
+ GLYPH *src;
+ int src_len;
+ unsigned char *dst;
+ int dst_len, *consumed;
+{
+ GLYPH *src_start = src, *src_end = src + src_len;
+ unsigned char *dst_start = dst, *dst_end = dst + dst_len;
+ register GLYPH g;
+ unsigned int c;
+ unsigned char workbuf[4], *buf;
+ int len;
+ register int tlen = GLYPH_TABLE_LENGTH;
+ register Lisp_Object *tbase = GLYPH_TABLE_BASE;
+ struct coding_system *coding;
+ coding = (CODING_REQUIRE_ENCODING (&terminal_coding)
+ ? &terminal_coding
+ : &safe_terminal_coding);
+
+ while (src < src_end)
+ {
+ g = *src;
+ /* We must skip glyphs to be padded for a wide character. */
+ if (! (g & GLYPH_MASK_PADDING))
+ {
+ if ((c = GLYPH_CHAR (selected_frame, g)) > MAX_CHAR)
+ {
+ c = ' ';
+ g = MAKE_GLYPH (selected_frame, c,
+ GLYPH_FACE (selected_frame, g));
+ }
+ if (COMPOSITE_CHAR_P (c))
+ {
+ /* If C is a composite character, we can display
+ only the first component. */
+ g = cmpchar_table[COMPOSITE_CHAR_ID (c)]->glyph[0],
+ c = GLYPH_CHAR (selected_frame, g);
+ }
+ if (c < tlen)
+ {
+ /* G has an entry in Vglyph_table,
+ so process any alias before testing for simpleness. */
+ GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
+ c = GLYPH_CHAR (selected_frame, g);
+ }
+ if (GLYPH_SIMPLE_P (tbase, tlen, g))
+ /* We set the multi-byte form of C at BUF. */
+ len = CHAR_STRING (c, workbuf, buf);
+ else
+ {
+ /* We have a string in Vglyph_table. */
+ len = GLYPH_LENGTH (tbase, g);
+ buf = GLYPH_STRING (tbase, g);
+ }
+
+ encode_coding (coding, buf, dst, len, dst_end - dst);
+ if (coding->consumed < len)
+ /* We get a carryover because the remaining output
+ buffer is too short. We must break the loop here
+ without increasing SRC so that the next call of
+ this function start from the same glyph. */
+ break;
+ dst += coding->produced;
+ }
+ src++;
+ }
+ *consumed = src - src_start;
+ return (dst - dst_start);
+}
+
+
+void
write_glyphs (string, len)
register GLYPH *string;
register int len;
register GLYPH g;
register int tlen = GLYPH_TABLE_LENGTH;
register Lisp_Object *tbase = GLYPH_TABLE_BASE;
+ int produced, consumed;
if (write_glyphs_hook
&& ! FRAME_TERMCAP_P ((updating_frame ? updating_frame : selected_frame)))
&& (curX + len - (chars_wasted[curY] & 077)
== FRAME_WIDTH (selected_frame)))
len --;
+ if (len <= 0)
+ return;
cmplus (len);
- while (--len >= 0)
+ /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
+ the tail. */
+ terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;
+ while (len > 0)
{
- g = *string++;
- /* Check quickly for G beyond length of table.
- That implies it isn't an alias and is simple. */
- if (g >= tlen)
+ /* We use shared conversion buffer of the current size (1024
+ bytes at least). Usually it is sufficient, but if not, we
+ just repeat the loop. */
+ produced = encode_terminal_code (string, conversion_buffer,
+ len, conversion_buffer_size, &consumed);
+ if (produced > 0)
{
- simple:
- putc (g & 0xff, stdout);
+ fwrite (conversion_buffer, 1, produced, stdout);
if (ferror (stdout))
clearerr (stdout);
if (termscript)
- putc (g & 0xff, termscript);
+ fwrite (conversion_buffer, 1, produced, termscript);
}
- else
+ len -= consumed;
+ string += consumed;
+ }
+ /* We may have to output some codes to terminate the writing. */
+ if (CODING_REQUIRE_FLUSHING (&terminal_coding))
+ {
+ terminal_coding.mode |= CODING_MODE_LAST_BLOCK;
+ encode_coding (&terminal_coding, (char *)0, conversion_buffer,
+ 0, conversion_buffer_size);
+ if (terminal_coding.produced > 0)
{
- /* G has an entry in Vglyph_table,
- so process any alias and then test for simpleness. */
- while (GLYPH_ALIAS_P (tbase, tlen, g))
- g = GLYPH_ALIAS (tbase, g);
- if (GLYPH_SIMPLE_P (tbase, tlen, g))
- goto simple;
- else
- {
- /* Here if G (or its definition as an alias) is not simple. */
- fwrite (GLYPH_STRING (tbase, g), 1, GLYPH_LENGTH (tbase, g),
- stdout);
- if (ferror (stdout))
- clearerr (stdout);
- if (termscript)
- fwrite (GLYPH_STRING (tbase, g), 1, GLYPH_LENGTH (tbase, g),
- termscript);
- }
+ fwrite (conversion_buffer, 1, terminal_coding.produced, stdout);
+ if (ferror (stdout))
+ clearerr (stdout);
+ if (termscript)
+ fwrite (conversion_buffer, 1, terminal_coding.produced,
+ termscript);
}
}
+ cmcheckmagic ();
}
/* If start is zero, insert blanks instead of a string at start */
+void
insert_glyphs (start, len)
register GLYPH *start;
register int len;
{
char *buf;
- register GLYPH g;
+ GLYPH g;
register int tlen = GLYPH_TABLE_LENGTH;
register Lisp_Object *tbase = GLYPH_TABLE_BASE;
+ if (len <= 0)
+ return;
+
if (insert_glyphs_hook && ! FRAME_TERMCAP_P (updating_frame))
{
(*insert_glyphs_hook) (start, len);
turn_on_insert ();
cmplus (len);
- while (--len >= 0)
+ /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */
+ terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;
+ while (len-- > 0)
{
+ int produced, consumed;
+
OUTPUT1_IF (TS_ins_char);
if (!start)
g = SPACEGLYPH;
else
- g = *start++;
-
- if (GLYPH_SIMPLE_P (tbase, tlen, g))
{
- putc (g & 0xff, stdout);
- if (ferror (stdout))
- clearerr (stdout);
- if (termscript)
- putc (g & 0xff, termscript);
+ g = *start++;
+ /* We must open sufficient space for a character which
+ occupies more than one column. */
+ while (*start & GLYPH_MASK_PADDING)
+ {
+ OUTPUT1_IF (TS_ins_char);
+ start++, len--;
+ }
}
- else
+
+ if (len <= 0)
+ /* This is the last glyph. */
+ terminal_coding.mode |= CODING_MODE_LAST_BLOCK;
+
+ /* We use shared conversion buffer of the current size (1024
+ bytes at least). It is surely sufficient for just one glyph. */
+ produced = encode_terminal_code (&g, conversion_buffer,
+ 1, conversion_buffer_size, &consumed);
+ if (produced > 0)
{
- fwrite (GLYPH_STRING (tbase, g), 1, GLYPH_LENGTH (tbase, g), stdout);
+ fwrite (conversion_buffer, 1, produced, stdout);
if (ferror (stdout))
clearerr (stdout);
if (termscript)
- fwrite (GLYPH_STRING (tbase, g), 1, GLYPH_LENGTH (tbase, g),
- termscript);
+ fwrite (conversion_buffer, 1, produced, termscript);
}
- OUTPUT1_IF (TS_pad_inserted_char);
- }
+ OUTPUT1_IF (TS_pad_inserted_char);
+ }
+ cmcheckmagic ();
}
+void
delete_glyphs (n)
register int n;
{
\f
/* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
+void
ins_del_lines (vpos, n)
int vpos, n;
{
if (TN_standout_width >= 0)
{
- register lower_limit
+ register int lower_limit
= (scroll_region_ok
? specified_window
: FRAME_HEIGHT (selected_frame));
#ifndef old
/* char_ins_del_cost[n] is cost of inserting N characters.
- char_ins_del_cost[-n] is cost of deleting N characters. */
+ char_ins_del_cost[-n] is cost of deleting N characters.
+ The length of this vector is based on max_frame_width. */
int *char_ins_del_vector;
/* Delete costs are at negative offsets */
p = &char_ins_del_cost (frame)[0];
- for (i = FRAME_WIDTH (selected_frame); --i >= 0;)
+ for (i = FRAME_WIDTH (frame); --i >= 0;)
*--p = (del_startup_cost += del_cost_per_char);
/* Doing nothing is free */
*p++ = (ins_startup_cost += ins_cost_per_char);
}
-#ifdef HAVE_X_WINDOWS
-extern int x_screen_planes;
-#endif
-
-extern do_line_insertion_deletion_costs ();
-
+void
calculate_costs (frame)
FRAME_PTR frame;
{
- register char *f = TS_set_scroll_region ?
- TS_set_scroll_region
- : TS_set_scroll_region_1;
+ register char *f = (TS_set_scroll_region
+ ? TS_set_scroll_region
+ : TS_set_scroll_region_1);
- if (dont_calculate_costs)
- return;
+ FRAME_COST_BAUD_RATE (frame) = baud_rate;
+ scroll_region_cost = string_cost (f);
#ifdef HAVE_X_WINDOWS
if (FRAME_X_P (frame))
{
do_line_insertion_deletion_costs (frame, 0, ".5*", 0, ".5*",
- 0, 0, x_screen_planes);
+ 0, 0,
+ x_screen_planes (frame));
+ scroll_region_cost = 0;
return;
}
#endif
chars_wasted and copybuf are only used here in term.c in cases where
the term hook isn't called. */
+ max_frame_height = max (max_frame_height, FRAME_HEIGHT (frame));
+ max_frame_width = max (max_frame_width, FRAME_WIDTH (frame));
+
if (chars_wasted != 0)
- chars_wasted = (char *) xrealloc (chars_wasted, FRAME_HEIGHT (frame));
+ chars_wasted = (char *) xrealloc (chars_wasted, max_frame_height);
else
- chars_wasted = (char *) xmalloc (FRAME_HEIGHT (frame));
+ chars_wasted = (char *) xmalloc (max_frame_height);
if (copybuf != 0)
- copybuf = (char *) xrealloc (copybuf, FRAME_HEIGHT (frame));
+ copybuf = (char *) xrealloc (copybuf, max_frame_height);
else
- copybuf = (char *) xmalloc (FRAME_HEIGHT (frame));
+ copybuf = (char *) xmalloc (max_frame_height);
if (char_ins_del_vector != 0)
char_ins_del_vector
= (int *) xrealloc (char_ins_del_vector,
(sizeof (int)
- + 2 * FRAME_WIDTH (frame) * sizeof (int)));
+ + 2 * max_frame_width * sizeof (int)));
else
char_ins_del_vector
= (int *) xmalloc (sizeof (int)
- + 2 * FRAME_WIDTH (frame) * sizeof (int));
+ + 2 * max_frame_width * sizeof (int));
- bzero (chars_wasted, FRAME_HEIGHT (frame));
- bzero (copybuf, FRAME_HEIGHT (frame));
+ bzero (chars_wasted, max_frame_height);
+ bzero (copybuf, max_frame_height);
bzero (char_ins_del_vector, (sizeof (int)
- + 2 * FRAME_WIDTH (frame) * sizeof (int)));
+ + 2 * max_frame_width * sizeof (int)));
if (f && (!TS_ins_line && !TS_del_line))
do_line_insertion_deletion_costs (frame,
refusing to run at all on such a terminal. */
extern Lisp_Object Fidentity ();
- static Lisp_Object term_get_fkeys_1 ();
term_get_fkeys_arg = address;
internal_condition_case (term_get_fkeys_1, Qerror, Fidentity);
}
static Lisp_Object
term_get_fkeys_1 ()
{
- extern char *tgetstr ();
int i;
char **address = term_get_fkeys_arg;
if (i <= 19)
fcap[1] = '1' + i - 11;
else if (i <= 45)
- fcap[1] = 'A' + i - 11;
+ fcap[1] = 'A' + i - 20;
else
- fcap[1] = 'a' + i - 11;
+ fcap[1] = 'a' + i - 46;
{
char *sequence = tgetstr (fcap, address);
CONDITIONAL_REASSIGN ("%8", "kP", "prior");
/* if there's no key_dc keycap, map key_ic to `insert' keysym */
CONDITIONAL_REASSIGN ("kD", "kI", "insert");
+ /* if there's no key_end keycap, map key_ll to 'end' keysym */
+ CONDITIONAL_REASSIGN ("@7", "kH", "end");
+
+ /* IBM has their own non-standard dialect of terminfo.
+ If the standard name isn't found, try the IBM name. */
+ CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
+ CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
+ CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
+ CONDITIONAL_REASSIGN ("%7", "ki", "menu");
+ CONDITIONAL_REASSIGN ("@7", "kw", "end");
+ CONDITIONAL_REASSIGN ("F1", "k<", "f11");
+ CONDITIONAL_REASSIGN ("F2", "k>", "f12");
+ CONDITIONAL_REASSIGN ("%1", "kq", "help");
+ CONDITIONAL_REASSIGN ("*6", "kU", "select");
#undef CONDITIONAL_REASSIGN
}
}
\f
+void
term_init (terminal_type)
char *terminal_type;
{
register char *p;
int status;
- extern char *tgetstr ();
+#ifdef WINDOWSNT
+ initialize_w32_display ();
+
+ Wcm_clear ();
+
+ area = (char *) malloc (2044);
+
+ if (area == 0)
+ abort ();
+
+ FrameRows = FRAME_HEIGHT (selected_frame);
+ FrameCols = FRAME_WIDTH (selected_frame);
+ specified_window = FRAME_HEIGHT (selected_frame);
+
+ delete_in_insert_mode = 1;
+
+ UseTabs = 0;
+ scroll_region_ok = 0;
+
+ /* Seems to insert lines when it's not supposed to, messing
+ up the display. In doing a trace, it didn't seem to be
+ called much, so I don't think we're losing anything by
+ turning it off. */
+
+ line_ins_del_ok = 0;
+ char_ins_del_ok = 1;
+
+ baud_rate = 19200;
+
+ FRAME_CAN_HAVE_SCROLL_BARS (selected_frame) = 0;
+ FRAME_VERTICAL_SCROLL_BAR_TYPE (selected_frame) = vertical_scroll_bar_none;
+
+ return;
+#endif /* WINDOWSNT */
Wcm_clear ();
- dont_calculate_costs = 0;
status = tgetent (buffer, terminal_type);
if (status < 0)
- fatal ("Cannot open termcap database file.\n");
+ {
+#ifdef TERMINFO
+ fatal ("Cannot open terminfo database file");
+#else
+ fatal ("Cannot open termcap database file");
+#endif
+ }
if (status == 0)
- fatal ("Terminal type %s is not defined.\n\
+ {
+#ifdef TERMINFO
+ fatal ("Terminal type %s is not defined.\n\
If that is not the actual type of terminal you have,\n\
use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
`setenv TERM ...') to specify the correct type. It may be necessary\n\
-to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.\n",
- terminal_type);
-
+to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
+ terminal_type);
+#else
+ fatal ("Terminal type %s is not defined.\n\
+If that is not the actual type of terminal you have,\n\
+use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
+`setenv TERM ...') to specify the correct type. It may be necessary\n\
+to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
+ terminal_type);
+#endif
+ }
#ifdef TERMINFO
area = (char *) malloc (2044);
#else
Wcm.cm_tab = tgetstr ("ta", address);
TS_end_termcap_modes = tgetstr ("te", address);
TS_termcap_modes = tgetstr ("ti", address);
+ TS_bold_mode = tgetstr ("md", address);
+ TS_end_bold_mode = tgetstr ("me", address);
+ TS_underscore_mode = tgetstr ("us", address);
+ TS_end_underscore_mode = tgetstr ("ue", address);
Up = tgetstr ("up", address);
TS_visible_bell = tgetstr ("vb", address);
TS_end_visual_mode = tgetstr ("ve", address);
MultiLeft = tgetstr ("LE", address);
MultiRight = tgetstr ("RI", address);
- AutoWrap = tgetflag ("am");
+ MagicWrap = tgetflag ("xn");
+ /* Since we make MagicWrap terminals look like AutoWrap, we need to have
+ the former flag imply the latter. */
+ AutoWrap = MagicWrap || tgetflag ("am");
memory_below_frame = tgetflag ("db");
TF_hazeltine = tgetflag ("hz");
must_write_spaces = tgetflag ("in");
TF_insmode_motion = tgetflag ("mi");
TF_standout_motion = tgetflag ("ms");
TF_underscore = tgetflag ("ul");
- MagicWrap = tgetflag ("xn");
TF_xs = tgetflag ("xs");
TF_teleray = tgetflag ("xt");
term_get_fkeys (address);
/* Get frame size from system, or else from termcap. */
- get_frame_size (&FRAME_WIDTH (selected_frame),
- &FRAME_HEIGHT (selected_frame));
+ {
+ int height, width;
+ get_frame_size (&width, &height);
+ FRAME_WIDTH (selected_frame) = width;
+ FRAME_HEIGHT (selected_frame) = height;
+ }
+
if (FRAME_WIDTH (selected_frame) <= 0)
- FRAME_WIDTH (selected_frame) = tgetnum ("co");
+ SET_FRAME_WIDTH (selected_frame, tgetnum ("co"));
+ else
+ /* Keep width and external_width consistent */
+ SET_FRAME_WIDTH (selected_frame, FRAME_WIDTH (selected_frame));
if (FRAME_HEIGHT (selected_frame) <= 0)
FRAME_HEIGHT (selected_frame) = tgetnum ("li");
+
+ if (FRAME_HEIGHT (selected_frame) < 3
+ || FRAME_WIDTH (selected_frame) < 3)
+ fatal ("Screen size %dx%d is too small",
+ FRAME_HEIGHT (selected_frame), FRAME_WIDTH (selected_frame));
min_padding_speed = tgetnum ("pb");
TN_standout_width = tgetnum ("sg");
If that fails, we can't use standout mode at all. */
if (TS_end_standout_mode == 0)
{
- char *s = tgetstr ("me");
+ char *s = tgetstr ("me", address);
if (s != 0)
TS_end_standout_mode = s;
else
It lacks the ability to position the cursor.\n\
If that is not the actual type of terminal you have, use either the\n\
DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\
-or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.\n",
+or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.",
terminal_type);
-#else
+#else /* not VMS */
+# ifdef TERMINFO
fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
It lacks the ability to position the cursor.\n\
If that is not the actual type of terminal you have,\n\
use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
`setenv TERM ...') to specify the correct type. It may be necessary\n\
-to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.\n",
+to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
terminal_type);
-#endif
+# else /* TERMCAP */
+ fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
+It lacks the ability to position the cursor.\n\
+If that is not the actual type of terminal you have,\n\
+use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
+`setenv TERM ...') to specify the correct type. It may be necessary\n\
+to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
+ terminal_type);
+# endif /* TERMINFO */
+#endif /*VMS */
if (FRAME_HEIGHT (selected_frame) <= 0
|| FRAME_WIDTH (selected_frame) <= 0)
- fatal ("The frame size has not been specified.");
+ fatal ("The frame size has not been specified");
delete_in_insert_mode
= TS_delete_mode && TS_insert_mode
/* Remove width of standout marker from usable width of line */
if (TN_standout_width > 0)
- FRAME_WIDTH (selected_frame) -= TN_standout_width;
+ SET_FRAME_WIDTH (selected_frame,
+ FRAME_WIDTH (selected_frame) - TN_standout_width);
UseTabs = tabs_safe_p () && TabWidth == 8;
baud_rate = 9600;
FRAME_CAN_HAVE_SCROLL_BARS (selected_frame) = 0;
- FRAME_HAS_VERTICAL_SCROLL_BARS (selected_frame) = 0;
+ FRAME_VERTICAL_SCROLL_BAR_TYPE (selected_frame) = vertical_scroll_bar_none;
}
/* VARARGS 1 */
+void
fatal (str, arg1, arg2)
char *str, *arg1, *arg2;
{
fprintf (stderr, "emacs: ");
fprintf (stderr, str, arg1, arg2);
+ fprintf (stderr, "\n");
fflush (stderr);
exit (1);
}
+void
syms_of_term ()
{
DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo,
#else
system_uses_terminfo = 0;
#endif
+
+ DEFVAR_LISP ("ring-bell-function", &Vring_bell_function,
+ "Non-nil means call this function to ring the bell.\n\
+The function should accept no arguments.");
+ Vring_bell_function = Qnil;
}