Merge from emacs-24; up to 2012-12-06T01:39:03Z!monnier@iro.umontreal.ca
[bpt/emacs.git] / src / term.c
index c5cec30..d76562b 100644 (file)
@@ -1,6 +1,6 @@
 /* Terminal control module for terminals described by TERMCAP
-   Copyright (C) 1985-1987, 1993-1995, 1998, 2000-2012
-                 Free Software Foundation, Inc.
+   Copyright (C) 1985-1987, 1993-1995, 1998, 2000-2013 Free Software
+   Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -20,17 +20,15 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 /* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>.  */
 
 #include <config.h>
-#include <stdio.h>
 #include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
 #include <sys/file.h>
 #include <sys/time.h>
 #include <unistd.h>
-#include <signal.h>
-#include <setjmp.h>
 
 #include "lisp.h"
 #include "termchar.h"
-#include "termopts.h"
 #include "tparam.h"
 #include "character.h"
 #include "buffer.h"
@@ -58,17 +56,10 @@ static int been_here = -1;
 #include "xterm.h"
 #endif
 
-#ifndef O_RDWR
-#define O_RDWR 2
-#endif
-
-#ifndef O_NOCTTY
-#define O_NOCTTY 0
-#endif
-
 /* The name of the default console device.  */
 #ifdef WINDOWSNT
 #define DEV_TTY  "CONOUT$"
+#include "w32term.h"
 #else
 #define DEV_TTY  "/dev/tty"
 #endif
@@ -135,10 +126,6 @@ enum no_color_bit
 
 static int max_frame_cols;
 
-/* Non-zero if we have dropped our controlling tty and therefore
-   should not open a frame on stdout. */
-static int no_controlling_tty;
-
 \f
 
 #ifdef HAVE_GPM
@@ -755,13 +742,13 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
       conversion_buffer = encode_terminal_code (string, n, coding);
       if (coding->produced > 0)
        {
-         BLOCK_INPUT;
+         block_input ();
          fwrite (conversion_buffer, 1, coding->produced, tty->output);
          if (ferror (tty->output))
            clearerr (tty->output);
          if (tty->termscript)
            fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
-         UNBLOCK_INPUT;
+         unblock_input ();
        }
       string += n;
 
@@ -816,13 +803,13 @@ tty_write_glyphs_with_face (register struct frame *f, register struct glyph *str
   conversion_buffer = encode_terminal_code (string, len, coding);
   if (coding->produced > 0)
     {
-      BLOCK_INPUT;
+      block_input ();
       fwrite (conversion_buffer, 1, coding->produced, tty->output);
       if (ferror (tty->output))
        clearerr (tty->output);
       if (tty->termscript)
        fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
-      UNBLOCK_INPUT;
+      unblock_input ();
     }
 
   /* Turn appearance modes off.  */
@@ -902,13 +889,13 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
 
       if (coding->produced > 0)
        {
-         BLOCK_INPUT;
+         block_input ();
          fwrite (conversion_buffer, 1, coding->produced, tty->output);
          if (ferror (tty->output))
            clearerr (tty->output);
          if (tty->termscript)
            fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
-         UNBLOCK_INPUT;
+         unblock_input ();
        }
 
       OUTPUT1_IF (tty, tty->TS_pad_inserted_char);
@@ -966,8 +953,8 @@ tty_ins_del_lines (struct frame *f, int vpos, int n)
   const char *single = n > 0 ? tty->TS_ins_line : tty->TS_del_line;
   const char *scroll = n > 0 ? tty->TS_rev_scroll : tty->TS_fwd_scroll;
 
-  register int i = n > 0 ? n : -n;
-  register char *buf;
+  int i = eabs (n);
+  char *buf;
 
   /* If the lines below the insertion are being pushed
      into the end of the window, this is the same as clearing;
@@ -1332,7 +1319,7 @@ term_get_fkeys_1 (void)
 
   /* This can happen if CANNOT_DUMP or with strange options.  */
   if (!KEYMAPP (KVAR (kboard, Vinput_decode_map)))
-    KSET (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++)
     {
@@ -1498,7 +1485,7 @@ append_glyph (struct it *it)
        {
          glyph->resolved_level = it->bidi_it.resolved_level;
          if ((it->bidi_it.type & 7) != it->bidi_it.type)
-           abort ();
+           emacs_abort ();
          glyph->bidi_type = it->bidi_it.type;
        }
       else
@@ -1695,7 +1682,7 @@ append_composite_glyph (struct it *it)
        {
          glyph->resolved_level = it->bidi_it.resolved_level;
          if ((it->bidi_it.type & 7) != it->bidi_it.type)
-           abort ();
+           emacs_abort ();
          glyph->bidi_type = it->bidi_it.type;
        }
       else
@@ -1780,7 +1767,7 @@ append_glyphless_glyph (struct it *it, int face_id, const char *str)
     {
       glyph->resolved_level = it->bidi_it.resolved_level;
       if ((it->bidi_it.type & 7) != it->bidi_it.type)
-       abort ();
+       emacs_abort ();
       glyph->bidi_type = it->bidi_it.type;
     }
   else
@@ -2250,7 +2237,7 @@ get_named_tty (const char *name)
   struct terminal *t;
 
   if (!name)
-    abort ();
+    emacs_abort ();
 
   for (t = terminal_list; t; t = t->next_terminal)
     {
@@ -2798,7 +2785,7 @@ create_tty_output (struct frame *f)
   struct tty_output *t = xzalloc (sizeof *t);
 
   if (! FRAME_TERMCAP_P (f))
-    abort ();
+    emacs_abort ();
 
   t->display_info = FRAME_TERMINAL (f)->display_info.tty;
 
@@ -2811,7 +2798,7 @@ static void
 tty_free_frame_resources (struct frame *f)
 {
   if (! FRAME_TERMCAP_P (f))
-    abort ();
+    emacs_abort ();
 
   if (FRAME_FACE_CACHE (f))
     free_frame_faces (f);
@@ -2827,7 +2814,7 @@ static void
 tty_free_frame_resources (struct frame *f)
 {
   if (! FRAME_TERMCAP_P (f) && ! FRAME_MSDOS_P (f))
-    abort ();
+    emacs_abort ();
 
   if (FRAME_FACE_CACHE (f))
     free_frame_faces (f);
@@ -2920,34 +2907,9 @@ set_tty_hooks (struct terminal *terminal)
 static void
 dissociate_if_controlling_tty (int fd)
 {
-#ifndef DOS_NT
-  int pgid = tcgetpgrp (fd); /* If tcgetpgrp succeeds, fd is the ctty. */
-  if (pgid != -1)
-    {
-#if defined (USG5)
-      setpgrp ();
-      no_controlling_tty = 1;
-#elif defined (CYGWIN)
-      setsid ();
-      no_controlling_tty = 1;
-#else
-#ifdef TIOCNOTTY                /* Try BSD ioctls. */
-      sigblock (sigmask (SIGTTOU));
-      fd = emacs_open (DEV_TTY, O_RDWR, 0);
-      if (fd != -1 && ioctl (fd, TIOCNOTTY, 0) != -1)
-        {
-          no_controlling_tty = 1;
-        }
-      if (fd != -1)
-        emacs_close (fd);
-      sigunblock (sigmask (SIGTTOU));
-#else
-      /* Unknown system. */
-      croak ();
-#endif  /* ! TIOCNOTTY */
-#endif  /* ! USG */
-    }
-#endif /* !DOS_NT */
+  pid_t pgid = tcgetpgrp (fd); /* If tcgetpgrp succeeds, fd is the ctty. */
+  if (0 <= pgid)
+    setsid ();
 }
 
 /* Create a termcap display on the tty device with the given name and
@@ -3001,6 +2963,7 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
 #else
   tty = xzalloc (sizeof *tty);
 #endif
+  tty->top_frame = Qnil;
   tty->next = tty_list;
   tty_list = tty;
 
@@ -3019,22 +2982,18 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
   set_tty_hooks (terminal);
 
   {
-    int fd;
+    /* Open the terminal device.  */
     FILE *file;
 
-#ifdef O_IGNORE_CTTY
-    if (!ctty)
-      /* Open the terminal device.  Don't recognize it as our
-         controlling terminal, and don't make it the controlling tty
-         if we don't have one at the moment.  */
-      fd = emacs_open (name, O_RDWR | O_IGNORE_CTTY | O_NOCTTY, 0);
-    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);
+    /* If !ctty, don't recognize it as our controlling terminal, and
+       don't make it the controlling tty if we don't have one now.
+
+       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.  */
+    int flags = O_RDWR | O_NOCTTY | (ctty ? 0 : O_IGNORE_CTTY);
+    int fd = emacs_open (name, flags, 0);
 
     tty->name = xstrdup (name);
     terminal->name = xstrdup (name);
@@ -3053,10 +3012,8 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
                      name);
       }
 
-#ifndef O_IGNORE_CTTY
-    if (!ctty)
+    if (!O_IGNORE_CTTY && !ctty)
       dissociate_if_controlling_tty (fd);
-#endif
 
     file = fdopen (fd, "w+");
     tty->input = file;
@@ -3073,9 +3030,14 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
 
   /* On some systems, tgetent tries to access the controlling
      terminal. */
-  sigblock (sigmask (SIGTTOU));
-  status = tgetent (tty->termcap_term_buffer, terminal_type);
-  sigunblock (sigmask (SIGTTOU));
+  {
+    sigset_t blocked;
+    sigemptyset (&blocked);
+    sigaddset (&blocked, SIGTTOU);
+    pthread_sigmask (SIG_BLOCK, &blocked, 0);
+    status = tgetent (tty->termcap_term_buffer, terminal_type);
+    pthread_sigmask (SIG_UNBLOCK, &blocked, 0);
+  }
 
   if (status < 0)
     {
@@ -3107,7 +3069,7 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
 
 #ifndef TERMINFO
   if (strlen (tty->termcap_term_buffer) >= buffer_size)
-    abort ();
+    emacs_abort ();
   buffer_size = strlen (tty->termcap_term_buffer);
 #endif
   tty->termcap_strings_buffer = area = xmalloc (buffer_size);
@@ -3229,7 +3191,6 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
     FrameCols (tty) = FRAME_COLS (f);
     tty->specified_window = FRAME_LINES (f);
 
-    FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
     FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
     terminal->char_ins_del_ok = 1;
     baud_rate = 19200;
@@ -3280,7 +3241,7 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
 
   terminal->kboard = xmalloc (sizeof *terminal->kboard);
   init_kboard (terminal->kboard);
-  KSET (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++;
@@ -3401,10 +3362,6 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
     = tty->TS_delete_mode && tty->TS_insert_mode
     && !strcmp (tty->TS_delete_mode, tty->TS_insert_mode);
 
-  tty->se_is_so = (tty->TS_standout_mode
-              && tty->TS_end_standout_mode
-              && !strcmp (tty->TS_standout_mode, tty->TS_end_standout_mode));
-
   UseTabs (tty) = tabs_safe_p (fileno (tty->input)) && TabWidth (tty) == 8;
 
   terminal->scroll_region_ok
@@ -3466,7 +3423,7 @@ maybe_fatal (int must_succeed, struct terminal *terminal,
     verror (str1, ap);
 
   va_end (ap);
-  abort ();
+  emacs_abort ();
 }
 
 void
@@ -3493,7 +3450,7 @@ delete_tty (struct terminal *terminal)
     return;
 
   if (terminal->type != output_termcap)
-    abort ();
+    emacs_abort ();
 
   tty = terminal->display_info.tty;
 
@@ -3507,7 +3464,7 @@ delete_tty (struct terminal *terminal)
 
       if (! p)
         /* This should not happen. */
-        abort ();
+        emacs_abort ();
 
       p->next = tty->next;
       tty->next = 0;
@@ -3541,22 +3498,6 @@ delete_tty (struct terminal *terminal)
   xfree (tty);
 }
 
-\f
-
-/* Mark the pointers in the tty_display_info objects.
-   Called by Fgarbage_collect.  */
-
-void
-mark_ttys (void)
-{
-  struct tty_display_info *tty;
-
-  for (tty = tty_list; tty; tty = tty->next)
-    mark_object (tty->top_frame);
-}
-
-\f
-
 void
 syms_of_term (void)
 {