#include <sys/file.h>
#include <unistd.h>
#include <signal.h>
-#include <stdarg.h>
#include <setjmp.h>
#include "lisp.h"
static void tty_set_scroll_region (struct frame *f, int start, int stop);
static void turn_on_face (struct frame *, int face_id);
static void turn_off_face (struct frame *, int face_id);
+static void tty_turn_off_highlight (struct tty_display_info *);
static void tty_show_cursor (struct tty_display_info *);
static void tty_hide_cursor (struct tty_display_info *);
static void tty_background_highlight (struct tty_display_info *tty);
+static struct terminal *get_tty_terminal (Lisp_Object, int);
static void clear_tty_hooks (struct terminal *terminal);
static void set_tty_hooks (struct terminal *terminal);
static void dissociate_if_controlling_tty (int fd);
static void delete_tty (struct terminal *);
static void maybe_fatal (int must_succeed, struct terminal *terminal,
- const char *str1, const char *str2, ...) NO_RETURN;
-static void vfatal (const char *str, va_list ap) NO_RETURN;
+ const char *str1, const char *str2, ...)
+ NO_RETURN ATTRIBUTE_FORMAT_PRINTF (3, 5) ATTRIBUTE_FORMAT_PRINTF (4, 5);
+static void vfatal (const char *str, va_list ap)
+ NO_RETURN ATTRIBUTE_FORMAT_PRINTF (1, 0);
#define OUTPUT(tty, a) \
/* The largest frame width in any call to calculate_costs. */
-int max_frame_cols;
-
-/* The largest frame height in any call to calculate_costs. */
-
-int max_frame_lines;
+static int max_frame_cols;
/* Non-zero if we have dropped our controlling tty and therefore
should not open a frame on stdout. */
/* Set up termcap modes for Emacs. */
-void
+static void
tty_set_terminal_modes (struct terminal *terminal)
{
struct tty_display_info *tty = terminal->display_info.tty;
/* Reset termcap modes before exiting Emacs. */
-void
+static void
tty_reset_terminal_modes (struct terminal *terminal)
{
struct tty_display_info *tty = terminal->display_info.tty;
\f
/* Handle highlighting. */
-void
+static void
tty_turn_off_highlight (struct tty_display_info *tty)
{
if (tty->standout_mode)
static unsigned char *encode_terminal_src;
static unsigned char *encode_terminal_dst;
/* Allocated sizes of the above buffers. */
-static int encode_terminal_src_size;
-static int encode_terminal_dst_size;
+static ptrdiff_t encode_terminal_src_size;
+static ptrdiff_t encode_terminal_dst_size;
/* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
Set CODING->produced to the byte-length of the resulting byte
{
struct glyph *src_end = src + src_len;
unsigned char *buf;
- int nchars, nbytes, required;
- register int tlen = GLYPH_TABLE_LENGTH;
+ ptrdiff_t nchars, nbytes, required;
+ ptrdiff_t tlen = GLYPH_TABLE_LENGTH;
register Lisp_Object *tbase = GLYPH_TABLE_BASE;
Lisp_Object charset_list;
multibyte-form. But, it may be enlarged on demand if
Vglyph_table contains a string or a composite glyph is
encountered. */
- required = MAX_MULTIBYTE_LENGTH * src_len;
+ if (min (PTRDIFF_MAX, SIZE_MAX) / MAX_MULTIBYTE_LENGTH < src_len)
+ memory_full (SIZE_MAX);
+ required = src_len;
+ required *= MAX_MULTIBYTE_LENGTH;
if (encode_terminal_src_size < required)
{
- if (encode_terminal_src)
- encode_terminal_src = xrealloc (encode_terminal_src, required);
- else
- encode_terminal_src = xmalloc (required);
+ encode_terminal_src = xrealloc (encode_terminal_src, required);
encode_terminal_src_size = required;
}
if (src->u.cmp.automatic)
{
gstring = composition_gstring_from_id (src->u.cmp.id);
- required = src->slice.cmp.to + 1 - src->slice.cmp.from;
+ required = src->slice.cmp.to - src->slice.cmp.from + 1;
}
else
{
cmp = composition_table[src->u.cmp.id];
- required = MAX_MULTIBYTE_LENGTH * cmp->glyph_len;
+ required = cmp->glyph_len;
+ required *= MAX_MULTIBYTE_LENGTH;
}
- if (encode_terminal_src_size < nbytes + required)
+ if (encode_terminal_src_size - nbytes < required)
{
- encode_terminal_src_size = nbytes + required;
- encode_terminal_src = xrealloc (encode_terminal_src,
- encode_terminal_src_size);
+ encode_terminal_src =
+ xpalloc (encode_terminal_src, &encode_terminal_src_size,
+ required - (encode_terminal_src_size - nbytes),
+ -1, 1);
buf = encode_terminal_src + nbytes;
}
if (NILP (string))
{
nbytes = buf - encode_terminal_src;
- if (encode_terminal_src_size < nbytes + MAX_MULTIBYTE_LENGTH)
+ if (encode_terminal_src_size - nbytes < MAX_MULTIBYTE_LENGTH)
{
- encode_terminal_src_size = nbytes + MAX_MULTIBYTE_LENGTH;
- encode_terminal_src = xrealloc (encode_terminal_src,
- encode_terminal_src_size);
+ encode_terminal_src =
+ xpalloc (encode_terminal_src, &encode_terminal_src_size,
+ MAX_MULTIBYTE_LENGTH, -1, 1);
buf = encode_terminal_src + nbytes;
}
if (CHAR_BYTE8_P (c)
if (! STRING_MULTIBYTE (string))
string = string_to_multibyte (string);
nbytes = buf - encode_terminal_src;
- if (encode_terminal_src_size < nbytes + SBYTES (string))
+ if (encode_terminal_src_size - nbytes < SBYTES (string))
{
- encode_terminal_src_size = nbytes + SBYTES (string);
- encode_terminal_src = xrealloc (encode_terminal_src,
- encode_terminal_src_size);
+ encode_terminal_src =
+ xpalloc (encode_terminal_src, &encode_terminal_src_size,
+ (SBYTES (string)
+ - (encode_terminal_src_size - nbytes)),
+ -1, 1);
buf = encode_terminal_src + nbytes;
}
memcpy (buf, SDATA (string), SBYTES (string));
coding->source = encode_terminal_src;
if (encode_terminal_dst_size == 0)
{
+ encode_terminal_dst = xrealloc (encode_terminal_dst,
+ encode_terminal_src_size);
encode_terminal_dst_size = encode_terminal_src_size;
- if (encode_terminal_dst)
- encode_terminal_dst = xrealloc (encode_terminal_dst,
- encode_terminal_dst_size);
- else
- encode_terminal_dst = xmalloc (encode_terminal_dst_size);
}
coding->destination = encode_terminal_dst;
coding->dst_bytes = encode_terminal_dst_size;
{
unsigned char *conversion_buffer;
struct coding_system *coding;
+ size_t n, stringlen;
struct tty_display_info *tty = FRAME_TTY (f);
the tail. */
coding->mode &= ~CODING_MODE_LAST_BLOCK;
- while (len > 0)
+ for (stringlen = len; stringlen != 0; stringlen -= n)
{
/* Identify a run of glyphs with the same face. */
int face_id = string->face_id;
- int n;
- for (n = 1; n < len; ++n)
+ for (n = 1; n < stringlen; ++n)
if (string[n].face_id != face_id)
break;
tty_highlight_if_desired (tty);
turn_on_face (f, face_id);
- if (n == len)
+ if (n == stringlen)
/* This is the last run. */
coding->mode |= CODING_MODE_LAST_BLOCK;
conversion_buffer = encode_terminal_code (string, n, coding);
fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
UNBLOCK_INPUT;
}
- len -= n;
string += n;
/* Turn appearance modes off. */
char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
X turns off char_ins_del_ok. */
- max_frame_lines = max (max_frame_lines, FRAME_LINES (frame));
max_frame_cols = max (max_frame_cols, FRAME_COLS (frame));
+ if ((min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) - 1) / 2
+ < max_frame_cols)
+ memory_full (SIZE_MAX);
- if (char_ins_del_vector != 0)
- char_ins_del_vector
- = (int *) xrealloc (char_ins_del_vector,
- (sizeof (int)
- + 2 * max_frame_cols * sizeof (int)));
- else
- char_ins_del_vector
- = (int *) xmalloc (sizeof (int)
- + 2 * max_frame_cols * sizeof (int));
+ char_ins_del_vector =
+ xrealloc (char_ins_del_vector,
+ (sizeof (int) + 2 * sizeof (int) * max_frame_cols));
memset (char_ins_del_vector, 0,
- (sizeof (int) + 2 * max_frame_cols * sizeof (int)));
+ (sizeof (int) + 2 * sizeof (int) * max_frame_cols));
if (f && (!tty->TS_ins_line && !tty->TS_del_line))
Character Display Information
***********************************************************************/
static void append_glyph (struct it *);
-static void produce_stretch_glyph (struct it *);
static void append_composite_glyph (struct it *);
static void produce_composite_glyph (struct it *);
static void append_glyphless_glyph (struct it *, int, const char *);
}
}
+/* For external use. */
+void
+tty_append_glyph (struct it *it)
+{
+ append_glyph (it);
+}
+
+
/* Produce glyphs for the display element described by IT. *IT
specifies what we want to produce a glyph for (character, image, ...),
and where in the glyph matrix we currently are (glyph row and hpos).
/* Nothing but characters are supported on terminal frames. */
xassert (it->what == IT_CHARACTER
|| it->what == IT_COMPOSITION
- || it->what == IT_STRETCH);
+ || it->what == IT_STRETCH
+ || it->what == IT_GLYPHLESS);
if (it->what == IT_STRETCH)
{
it->descent = it->max_descent = it->phys_descent = it->max_phys_descent = 1;
}
-
-/* Produce a stretch glyph for iterator IT. IT->object is the value
- of the glyph property displayed. The value must be a list
- `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
- being recognized:
-
- 1. `:width WIDTH' specifies that the space should be WIDTH *
- canonical char width wide. WIDTH may be an integer or floating
- point number.
-
- 2. `:align-to HPOS' specifies that the space should be wide enough
- to reach HPOS, a value in canonical character units. */
-
-static void
-produce_stretch_glyph (struct it *it)
-{
- /* (space :width WIDTH ...) */
- Lisp_Object prop, plist;
- int width = 0, align_to = -1;
- int zero_width_ok_p = 0;
- double tem;
-
- /* List should start with `space'. */
- xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
- plist = XCDR (it->object);
-
- /* Compute the width of the stretch. */
- if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
- && calc_pixel_width_or_height (&tem, it, prop, 0, 1, 0))
- {
- /* Absolute width `:width WIDTH' specified and valid. */
- zero_width_ok_p = 1;
- width = (int)(tem + 0.5);
- }
- else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
- && calc_pixel_width_or_height (&tem, it, prop, 0, 1, &align_to))
- {
- if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
- align_to = (align_to < 0
- ? 0
- : align_to - window_box_left_offset (it->w, TEXT_AREA));
- else if (align_to < 0)
- align_to = window_box_left_offset (it->w, TEXT_AREA);
- width = max (0, (int)(tem + 0.5) + align_to - it->current_x);
- zero_width_ok_p = 1;
- }
- else
- /* Nothing specified -> width defaults to canonical char width. */
- width = FRAME_COLUMN_WIDTH (it->f);
-
- if (width <= 0 && (width < 0 || !zero_width_ok_p))
- width = 1;
-
- if (width > 0 && it->line_wrap != TRUNCATE
- && it->current_x + width > it->last_visible_x)
- width = it->last_visible_x - it->current_x - 1;
-
- if (width > 0 && it->glyph_row)
- {
- Lisp_Object o_object = it->object;
- Lisp_Object object = it->stack[it->sp - 1].string;
- int n = width;
-
- if (!STRINGP (object))
- object = it->w->buffer;
- it->object = object;
- it->char_to_display = ' ';
- it->pixel_width = it->len = 1;
- while (n--)
- append_glyph (it);
- it->object = o_object;
- }
- it->pixel_width = width;
- it->nglyphs = width;
-}
-
-
/* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
Called from produce_composite_glyph for terminal frames if
IT->glyph_row != NULL. IT->face_id contains the character's
{
if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
+ if (CONSP (acronym))
+ acronym = XCDR (acronym);
buf[0] = '[';
str = STRINGP (acronym) ? SSDATA (acronym) : "";
for (len = 0; len < 6 && str[len] && ASCII_BYTE_P (str[len]); len++)
/* Return the tty display object specified by TERMINAL. */
-struct terminal *
+static struct terminal *
get_tty_terminal (Lisp_Object terminal, int throw)
{
struct terminal *t = get_terminal (terminal, throw);
/* First run `suspend-tty-functions' and then clean up the tty
state because `suspend-tty-functions' might need to change
the tty state. */
- if (!NILP (Vrun_hooks))
- {
- Lisp_Object args[2];
- args[0] = intern ("suspend-tty-functions");
- XSETTERMINAL (args[1], t);
- Frun_hook_with_args (2, args);
- }
+ Lisp_Object args[2];
+ args[0] = intern ("suspend-tty-functions");
+ XSETTERMINAL (args[1], t);
+ Frun_hook_with_args (2, args);
reset_sys_modes (t->display_info.tty);
delete_keyboard_wait_descriptor (fileno (f));
FRAME_SET_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1);
}
+ set_tty_hooks (t);
init_sys_modes (t->display_info.tty);
- /* Run `resume-tty-functions'. */
- if (!NILP (Vrun_hooks))
- {
- Lisp_Object args[2];
- args[0] = intern ("resume-tty-functions");
- XSETTERMINAL (args[1], t);
- Frun_hook_with_args (2, args);
- }
+ {
+ /* Run `resume-tty-functions'. */
+ Lisp_Object args[2];
+ args[0] = intern ("resume-tty-functions");
+ XSETTERMINAL (args[1], t);
+ Frun_hook_with_args (2, args);
+ }
}
set_tty_hooks (t);
***********************************************************************/
#ifdef HAVE_GPM
+
+#ifndef HAVE_WINDOW_SYSTEM
void
term_mouse_moveto (int x, int y)
{
last_mouse_x = x;
last_mouse_y = y; */
}
+#endif /* HAVE_WINDOW_SYSTEM */
/* Implementation of draw_row_with_mouse_face for TTY/GPM. */
void
static void
term_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
enum scroll_bar_part *part, Lisp_Object *x,
- Lisp_Object *y, unsigned long *timeptr)
+ Lisp_Object *y, Time *timeptr)
{
struct timeval now;
+ Time sec, usec;
*fp = SELECTED_FRAME ();
(*fp)->mouse_moved = 0;
XSETINT (*x, last_mouse_x);
XSETINT (*y, last_mouse_y);
gettimeofday(&now, 0);
- *timeptr = (now.tv_sec * 1000) + (now.tv_usec / 1000);
+ sec = now.tv_sec;
+ usec = now.tv_usec;
+ *timeptr = (sec * 1000) + (usec / 1000);
}
/* Prepare a mouse-event in *RESULT for placement in the input queue.
char *area = NULL;
char **address = &area;
int buffer_size = 4096;
- register char *p = NULL;
int status;
struct tty_display_info *tty = NULL;
struct terminal *terminal = NULL;
terminal = create_terminal ();
#ifdef MSDOS
if (been_here > 0)
- maybe_fatal (1, 0, "Attempt to create another terminal %s", "",
+ maybe_fatal (0, 0, "Attempt to create another terminal %s", "",
name, "");
been_here = 1;
tty = &the_only_display_info;
encode_terminal_src_size = 0;
encode_terminal_dst_size = 0;
-#ifdef HAVE_GPM
- terminal->mouse_position_hook = term_mouse_position;
- tty->mouse_highlight.mouse_face_window = Qnil;
-#endif
-
#ifndef DOS_NT
set_tty_hooks (terminal);
if we don't have one at the moment. */
fd = emacs_open (name, O_RDWR | O_IGNORE_CTTY | O_NOCTTY, 0);
else
-#else
+#endif /* O_IGNORE_CTTY */
/* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
defined on Hurd. On other systems, we need to explicitly
dissociate ourselves from the controlling tty when we want to
open a frame on the same terminal. */
fd = emacs_open (name, O_RDWR | O_NOCTTY, 0);
-#endif /* O_IGNORE_CTTY */
tty->name = xstrdup (name);
terminal->name = xstrdup (name);
tty->TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */
#endif /* DOS_NT */
+#ifdef HAVE_GPM
+ terminal->mouse_position_hook = term_mouse_position;
+ tty->mouse_highlight.mouse_face_window = Qnil;
+#endif
+
terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
init_kboard (terminal->kboard);
KVAR (terminal->kboard, Vwindow_system) = Qnil;
Down (tty) = 0;
}
- /* Special handling for certain terminal types known to need it */
-
- if (!strcmp (terminal_type, "supdup"))
- {
- terminal->memory_below_frame = 1;
- tty->Wcm->cm_losewrap = 1;
- }
- if (!strncmp (terminal_type, "c10", 3)
- || !strcmp (terminal_type, "perq"))
- {
- /* Supply a makeshift :wi string.
- This string is not valid in general since it works only
- for windows starting at the upper left corner;
- but that is all Emacs uses.
-
- 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.
-
- It would be simpler if the :wi string could go in the termcap
- entry, but it can't because it is not fully valid.
- If it were in the termcap entry, it would confuse other programs. */
- if (!tty->TS_set_window)
- {
- const char *m = tty->TS_termcap_modes;
- while (*m && strcmp (m, "\033v "))
- m++;
- if (*m)
- tty->TS_set_window = "\033v%C %C %C %C ";
- }
- /* Termcap entry often fails to have :in: flag */
- terminal->must_write_spaces = 1;
- /* :ti string typically fails to have \E^G! in it */
- /* This limits scope of insert-char to one line. */
- strcpy (area, tty->TS_termcap_modes);
- strcat (area, "\033\007!");
- tty->TS_termcap_modes = area;
- area += strlen (area) + 1;
- p = AbsPosition (tty);
- /* Change all %+ parameters to %C, to handle
- values above 96 correctly for the C100. */
- while (*p)
- {
- if (p[0] == '%' && p[1] == '+')
- p[1] = 'C';
- p++;
- }
- }
-
tty->specified_window = FrameRows (tty);
if (Wcm_init (tty) == -1) /* can't do cursor motion */
vfprintf (stderr, str, ap);
if (!(strlen (str) > 0 && str[strlen (str) - 1] == '\n'))
fprintf (stderr, "\n");
- va_end (ap);
fflush (stderr);
exit (1);
}
/* Auxiliary error-handling function for init_tty.
Delete TERMINAL, then call error or fatal with str1 or str2,
- respectively, according to MUST_SUCCEED. */
+ respectively, according to whether MUST_SUCCEED is zero or not. */
static void
maybe_fatal (int must_succeed, struct terminal *terminal,