merge trunk
[bpt/emacs.git] / src / term.c
index 3a41552..23e0742 100644 (file)
@@ -21,9 +21,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include <stdio.h>
-#include <ctype.h>
 #include <errno.h>
 #include <sys/file.h>
+#include <sys/time.h>
 #include <unistd.h>
 #include <signal.h>
 #include <setjmp.h>
@@ -85,11 +85,11 @@ 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 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);
+static _Noreturn void maybe_fatal (int must_succeed, struct terminal *terminal,
+                                  const char *str1, const char *str2, ...)
+  ATTRIBUTE_FORMAT_PRINTF (3, 5) ATTRIBUTE_FORMAT_PRINTF (4, 5);
+static _Noreturn void vfatal (const char *str, va_list ap)
+  ATTRIBUTE_FORMAT_PRINTF (1, 0);
 
 
 #define OUTPUT(tty, a)                                          \
@@ -1332,7 +1332,7 @@ term_get_fkeys_1 (void)
 
   /* This can happen if CANNOT_DUMP or with strange options.  */
   if (!KEYMAPP (KVAR (kboard, Vinput_decode_map)))
-    KVAR (kboard, Vinput_decode_map) = Fmake_sparse_keymap (Qnil);
+    kset_input_decode_map (kboard, Fmake_sparse_keymap (Qnil));
 
   for (i = 0; i < (sizeof (keys)/sizeof (keys[0])); i++)
     {
@@ -1458,7 +1458,7 @@ append_glyph (struct it *it)
   struct glyph *glyph, *end;
   int i;
 
-  xassert (it->glyph_row);
+  eassert (it->glyph_row);
   glyph = (it->glyph_row->glyphs[it->area]
           + it->glyph_row->used[it->area]);
   end = it->glyph_row->glyphs[1 + it->area];
@@ -1545,7 +1545,7 @@ produce_glyphs (struct it *it)
   /* If a hook is installed, let it do the work.  */
 
   /* Nothing but characters are supported on terminal frames.  */
-  xassert (it->what == IT_CHARACTER
+  eassert (it->what == IT_CHARACTER
           || it->what == IT_COMPOSITION
           || it->what == IT_STRETCH
           || it->what == IT_GLYPHLESS);
@@ -1632,7 +1632,7 @@ produce_glyphs (struct it *it)
        {
          Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
 
-         xassert (it->what == IT_GLYPHLESS);
+         eassert (it->what == IT_GLYPHLESS);
          produce_glyphless_glyph (it, 1, acronym);
        }
     }
@@ -1656,7 +1656,7 @@ append_composite_glyph (struct it *it)
 {
   struct glyph *glyph;
 
-  xassert (it->glyph_row);
+  eassert (it->glyph_row);
   glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area];
   if (glyph < it->glyph_row->glyphs[1 + it->area])
     {
@@ -1748,7 +1748,7 @@ append_glyphless_glyph (struct it *it, int face_id, const char *str)
   struct glyph *glyph, *end;
   int i;
 
-  xassert (it->glyph_row);
+  eassert (it->glyph_row);
   glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area];
   end = it->glyph_row->glyphs[1 + it->area];
 
@@ -1850,8 +1850,7 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
        len = 1;
       else if (len > 4)
        len = 4;
-      sprintf (buf, "[%.*s]", len, str);
-      len += 2;
+      len = sprintf (buf, "[%.*s]", len, str);
       str = buf;
     }
   else
@@ -1871,7 +1870,7 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
        }
       else
        {
-         xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
+         eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
          len = (it->c < 0x10000 ? sprintf (buf, "\\u%04X", it->c)
                 : it->c <= MAX_UNICODE_CHAR ? sprintf (buf, "\\U%06X", it->c)
                 : sprintf (buf, "\\x%06X", it->c));
@@ -1885,67 +1884,6 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
     append_glyphless_glyph (it, face_id, str);
 }
 
-
-/* Get information about special display element WHAT in an
-   environment described by IT.  WHAT is one of IT_TRUNCATION or
-   IT_CONTINUATION.  Maybe produce glyphs for WHAT if IT has a
-   non-null glyph_row member.  This function ensures that fields like
-   face_id, c, len of IT are left untouched.  */
-
-void
-produce_special_glyphs (struct it *it, enum display_element_type what)
-{
-  struct it temp_it;
-  Lisp_Object gc;
-  GLYPH glyph;
-
-  temp_it = *it;
-  temp_it.dp = NULL;
-  temp_it.what = IT_CHARACTER;
-  temp_it.len = 1;
-  temp_it.object = make_number (0);
-  memset (&temp_it.current, 0, sizeof temp_it.current);
-
-  if (what == IT_CONTINUATION)
-    {
-      /* Continuation glyph.  For R2L lines, we mirror it by hand.  */
-      if (it->bidi_it.paragraph_dir == R2L)
-       SET_GLYPH_FROM_CHAR (glyph, '/');
-      else
-       SET_GLYPH_FROM_CHAR (glyph, '\\');
-      if (it->dp
-         && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
-       {
-         /* FIXME: Should we mirror GC for R2L lines?  */
-         SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
-         spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
-       }
-    }
-  else if (what == IT_TRUNCATION)
-    {
-      /* Truncation glyph.  */
-      SET_GLYPH_FROM_CHAR (glyph, '$');
-      if (it->dp
-         && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
-       {
-         /* FIXME: Should we mirror GC for R2L lines?  */
-         SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
-         spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
-       }
-    }
-  else
-    abort ();
-
-  temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
-  temp_it.face_id = GLYPH_FACE (glyph);
-  temp_it.len = CHAR_BYTES (temp_it.c);
-
-  produce_glyphs (&temp_it);
-  it->pixel_width = temp_it.pixel_width;
-  it->nglyphs = temp_it.pixel_width;
-}
-
-
 \f
 /***********************************************************************
                                Faces
@@ -2067,7 +2005,7 @@ turn_off_face (struct frame *f, int face_id)
   struct face *face = FACE_FROM_ID (f, face_id);
   struct tty_display_info *tty = FRAME_TTY (f);
 
-  xassert (face != NULL);
+  eassert (face != NULL);
 
   if (tty->TS_exit_attribute_mode)
     {
@@ -2132,7 +2070,7 @@ DEFUN ("tty-display-color-p", Ftty_display_color_p, Stty_display_color_p,
 
 TERMINAL can be a terminal object, a frame, or nil (meaning the
 selected frame's terminal).  This function always returns nil if
-TERMINAL does not refer to a text-only terminal.  */)
+TERMINAL does not refer to a text terminal.  */)
   (Lisp_Object terminal)
 {
   struct terminal *t = get_tty_terminal (terminal, 0);
@@ -2149,7 +2087,7 @@ DEFUN ("tty-display-color-cells", Ftty_display_color_cells,
 
 TERMINAL can be a terminal object, a frame, or nil (meaning the
 selected frame's terminal).  This function always returns 0 if
-TERMINAL does not refer to a text-only terminal.  */)
+TERMINAL does not refer to a text terminal.  */)
   (Lisp_Object terminal)
 {
   struct terminal *t = get_tty_terminal (terminal, 0);
@@ -2270,11 +2208,10 @@ set_tty_color_mode (struct tty_display_info *tty, struct frame *f)
 
   if (mode != tty->previous_color_mode)
     {
-      Lisp_Object funsym = intern ("tty-set-up-initial-frame-faces");
       tty->previous_color_mode = mode;
       tty_setup_colors (tty , mode);
       /*  This recomputes all the faces given the new color definitions.  */
-      safe_call (1, &funsym);
+      safe_call (1, intern ("tty-set-up-initial-frame-faces"));
     }
 }
 
@@ -2371,7 +2308,7 @@ no effect if used on a non-tty terminal.
 
 TERMINAL can be a terminal object, a frame or nil (meaning the
 selected frame's terminal).  This function always returns nil if
-TERMINAL does not refer to a text-only terminal.  */)
+TERMINAL does not refer to a text terminal.  */)
   (Lisp_Object terminal)
 {
   struct terminal *t = get_terminal (terminal, 1);
@@ -2381,6 +2318,21 @@ TERMINAL does not refer to a text-only terminal.  */)
   return Qnil;
 }
 
+DEFUN ("tty-top-frame", Ftty_top_frame, Stty_top_frame, 0, 1, 0,
+       doc: /* Return the topmost terminal frame on TERMINAL.
+TERMINAL can be a terminal object, a frame or nil (meaning the
+selected frame's terminal).  This function returns nil if TERMINAL
+does not refer to a text terminal.  Otherwise, it returns the
+top-most frame on the text terminal.  */)
+  (Lisp_Object terminal)
+{
+  struct terminal *t = get_terminal (terminal, 1);
+
+  if (t->type == output_termcap)
+    return t->display_info.tty->top_frame;
+  return Qnil;
+}
+
 \f
 
 DEFUN ("suspend-tty", Fsuspend_tty, Ssuspend_tty, 0, 1, 0,
@@ -2596,6 +2548,18 @@ term_mouse_movement (FRAME_PTR frame, Gpm_Event *event)
   return 0;
 }
 
+/* Return the Time that corresponds to T.  Wrap around on overflow.  */
+static Time
+timeval_to_Time (struct timeval const *t)
+{
+  Time s_1000, ms;
+
+  s_1000 = t->tv_sec;
+  s_1000 *= 1000;
+  ms = t->tv_usec / 1000;
+  return s_1000 + ms;
+}
+
 /* Return the current position of the mouse.
 
    Set *f to the frame the mouse is in, or zero if the mouse is in no
@@ -2615,7 +2579,6 @@ term_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
                     Lisp_Object *y, Time *timeptr)
 {
   struct timeval now;
-  Time sec, usec;
 
   *fp = SELECTED_FRAME ();
   (*fp)->mouse_moved = 0;
@@ -2626,9 +2589,7 @@ term_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
   XSETINT (*x, last_mouse_x);
   XSETINT (*y, last_mouse_y);
   gettimeofday(&now, 0);
-  sec = now.tv_sec;
-  usec = now.tv_usec;
-  *timeptr = (sec * 1000) + (usec / 1000);
+  *timeptr = timeval_to_Time (&now);
 }
 
 /* Prepare a mouse-event in *RESULT for placement in the input queue.
@@ -2652,7 +2613,7 @@ term_mouse_click (struct input_event *result, Gpm_Event *event,
       }
     }
   gettimeofday(&now, 0);
-  result->timestamp = (now.tv_sec * 1000) + (now.tv_usec / 1000);
+  result->timestamp = timeval_to_Time (&now);
 
   if (event->type & GPM_UP)
     result->modifiers = up_modifier;
@@ -2834,14 +2795,11 @@ DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop, Sgpm_mouse_stop,
 void
 create_tty_output (struct frame *f)
 {
-  struct tty_output *t;
+  struct tty_output *t = xzalloc (sizeof *t);
 
   if (! FRAME_TERMCAP_P (f))
     abort ();
 
-  t = xmalloc (sizeof (struct tty_output));
-  memset (t, 0, sizeof (struct tty_output));
-
   t->display_info = FRAME_TERMINAL (f)->display_info.tty;
 
   f->output_data.tty = t;
@@ -3041,9 +2999,8 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
   been_here = 1;
   tty = &the_only_display_info;
 #else
-  tty = (struct tty_display_info *) xmalloc (sizeof (struct tty_display_info));
+  tty = xzalloc (sizeof *tty);
 #endif
-  memset (tty, 0, sizeof (struct tty_display_info));
   tty->next = tty_list;
   tty_list = tty;
 
@@ -3051,7 +3008,7 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
   terminal->display_info.tty = tty;
   tty->terminal = terminal;
 
-  tty->Wcm = (struct cm *) xmalloc (sizeof (struct cm));
+  tty->Wcm = xmalloc (sizeof *tty->Wcm);
   Wcm_clear (tty);
 
   encode_terminal_src_size = 0;
@@ -3112,7 +3069,7 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
 
   Wcm_clear (tty);
 
-  tty->termcap_term_buffer = (char *) xmalloc (buffer_size);
+  tty->termcap_term_buffer = xmalloc (buffer_size);
 
   /* On some systems, tgetent tries to access the controlling
      terminal. */
@@ -3153,7 +3110,7 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
     abort ();
   buffer_size = strlen (tty->termcap_term_buffer);
 #endif
-  tty->termcap_strings_buffer = area = (char *) xmalloc (buffer_size);
+  tty->termcap_strings_buffer = area = xmalloc (buffer_size);
   tty->TS_ins_line = tgetstr ("al", address);
   tty->TS_ins_multi_lines = tgetstr ("AL", address);
   tty->TS_bell = tgetstr ("bl", address);
@@ -3321,9 +3278,9 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
   tty->mouse_highlight.mouse_face_window = Qnil;
 #endif
 
-  terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
+  terminal->kboard = xmalloc (sizeof *terminal->kboard);
   init_kboard (terminal->kboard);
-  KVAR (terminal->kboard, Vwindow_system) = Qnil;
+  kset_window_system (terminal->kboard, Qnil);
   terminal->kboard->next_kboard = all_kboards;
   all_kboards = terminal->kboard;
   terminal->kboard->reference_count++;
@@ -3581,7 +3538,6 @@ delete_tty (struct terminal *terminal)
   xfree (tty->termcap_strings_buffer);
   xfree (tty->termcap_term_buffer);
 
-  memset (tty, 0, sizeof (struct tty_display_info));
   xfree (tty);
 }
 
@@ -3614,14 +3570,14 @@ This variable can be used by terminal emulator packages.  */);
 #endif
 
   DEFVAR_LISP ("suspend-tty-functions", Vsuspend_tty_functions,
-    doc: /* Functions to be run after suspending a tty.
+    doc: /* Functions run after suspending a tty.
 The functions are run with one argument, the terminal object to be suspended.
 See `suspend-tty'.  */);
   Vsuspend_tty_functions = Qnil;
 
 
   DEFVAR_LISP ("resume-tty-functions", Vresume_tty_functions,
-    doc: /* Functions to be run after resuming a tty.
+    doc: /* Functions run after resuming a tty.
 The functions are run with one argument, the terminal object that was revived.
 See `resume-tty'.  */);
   Vresume_tty_functions = Qnil;
@@ -3638,6 +3594,7 @@ bigger, or it may make it blink, or it may do nothing at all.  */);
   defsubr (&Stty_no_underline);
   defsubr (&Stty_type);
   defsubr (&Scontrolling_tty_p);
+  defsubr (&Stty_top_frame);
   defsubr (&Ssuspend_tty);
   defsubr (&Sresume_tty);
 #ifdef HAVE_GPM