/* terminal control module for terminals described by TERMCAP
- Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc.
+ Copyright (C) 1985, 1986, 1987, 1993, 1994 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
+the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Emacs is distributed in the hope that it will be useful,
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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 "screen.h"
+#include "frame.h"
#include "disptab.h"
#include "termhooks.h"
#include "keyboard.h"
+extern Lisp_Object Fmake_sparse_keymap ();
+
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
-#define OUTPUT(a) tputs (a, SCREEN_HEIGHT (selected_screen) - curY, cmputc)
+#define OUTPUT(a) tputs (a, 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, SCREEN_HEIGHT (selected_screen) - curY, cmputc); }
+#define OUTPUT_IF(a) { if (a) tputs (a, FRAME_HEIGHT (selected_frame) - curY, cmputc); }
#define OUTPUT1_IF(a) { if (a) tputs (a, 1, cmputc); }
-/* Terminal charateristics that higher levels want to look at.
+/* Terminal characteristics that higher levels want to look at.
These are all extern'd in termchar.h */
-#ifndef MULTI_SCREEN
-int screen_width; /* Number of usable columns */
-int screen_height; /* Number of lines */
-#endif
-
int must_write_spaces; /* Nonzero means spaces in the text
must actually be output; can't just skip
over some columns to leave them blank. */
int char_ins_del_ok; /* Terminal can insert and delete chars */
int scroll_region_ok; /* Terminal supports setting the
scroll window */
-int memory_below_screen; /* Terminal remembers lines
+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 screen on resuming
+/* 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. */
int no_redraw_on_reenter;
int (*raw_cursor_to_hook) ();
int (*clear_to_end_hook) ();
-int (*clear_screen_hook) ();
+int (*clear_frame_hook) ();
int (*clear_end_of_line_hook) ();
int (*ins_del_lines_hook) ();
int (*read_socket_hook) ();
-/* Return the current position of the mouse. This should clear
- mouse_moved until the next motion event arrives. */
-void (*mouse_position_hook) ( /* SCREEN_PTR *s,
- Lisp_Object *x,
- Lisp_Object *y,
- Lisp_Object *time */ );
+int (*frame_up_to_date_hook) ();
+
+/* Return the current position of the mouse.
+
+ Set *f to the frame the mouse is in, or zero if the mouse is in no
+ Emacs frame. If it is set to zero, all the other arguments are
+ garbage.
+
+ If the motion started in a scroll bar, set *bar_window to the
+ scroll bar's window, *part to the part the mouse is currently over,
+ *x to the position of the mouse along the scroll bar, and *y to the
+ overall length of the scroll bar.
+
+ Otherwise, set *bar_window to Qnil, and *x and *y to the column and
+ row of the character cell the mouse is over.
+
+ Set *time to the time the mouse was at the returned position.
-/* When reading from a minibuffer in a different screen, Emacs wants
- to shift the highlight from the selected screen to the minibuffer's
- screen; under X, this means it lies about where the focus is.
+ This should clear mouse_moved until the next motion
+ event arrives. */
+void (*mouse_position_hook) ( /* FRAME_PTR *f,
+ Lisp_Object *bar_window,
+ enum scroll_bar_part *part,
+ Lisp_Object *x,
+ Lisp_Object *y,
+ 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 (*screen_rehighlight_hook) ( /* SCREEN_PTR s */ );
+void (*frame_rehighlight_hook) ( /* 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
+ to the front, or bury it behind all the other windows. If this
+ hook is zero, that means the device we're displaying on doesn't
+ support overlapping frames, so there's no need to raise or lower
+ anything.
+
+ 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 */ );
+
+/* 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
+ indicate that we are displaying PORTION characters out of a total
+ 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 */ );
+
+
+/* The following three hooks are used when we're doing a thorough
+ redisplay of the frame. We don't explicitly know which scroll bars
+ are going to be deleted, because keeping track of when windows go
+ 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. */
+
+/* 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
+ `*redeem_scroll_bar_hook' is applied to its window before the judgement.
+
+ This should be applied to each frame each time its window tree is
+ redisplayed, even if it is not displaying scroll bars at the moment;
+ if the HAS_SCROLL_BARS flag has just been turned off, only calling
+ this and the judge_scroll_bars_hook will get rid of them.
+
+ 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 */ );
+
+/* 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 */ );
+
+/* Remove all scroll bars on FRAME that haven't been saved since the
+ last call to `*condemn_scroll_bars_hook'.
+
+ This should be applied to each frame after each time its window
+ tree is redisplayed, even if it is not displaying scroll bars at the
+ moment; if the HAS_SCROLL_BARS flag has just been turned off, only
+ calling this and condemn_scroll_bars_hook will get rid of them.
+
+ 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 */ );
+
/* Strings, numbers and flags taken from the termcap entry. */
char *TS_bell; /* "bl" */
char *TS_clr_to_bottom; /* "cd" */
char *TS_clr_line; /* "ce", clear to end of line */
-char *TS_clr_screen; /* "cl" */
+char *TS_clr_frame; /* "cl" */
char *TS_set_scroll_region; /* "cs" (2 params, first line and last line) */
char *TS_set_scroll_region_1; /* "cS" (4 params: total lines,
lines above scroll region, lines below it,
int standout_mode; /* Nonzero when in standout mode. */
/* Size of window specified by higher levels.
- This is the number of lines, from the top of screen downwards,
+ This is the number of lines, from the top of frame downwards,
which can participate in insert-line/delete-line operations.
- Effectively it excludes the bottom screen_height - specified_window_size
+ Effectively it excludes the bottom frame_height - specified_window_size
lines from those operations. */
int specified_window;
-/* Screen currently being redisplayed; 0 if not currently redisplaying.
+/* Frame currently being redisplayed; 0 if not currently redisplaying.
(Direct output does not count). */
-SCREEN_PTR updating_screen;
+FRAME_PTR updating_frame;
+
+/* Provided for lisp packages. */
+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 */
+
ring_bell ()
{
- if (! SCREEN_IS_TERMCAP (selected_screen))
+ if (! FRAME_TERMCAP_P (selected_frame))
{
(*ring_bell_hook) ();
return;
set_terminal_modes ()
{
- if (! SCREEN_IS_TERMCAP (selected_screen))
+ if (! FRAME_TERMCAP_P (selected_frame))
{
(*set_terminal_modes_hook) ();
return;
reset_terminal_modes ()
{
- if (! SCREEN_IS_TERMCAP (selected_screen))
+ if (! FRAME_TERMCAP_P (selected_frame))
{
(*reset_terminal_modes_hook) ();
return;
OUTPUT_IF (TS_end_termcap_modes);
/* Output raw CR so kernel can track the cursor hpos. */
/* But on magic-cookie terminals this can erase an end-standout marker and
- cause the rest of the screen to be in standout, so move down first. */
+ cause the rest of the frame to be in standout, so move down first. */
if (TN_standout_width >= 0)
cmputc ('\n');
cmputc ('\r');
}
-update_begin (s)
- SCREEN_PTR s;
+update_begin (f)
+ FRAME_PTR f;
{
- updating_screen = s;
- if (! SCREEN_IS_TERMCAP (updating_screen))
- (*update_begin_hook) (s);
+ updating_frame = f;
+ if (! FRAME_TERMCAP_P (updating_frame))
+ (*update_begin_hook) (f);
}
-update_end (s)
- SCREEN_PTR s;
+update_end (f)
+ FRAME_PTR f;
{
- if (! SCREEN_IS_TERMCAP (updating_screen))
+ if (! FRAME_TERMCAP_P (updating_frame))
{
- (*update_end_hook) (s);
- updating_screen = 0;
+ (*update_end_hook) (f);
+ updating_frame = 0;
return;
}
turn_off_insert ();
background_highlight ();
standout_requested = 0;
- updating_screen = 0;
+ updating_frame = 0;
}
set_terminal_window (size)
int size;
{
- if (! SCREEN_IS_TERMCAP (updating_screen))
+ if (! FRAME_TERMCAP_P (updating_frame))
{
(*set_terminal_window_hook) (size);
return;
}
- specified_window = size ? size : SCREEN_HEIGHT (selected_screen);
+ specified_window = size ? size : FRAME_HEIGHT (selected_frame);
if (!scroll_region_ok)
return;
set_scroll_region (0, specified_window);
else if (TS_set_scroll_region_1)
{
buf = tparam (TS_set_scroll_region_1, 0, 0,
- SCREEN_HEIGHT (selected_screen), start,
- SCREEN_HEIGHT (selected_screen) - stop,
- SCREEN_HEIGHT (selected_screen));
+ FRAME_HEIGHT (selected_frame), start,
+ FRAME_HEIGHT (selected_frame) - stop,
+ FRAME_HEIGHT (selected_frame));
}
else
{
- buf = tparam (TS_set_window, 0, 0, start, 0, stop, SCREEN_WIDTH (selected_screen));
+ buf = tparam (TS_set_window, 0, 0, start, 0, stop, FRAME_WIDTH (selected_frame));
}
OUTPUT (buf);
- free (buf);
+ xfree (buf);
losecursor ();
}
\f
\f
/* Handle standout mode for terminals in which TN_standout_width >= 0.
On these terminals, standout is controlled by markers that
- live inside the screen memory. TN_standout_width is the width
+ live inside the terminal's memory. TN_standout_width is the width
that the marker occupies in memory. Standout runs from the marker
to the end of the line on some terminals, or to the next
turn-off-standout marker (TS_end_standout_mode) string
int highlight;
int vpos;
{
- if (! SCREEN_IS_TERMCAP ((updating_screen ? updating_screen : selected_screen)))
+ if (! FRAME_TERMCAP_P ((updating_frame ? updating_frame : selected_frame)))
{
(*reassert_line_highlight_hook) (highlight, vpos);
return;
int new_highlight, vpos, first_unused_hpos;
{
standout_requested = new_highlight;
- if (! SCREEN_IS_TERMCAP (updating_screen))
+ if (! FRAME_TERMCAP_P (updating_frame))
{
(*change_line_highlight_hook) (new_highlight, vpos, first_unused_hpos);
return;
/* On Teleray, make sure to erase the SO marker. */
if (TF_teleray)
{
- cmgoto (curY - 1, SCREEN_WIDTH (selected_screen) - 4);
+ cmgoto (curY - 1, FRAME_WIDTH (selected_frame) - 4);
OUTPUT ("\033S");
curY++; /* ESC S moves to next line where the TS_standout_mode was */
curX = 0;
/* Move to absolute position, specified origin 0 */
cursor_to (row, col)
+ int row, col;
{
- if (! SCREEN_IS_TERMCAP ((updating_screen
- ? updating_screen
- : selected_screen))
+ if (! FRAME_TERMCAP_P ((updating_frame
+ ? updating_frame
+ : selected_frame))
&& cursor_to_hook)
{
(*cursor_to_hook) (row, col);
/* Similar but don't take any account of the wasted characters. */
raw_cursor_to (row, col)
+ int row, col;
{
- if (! SCREEN_IS_TERMCAP ((updating_screen ? updating_screen : selected_screen)))
+ if (! FRAME_TERMCAP_P ((updating_frame ? updating_frame : selected_frame)))
{
(*raw_cursor_to_hook) (row, col);
return;
\f
/* Erase operations */
-/* clear from cursor to end of screen */
+/* clear from cursor to end of frame */
clear_to_end ()
{
register int i;
- if (clear_to_end_hook && SCREEN_IS_TERMCAP (updating_screen))
+ if (clear_to_end_hook && ! FRAME_TERMCAP_P (updating_frame))
{
(*clear_to_end_hook) ();
return;
{
background_highlight ();
OUTPUT (TS_clr_to_bottom);
- bzero (chars_wasted + curY, SCREEN_HEIGHT (selected_screen) - curY);
+ bzero (chars_wasted + curY, FRAME_HEIGHT (selected_frame) - curY);
}
else
{
- for (i = curY; i < SCREEN_HEIGHT (selected_screen); i++)
+ for (i = curY; i < FRAME_HEIGHT (selected_frame); i++)
{
cursor_to (i, 0);
- clear_end_of_line_raw (SCREEN_WIDTH (selected_screen));
+ clear_end_of_line_raw (FRAME_WIDTH (selected_frame));
}
}
}
-/* Clear entire screen */
+/* Clear entire frame */
-clear_screen ()
+clear_frame ()
{
- if (clear_screen_hook
- && ! SCREEN_IS_TERMCAP ((updating_screen ? updating_screen : selected_screen)))
+ if (clear_frame_hook
+ && ! FRAME_TERMCAP_P ((updating_frame ? updating_frame : selected_frame)))
{
- (*clear_screen_hook) ();
+ (*clear_frame_hook) ();
return;
}
- if (TS_clr_screen)
+ if (TS_clr_frame)
{
background_highlight ();
- OUTPUT (TS_clr_screen);
- bzero (chars_wasted, SCREEN_HEIGHT (selected_screen));
+ OUTPUT (TS_clr_frame);
+ bzero (chars_wasted, FRAME_HEIGHT (selected_frame));
cmat (0, 0);
}
else
clear_end_of_line (first_unused_hpos)
int first_unused_hpos;
{
- static GLYPH buf[1] = {SPACEGLYPH};
- if (SCREEN_IS_TERMCAP (selected_screen)
+ static GLYPH buf = SPACEGLYPH;
+ if (FRAME_TERMCAP_P (selected_frame)
&& TN_standout_width == 0 && curX == 0 && chars_wasted[curY] != 0)
- write_glyphs (buf, 1);
+ write_glyphs (&buf, 1);
clear_end_of_line_raw (first_unused_hpos);
}
register int i;
if (clear_end_of_line_hook
- && ! SCREEN_IS_TERMCAP ((updating_screen
- ? updating_screen
- : selected_screen)))
+ && ! FRAME_TERMCAP_P ((updating_frame
+ ? updating_frame
+ : selected_frame)))
{
(*clear_end_of_line_hook) (first_unused_hpos);
return;
turn_off_insert ();
/* Do not write in last row last col with Autowrap on. */
- if (AutoWrap && curY == SCREEN_HEIGHT (selected_screen) - 1
- && first_unused_hpos == SCREEN_WIDTH (selected_screen))
+ if (AutoWrap && curY == FRAME_HEIGHT (selected_frame) - 1
+ && first_unused_hpos == FRAME_WIDTH (selected_frame))
first_unused_hpos--;
for (i = curX; i < first_unused_hpos; i++)
register Lisp_Object *tbase = GLYPH_TABLE_BASE;
if (write_glyphs_hook
- && ! SCREEN_IS_TERMCAP ((updating_screen ? updating_screen : selected_screen)))
+ && ! FRAME_TERMCAP_P ((updating_frame ? updating_frame : selected_frame)))
{
(*write_glyphs_hook) (string, len);
return;
turn_off_insert ();
/* Don't dare write in last column of bottom line, if AutoWrap,
- since that would scroll the whole screen on some terminals. */
+ since that would scroll the whole frame on some terminals. */
if (AutoWrap
- && curY + 1 == SCREEN_HEIGHT (selected_screen)
+ && curY + 1 == FRAME_HEIGHT (selected_frame)
&& (curX + len - (chars_wasted[curY] & 077)
- == SCREEN_WIDTH (selected_screen)))
+ == FRAME_WIDTH (selected_frame)))
len --;
cmplus (len);
register int tlen = GLYPH_TABLE_LENGTH;
register Lisp_Object *tbase = GLYPH_TABLE_BASE;
- if (insert_glyphs_hook && ! SCREEN_IS_TERMCAP (updating_screen))
+ if (insert_glyphs_hook && ! FRAME_TERMCAP_P (updating_frame))
{
(*insert_glyphs_hook) (start, len);
return;
{
buf = tparam (TS_ins_multi_chars, 0, 0, len);
OUTPUT1 (buf);
- free (buf);
+ xfree (buf);
if (start)
write_glyphs (start, len);
return;
char *buf;
register int i;
- if (delete_glyphs_hook && ! SCREEN_IS_TERMCAP (updating_screen))
+ if (delete_glyphs_hook && ! FRAME_TERMCAP_P (updating_frame))
{
(*delete_glyphs_hook) (n);
return;
{
buf = tparam (TS_del_multi_chars, 0, 0, n);
OUTPUT1 (buf);
- free (buf);
+ xfree (buf);
}
else
for (i = 0; i < n; i++)
register int i = n > 0 ? n : -n;
register char *buf;
- if (ins_del_lines_hook && ! SCREEN_IS_TERMCAP (updating_screen))
+ if (ins_del_lines_hook && ! FRAME_TERMCAP_P (updating_frame))
{
(*ins_del_lines_hook) (vpos, n);
return;
as there will be a matching inslines later that will flush them. */
if (scroll_region_ok && vpos + i >= specified_window)
return;
- if (!memory_below_screen && vpos + i >= SCREEN_HEIGHT (selected_screen))
+ if (!memory_below_frame && vpos + i >= FRAME_HEIGHT (selected_frame))
return;
if (multi)
background_highlight ();
buf = tparam (multi, 0, 0, i);
OUTPUT (buf);
- free (buf);
+ xfree (buf);
}
else if (single)
{
register lower_limit
= (scroll_region_ok
? specified_window
- : SCREEN_HEIGHT (selected_screen));
+ : FRAME_HEIGHT (selected_frame));
if (n < 0)
{
bzero (&chars_wasted[vpos], n);
}
}
- if (!scroll_region_ok && memory_below_screen && n < 0)
+ if (!scroll_region_ok && memory_below_frame && n < 0)
{
- cursor_to (SCREEN_HEIGHT (selected_screen) + n, 0);
+ cursor_to (FRAME_HEIGHT (selected_frame) + n, 0);
clear_to_end ();
}
}
int *char_ins_del_vector;
-#define char_ins_del_cost(s) (&char_ins_del_vector[SCREEN_WIDTH ((s))])
+#define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH ((f))])
#endif
/* ARGSUSED */
static void
-calculate_ins_del_char_costs (screen)
- SCREEN_PTR screen;
+calculate_ins_del_char_costs (frame)
+ FRAME_PTR frame;
{
int ins_startup_cost, del_startup_cost;
int ins_cost_per_char, del_cost_per_char;
}
/* Delete costs are at negative offsets */
- p = &char_ins_del_cost (screen)[0];
- for (i = SCREEN_WIDTH (selected_screen); --i >= 0;)
+ p = &char_ins_del_cost (frame)[0];
+ for (i = FRAME_WIDTH (selected_frame); --i >= 0;)
*--p = (del_startup_cost += del_cost_per_char);
/* Doing nothing is free */
- p = &char_ins_del_cost (screen)[0];
+ p = &char_ins_del_cost (frame)[0];
*p++ = 0;
/* Insert costs are at positive offsets */
- for (i = SCREEN_WIDTH (screen); --i >= 0;)
+ for (i = FRAME_WIDTH (frame); --i >= 0;)
*p++ = (ins_startup_cost += ins_cost_per_char);
}
-#ifdef HAVE_X_WINDOWS
-extern int x_screen_planes;
-#endif
+extern do_line_insertion_deletion_costs ();
-calculate_costs (screen)
- SCREEN_PTR screen;
+calculate_costs (frame)
+ FRAME_PTR frame;
{
- register char *s = 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 (SCREEN_IS_X (screen))
+ if (FRAME_X_P (frame))
{
- do_line_insertion_deletion_costs (screen, 0, ".5*", 0, ".5*",
- 0, 0, x_screen_planes);
+ do_line_insertion_deletion_costs (frame, 0, ".5*", 0, ".5*",
+ 0, 0,
+ x_screen_planes (frame));
+ scroll_region_cost = 0;
return;
}
#endif
/* These variables are only used for terminal stuff. They are allocated
- once for the terminal screen of X-windows emacs, but not used afterwards.
+ once for the terminal frame of X-windows emacs, but not used afterwards.
char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
X turns off char_ins_del_ok.
the term hook isn't called. */
if (chars_wasted != 0)
- chars_wasted = (char *) xrealloc (chars_wasted, SCREEN_HEIGHT (screen));
+ chars_wasted = (char *) xrealloc (chars_wasted, FRAME_HEIGHT (frame));
else
- chars_wasted = (char *) xmalloc (SCREEN_HEIGHT (screen));
+ chars_wasted = (char *) xmalloc (FRAME_HEIGHT (frame));
if (copybuf != 0)
- copybuf = (char *) xrealloc (copybuf, SCREEN_HEIGHT (screen));
+ copybuf = (char *) xrealloc (copybuf, FRAME_HEIGHT (frame));
else
- copybuf = (char *) xmalloc (SCREEN_HEIGHT (screen));
+ copybuf = (char *) xmalloc (FRAME_HEIGHT (frame));
if (char_ins_del_vector != 0)
char_ins_del_vector
= (int *) xrealloc (char_ins_del_vector,
(sizeof (int)
- + 2 * SCREEN_WIDTH (screen) * sizeof (int)));
+ + 2 * FRAME_WIDTH (frame) * sizeof (int)));
else
char_ins_del_vector
= (int *) xmalloc (sizeof (int)
- + 2 * SCREEN_WIDTH (screen) * sizeof (int));
+ + 2 * FRAME_WIDTH (frame) * sizeof (int));
- bzero (chars_wasted, SCREEN_HEIGHT (screen));
- bzero (copybuf, SCREEN_HEIGHT (screen));
+ bzero (chars_wasted, FRAME_HEIGHT (frame));
+ bzero (copybuf, FRAME_HEIGHT (frame));
bzero (char_ins_del_vector, (sizeof (int)
- + 2 * SCREEN_WIDTH (screen) * sizeof (int)));
+ + 2 * FRAME_WIDTH (frame) * sizeof (int)));
- if (s && (!TS_ins_line && !TS_del_line))
- do_line_insertion_deletion_costs (screen,
+ if (f && (!TS_ins_line && !TS_del_line))
+ do_line_insertion_deletion_costs (frame,
TS_rev_scroll, TS_ins_multi_lines,
TS_fwd_scroll, TS_del_multi_lines,
- s, s, 1);
+ f, f, 1);
else
- do_line_insertion_deletion_costs (screen,
+ do_line_insertion_deletion_costs (frame,
TS_ins_line, TS_ins_multi_lines,
TS_del_line, TS_del_multi_lines,
0, 0, 1);
- calculate_ins_del_char_costs (screen);
+ calculate_ins_del_char_costs (frame);
/* Don't use TS_repeat if its padding is worse than sending the chars */
if (TS_repeat && per_line_cost (TS_repeat) * baud_rate < 9000)
RPov = string_cost (TS_repeat);
else
- RPov = SCREEN_WIDTH (screen) * 2;
+ RPov = FRAME_WIDTH (frame) * 2;
cmcostinit (); /* set up cursor motion costs */
}
\f
+struct fkey_table {
+ char *cap, *name;
+};
+
+ /* Termcap capability names that correspond directly to X keysyms.
+ Some of these (marked "terminfo") aren't supplied by old-style
+ (Berkeley) termcap entries. They're listed in X keysym order;
+ except we put the keypad keys first, so that if they clash with
+ other keys (as on the IBM PC keyboard) they get overridden.
+ */
+
+static struct fkey_table keys[] = {
+ "kh", "home", /* termcap */
+ "kl", "left", /* termcap */
+ "ku", "up", /* termcap */
+ "kr", "right", /* termcap */
+ "kd", "down", /* termcap */
+ "%8", "prior", /* terminfo */
+ "%5", "next", /* terminfo */
+ "@7", "end", /* terminfo */
+ "@1", "begin", /* terminfo */
+ "*6", "select", /* terminfo */
+ "%9", "print", /* terminfo */
+ "@4", "execute", /* terminfo --- actually the `command' key */
+ /*
+ * "insert" --- see below
+ */
+ "&8", "undo", /* terminfo */
+ "%0", "redo", /* terminfo */
+ "%7", "menu", /* terminfo --- actually the `options' key */
+ "@0", "find", /* terminfo */
+ "@2", "cancel", /* terminfo */
+ "%1", "help", /* terminfo */
+ /*
+ * "break" goes here, but can't be reliably intercepted with termcap
+ */
+ "&4", "reset", /* terminfo --- actually `restart' */
+ /*
+ * "system" and "user" --- no termcaps
+ */
+ "kE", "clearline", /* terminfo */
+ "kA", "insertline", /* terminfo */
+ "kL", "deleteline", /* terminfo */
+ "kI", "insertchar", /* terminfo */
+ "kD", "deletechar", /* terminfo */
+ "kB", "backtab", /* terminfo */
+ /*
+ * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
+ */
+ "@8", "kp-enter", /* terminfo */
+ /*
+ * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
+ * "kp-multiply", "kp-add", "kp-separator",
+ * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
+ * --- no termcaps for any of these.
+ */
+ "K4", "kp-1", /* terminfo */
+ /*
+ * "kp-2" --- no termcap
+ */
+ "K5", "kp-3", /* terminfo */
+ /*
+ * "kp-4" --- no termcap
+ */
+ "K2", "kp-5", /* terminfo */
+ /*
+ * "kp-6" --- no termcap
+ */
+ "K1", "kp-7", /* terminfo */
+ /*
+ * "kp-8" --- no termcap
+ */
+ "K3", "kp-9", /* terminfo */
+ /*
+ * "kp-equal" --- no termcap
+ */
+ "k1", "f1",
+ "k2", "f2",
+ "k3", "f3",
+ "k4", "f4",
+ "k5", "f5",
+ "k6", "f6",
+ "k7", "f7",
+ "k8", "f8",
+ "k9", "f9",
+ };
+
+static char **term_get_fkeys_arg;
+static Lisp_Object term_get_fkeys_1 ();
+
/* Find the escape codes sent by the function keys for Vfunction_key_map.
This function scans the termcap function key sequence entries, and
adds entries to Vfunction_key_map for each function key it finds. */
term_get_fkeys (address)
char **address;
{
- extern char *tgetstr ();
- struct fkey_table {
- char *cap, *name;
- };
- static struct fkey_table keys[] = {
- "kl", "left",
- "kr", "right",
- "ku", "up",
- "kd", "down",
- "kh", "home",
- "k1", "f1",
- "k2", "f2",
- "k3", "f3",
- "k4", "f4",
- "k5", "f5",
- "k6", "f6",
- "k7", "f7",
- "k8", "f8",
- "k9", "f9",
- "k0", "f10",
- "kH", "home-down",
- "ka", "clear-tabs",
- "kt", "clear-tab",
- "kT", "set-tab",
- "kC", "clear",
- "kL", "deleteline",
- "kM", "exit-insert",
- "kE", "clear-eol",
- "kS", "clear-eos",
- "kI", "insert",
- "kA", "insertline",
- "kN", "next",
- "kP", "prior",
- "kF", "scroll-forward",
- "kR", "scroll-reverse"
- };
+ /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
+ errors during the call. The only errors should be from Fdefine_key
+ when given a key sequence containing an invalid prefix key. If the
+ termcap defines function keys which use a prefix that is already bound
+ to a command by the default bindings, we should silently ignore that
+ function key specification, rather than giving the user an error and
+ refusing to run at all on such a terminal. */
+
+ extern Lisp_Object Fidentity ();
+ term_get_fkeys_arg = address;
+ internal_condition_case (term_get_fkeys_1, Qerror, Fidentity);
+}
+
+static Lisp_Object
+term_get_fkeys_1 ()
+{
int i;
+ char **address = term_get_fkeys_arg;
+
+ /* This can happen if CANNOT_DUMP or with strange options. */
+ if (!initialized)
+ Vfunction_key_map = Fmake_sparse_keymap (Qnil);
+
for (i = 0; i < (sizeof (keys)/sizeof (keys[0])); i++)
{
char *sequence = tgetstr (keys[i].cap, address);
if (sequence)
- Fdefine_key (Vfunction_key_map,
- build_string (sequence),
- Fmake_vector (make_number (1), intern (keys[i].name)));
+ Fdefine_key (Vfunction_key_map, build_string (sequence),
+ Fmake_vector (make_number (1),
+ intern (keys[i].name)));
}
+
+ /* The uses of the "k0" capability are inconsistent; sometimes it
+ describes F10, whereas othertimes it describes F0 and "k;" describes F10.
+ We will attempt to politely accommodate both systems by testing for
+ "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
+ */
+ {
+ char *k_semi = tgetstr ("k;", address);
+ char *k0 = tgetstr ("k0", address);
+ char *k0_name = "f10";
+
+ if (k_semi)
+ {
+ Fdefine_key (Vfunction_key_map, build_string (k_semi),
+ Fmake_vector (make_number (1), intern ("f10")));
+ k0_name = "f0";
+ }
+
+ if (k0)
+ Fdefine_key (Vfunction_key_map, build_string (k0),
+ Fmake_vector (make_number (1), intern (k0_name)));
+ }
+
+ /* Set up cookies for numbered function keys above f10. */
+ {
+ char fcap[3], fkey[4];
+
+ fcap[0] = 'F'; fcap[2] = '\0';
+ for (i = 11; i < 64; i++)
+ {
+ if (i <= 19)
+ fcap[1] = '1' + i - 11;
+ else if (i <= 45)
+ fcap[1] = 'A' + i - 11;
+ else
+ fcap[1] = 'a' + i - 11;
+
+ {
+ char *sequence = tgetstr (fcap, address);
+ if (sequence)
+ {
+ sprintf (fkey, "f%d", i);
+ Fdefine_key (Vfunction_key_map, build_string (sequence),
+ Fmake_vector (make_number (1),
+ intern (fkey)));
+ }
+ }
+ }
+ }
+
+ /*
+ * Various mappings to try and get a better fit.
+ */
+ {
+#define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
+ if (!tgetstr (cap1, address)) \
+ { \
+ char *sequence = tgetstr (cap2, address); \
+ if (sequence) \
+ Fdefine_key (Vfunction_key_map, build_string (sequence), \
+ Fmake_vector (make_number (1), \
+ intern (sym))); \
+ }
+
+ /* if there's no key_next keycap, map key_npage to `next' keysym */
+ CONDITIONAL_REASSIGN ("%5", "kN", "next");
+ /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
+ CONDITIONAL_REASSIGN ("%8", "kP", "prior");
+ /* if there's no key_dc keycap, map key_ic to `insert' keysym */
+ CONDITIONAL_REASSIGN ("kD", "kI", "insert");
+
+ /* 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
register char *p;
int status;
- extern char *tgetstr ();
+#ifdef WINDOWSNT
+ initialize_win_nt_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_HAS_VERTICAL_SCROLL_BARS (selected_frame) = 0;
+
+ return;
+#endif /* WINDOWSNT */
Wcm_clear ();
- dont_calculate_costs = 0;
status = tgetent (buffer, terminal_type);
if (status < 0)
fatal ("Cannot open termcap database file.\n");
if (status == 0)
- fatal ("Terminal type %s is not defined.\n", terminal_type);
+ 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);
#ifdef TERMINFO
area = (char *) malloc (2044);
BackTab = tgetstr ("bt", address);
TS_clr_to_bottom = tgetstr ("cd", address);
TS_clr_line = tgetstr ("ce", address);
- TS_clr_screen = tgetstr ("cl", address);
+ TS_clr_frame = tgetstr ("cl", address);
ColPosition = tgetstr ("ch", address);
AbsPosition = tgetstr ("cm", address);
CR = tgetstr ("cr", address);
MultiRight = tgetstr ("RI", address);
AutoWrap = tgetflag ("am");
- memory_below_screen = tgetflag ("db");
+ memory_below_frame = tgetflag ("db");
TF_hazeltine = tgetflag ("hz");
must_write_spaces = tgetflag ("in");
meta_key = tgetflag ("km") || tgetflag ("MT");
term_get_fkeys (address);
- /* Get screen size from system, or else from termcap. */
- get_screen_size (&SCREEN_WIDTH (selected_screen),
- &SCREEN_HEIGHT (selected_screen));
- if (SCREEN_WIDTH (selected_screen) <= 0)
- SCREEN_WIDTH (selected_screen) = tgetnum ("co");
- if (SCREEN_HEIGHT (selected_screen) <= 0)
- SCREEN_HEIGHT (selected_screen) = tgetnum ("li");
+ /* Get frame size from system, or else from termcap. */
+ get_frame_size (&FRAME_WIDTH (selected_frame),
+ &FRAME_HEIGHT (selected_frame));
+ if (FRAME_WIDTH (selected_frame) <= 0)
+ FRAME_WIDTH (selected_frame) = tgetnum ("co");
+ 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.\n",
+ FRAME_HEIGHT (selected_frame), FRAME_WIDTH (selected_frame));
min_padding_speed = tgetnum ("pb");
TN_standout_width = tgetnum ("sg");
TS_standout_mode = tgetstr ("us", address);
}
+ /* If no `se' string, try using a `me' string instead.
+ If that fails, we can't use standout mode at all. */
+ if (TS_end_standout_mode == 0)
+ {
+ char *s = tgetstr ("me", address);
+ if (s != 0)
+ TS_end_standout_mode = s;
+ else
+ TS_standout_mode = 0;
+ }
+
if (TF_teleray)
{
Wcm.cm_tab = 0;
if (!strcmp (terminal_type, "supdup"))
{
- memory_below_screen = 1;
+ memory_below_frame = 1;
Wcm.cm_losewrap = 1;
}
if (!strncmp (terminal_type, "c10", 3)
for windows starting at the upper left corner;
but that is all Emacs uses.
- This string works only if the screen is using
+ This string works only if the frame is using
the top of the video memory, because addressing is memory-relative.
So first check the :ti string to see if that is true.
}
}
- ScreenRows = SCREEN_HEIGHT (selected_screen);
- ScreenCols = SCREEN_WIDTH (selected_screen);
- specified_window = SCREEN_HEIGHT (selected_screen);
+ FrameRows = FRAME_HEIGHT (selected_frame);
+ FrameCols = FRAME_WIDTH (selected_frame);
+ specified_window = FRAME_HEIGHT (selected_frame);
if (Wcm_init () == -1) /* can't do cursor motion */
#ifdef VMS
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 C-shell command `setenv TERM ...' to specify the correct type.\n\
-It may be necessary to do `unsetenv TERMCAP' as well.\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);
#endif
- if (SCREEN_HEIGHT (selected_screen) <= 0
- || SCREEN_WIDTH (selected_screen) <= 0)
- fatal ("The screen size has not been specified.");
+ if (FRAME_HEIGHT (selected_frame) <= 0
+ || FRAME_WIDTH (selected_frame) <= 0)
+ 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)
- SCREEN_WIDTH (selected_screen) -= TN_standout_width;
+ FRAME_WIDTH (selected_frame) -= TN_standout_width;
UseTabs = tabs_safe_p () && TabWidth == 8;
if (read_socket_hook) /* Baudrate is somewhat */
/* meaningless in this case */
baud_rate = 9600;
+
+ FRAME_CAN_HAVE_SCROLL_BARS (selected_frame) = 0;
+ FRAME_HAS_VERTICAL_SCROLL_BARS (selected_frame) = 0;
}
/* VARARGS 1 */
fatal (str, arg1, arg2)
+ char *str, *arg1, *arg2;
{
fprintf (stderr, "emacs: ");
fprintf (stderr, str, arg1, arg2);
fflush (stderr);
exit (1);
}
+
+syms_of_term ()
+{
+ DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo,
+ "Non-nil means the system uses terminfo rather than termcap.\n\
+This variable can be used by terminal emulator packages.");
+#ifdef TERMINFO
+ system_uses_terminfo = 1;
+#else
+ system_uses_terminfo = 0;
+#endif
+}