Merge from emacs-24; up to 2014-04-22T20:19:17Z!eggert@cs.ucla.edu
[bpt/emacs.git] / src / term.c
index 4d8da13..6ea9a4e 100644 (file)
@@ -131,6 +131,9 @@ enum no_color_bit
 
 static int max_frame_cols;
 
+static Lisp_Object Qtty_mode_set_strings;
+static Lisp_Object Qtty_mode_reset_strings;
+
 \f
 
 #ifdef HAVE_GPM
@@ -161,6 +164,28 @@ tty_ring_bell (struct frame *f)
 
 /* Set up termcap modes for Emacs. */
 
+static void
+tty_send_additional_strings (struct terminal *terminal, Lisp_Object sym)
+{
+  Lisp_Object lisp_terminal;
+  Lisp_Object extra_codes;
+  struct tty_display_info *tty = terminal->display_info.tty;
+
+  XSETTERMINAL (lisp_terminal, terminal);
+  for (extra_codes = Fterminal_parameter (lisp_terminal, sym);
+       CONSP (extra_codes);
+       extra_codes = XCDR (extra_codes))
+    {
+      Lisp_Object string = XCAR (extra_codes);
+      if (STRINGP (string))
+        {
+          fwrite (SDATA (string), 1, SBYTES (string), tty->output);
+          if (tty->termscript)
+            fwrite (SDATA (string), 1, SBYTES (string), tty->termscript);
+        }
+    }
+}
+
 static void
 tty_set_terminal_modes (struct terminal *terminal)
 {
@@ -183,6 +208,7 @@ tty_set_terminal_modes (struct terminal *terminal)
       OUTPUT_IF (tty, visible_cursor ? tty->TS_cursor_visible : tty->TS_cursor_normal);
       OUTPUT_IF (tty, tty->TS_keypad_mode);
       losecursor (tty);
+      tty_send_additional_strings (terminal, Qtty_mode_set_strings);
       fflush (tty->output);
     }
 }
@@ -196,6 +222,7 @@ tty_reset_terminal_modes (struct terminal *terminal)
 
   if (tty->output)
     {
+      tty_send_additional_strings (terminal, Qtty_mode_reset_strings);
       tty_turn_off_highlight (tty);
       tty_turn_off_insert (tty);
       OUTPUT_IF (tty, tty->TS_end_keypad_mode);
@@ -500,7 +527,7 @@ static ptrdiff_t encode_terminal_dst_size;
    Set CODING->produced to the byte-length of the resulting byte
    sequence, and return a pointer to that byte sequence.  */
 
-#ifndef WINDOWSNT
+#ifndef DOS_NT
 static
 #endif
 unsigned char *
@@ -1339,7 +1366,7 @@ term_get_fkeys_1 (void)
   if (!KEYMAPP (KVAR (kboard, Vinput_decode_map)))
     kset_input_decode_map (kboard, Fmake_sparse_keymap (Qnil));
 
-  for (i = 0; i < (sizeof (keys) / sizeof (keys[0])); i++)
+  for (i = 0; i < ARRAYELTS (keys); i++)
     {
       char *sequence = tgetstr (keys[i].cap, address);
       if (sequence)
@@ -2052,17 +2079,9 @@ tty_default_color_capabilities (struct tty_display_info *tty, bool save)
 
   if (save)
     {
-      xfree (default_orig_pair);
-      default_orig_pair = tty->TS_orig_pair ? xstrdup (tty->TS_orig_pair) : NULL;
-
-      xfree (default_set_foreground);
-      default_set_foreground = tty->TS_set_foreground ? xstrdup (tty->TS_set_foreground)
-                              : NULL;
-
-      xfree (default_set_background);
-      default_set_background = tty->TS_set_background ? xstrdup (tty->TS_set_background)
-                              : NULL;
-
+      dupstring (&default_orig_pair, tty->TS_orig_pair);
+      dupstring (&default_set_foreground, tty->TS_set_foreground);
+      dupstring (&default_set_background, tty->TS_set_background);
       default_max_colors = tty->TN_max_colors;
       default_max_pairs = tty->TN_max_pairs;
       default_no_color_video = tty->TN_no_color_video;
@@ -3062,7 +3081,7 @@ free_saved_screen (struct glyph_matrix *saved)
   int i;
 
   if (!saved)
-    return;    /* already freed */
+    return;    /* Already freed!  */
 
   for (i = 0; i < saved->nrows; ++i)
     {
@@ -3124,7 +3143,11 @@ read_menu_input (struct frame *sf, int *x, int *y, int min_y, int max_y,
       tty->showing_menu = 0;
       do_mouse_tracking = saved_mouse_tracking;
 
-      if (EQ (cmd, Qt) || EQ (cmd, Qtty_menu_exit))
+      if (EQ (cmd, Qt) || EQ (cmd, Qtty_menu_exit)
+         /* If some input switched frames under our feet, exit the
+            menu, since the menu faces are no longer valid, and the
+            menu is no longer relevant anyway.  */
+         || sf != SELECTED_FRAME ())
        return MI_QUIT_MENU;
       if (EQ (cmd, Qtty_menu_mouse_movement))
        mouse_get_xy (x, y);
@@ -3174,7 +3197,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
   int statecount, x, y, i;
   bool leave, onepane;
   int result IF_LINT (= 0);
-  int title_faces[4];          /* face to display the menu title */
+  int title_faces[4];          /* Face to display the menu title.  */
   int faces[4], buffers_num_deleted = 0;
   struct frame *sf = SELECTED_FRAME ();
   struct tty_display_info *tty = FRAME_TTY (sf);
@@ -3336,7 +3359,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
                       have been opened.  That does not include an open and
                       active submenu.  */
                    if (i != statecount - 2
-                       || state[i].menu->submenu[dy] != state[i+1].menu)
+                       || state[i].menu->submenu[dy] != state[i + 1].menu)
                      while (i != statecount - 1)
                        {
                          statecount--;
@@ -3387,7 +3410,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
   screen_update (sf, state[0].screen_behind);
   while (statecount--)
     free_saved_screen (state[statecount].screen_behind);
-  tty_show_cursor (tty);       /* turn cursor back on */
+  tty_show_cursor (tty);       /* Turn cursor back on.  */
   fflush (tty->output);
 
 /* Clean up any mouse events that are waiting inside Emacs event queue.
@@ -3478,7 +3501,7 @@ tty_menu_last_menubar_item (struct frame *f)
            break;
          i += 4;
        }
-      i -= 4;  /* went one too far */
+      i -= 4;  /* Went one too far!  */
     }
   return i;
 }
@@ -3523,7 +3546,7 @@ tty_menu_new_item_coords (struct frame *f, int which, int *x, int *y)
                  if (i < last_i)
                    *x = XINT (AREF (items, i + 4 + 3));
                  else
-                   *x = 0;     /* wrap around to the first item */
+                   *x = 0;     /* Wrap around to the first item.  */
                }
              else if (prev_x < 0)
                {
@@ -3651,7 +3674,7 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
 
          if (!NILP (descrip))
            {
-             /* if alloca is fast, use that to make the space,
+             /* If alloca is fast, use that to make the space,
                 to reduce gc needs.  */
              item_data = (char *) alloca (maxwidth + SBYTES (descrip) + 1);
              memcpy (item_data, SSDATA (item_name), SBYTES (item_name));
@@ -3698,7 +3721,7 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
       uly = dispheight - height;
     }
 
-  if (FRAME_HAS_MINIBUF_P (f) && uly+height > dispheight - 2)
+  if (FRAME_HAS_MINIBUF_P (f) && uly + height > dispheight - 2)
     {
       /* Move the menu away of the echo area, to avoid overwriting the
         menu with help echo messages or vice versa.  */
@@ -3727,8 +3750,8 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
       /* If position was not given by a mouse click, adjust so upper left
          corner of the menu as a whole ends up at given coordinates.  This
          is what x-popup-menu says in its documentation.  */
-      x += width/2;
-      y += 1.5*height/(maxlines+2);
+      x += width / 2;
+      y += 1.5 * height / (maxlines + 2);
     }
 #endif
 
@@ -3791,6 +3814,11 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
     case TTYM_IA_SELECT:
       break;
     case TTYM_NO_SELECT:
+      /* If the selected frame was changed while we displayed a menu,
+        throw to top level in order to undo any temporary settings
+        made by TTY menu code.  */
+      if (f != SELECTED_FRAME ())
+       Ftop_level ();
       /* Make "Cancel" equivalent to C-g unless FOR_CLICK (which means
         the menu was invoked with a mouse event as POSITION).  */
       if (! for_click)
@@ -3943,9 +3971,10 @@ dissociate_if_controlling_tty (int fd)
       /* setsid failed, presumably because Emacs is already a process
         group leader.  Fall back on the obsolescent way to dissociate
         a controlling tty.  */
-      block_tty_out_signal ();
+      sigset_t oldset;
+      block_tty_out_signal (&oldset);
       ioctl (fd, TIOCNOTTY, 0);
-      unblock_tty_out_signal ();
+      unblock_tty_out_signal (&oldset);
 #endif
     }
 }
@@ -3969,6 +3998,7 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed)
   int status;
   struct tty_display_info *tty = NULL;
   struct terminal *terminal = NULL;
+  sigset_t oldset;
   bool ctty = false;  /* True if asked to open controlling tty.  */
 
   if (!terminal_type)
@@ -4030,12 +4060,15 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed)
        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->input = tty->output = fd < 0 || ! isatty (fd) ? 0 : fdopen (fd, "w+");
+    tty->input = tty->output =
+      ((fd < 0 || ! isatty (fd))
+       ? NULL
+       : fdopen (fd, "w+"));
 
     if (! tty->input)
       {
        char const *diagnostic
-         = tty->input ? "Not a tty device: %s" : "Could not open file: %s";
+         = (fd < 0) ? "Could not open file: %s" : "Not a tty device: %s";
        emacs_close (fd);
        maybe_fatal (must_succeed, terminal, diagnostic, diagnostic, name);
       }
@@ -4055,11 +4088,11 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed)
 
   /* On some systems, tgetent tries to access the controlling
      terminal.  */
-  block_tty_out_signal ();
+  block_tty_out_signal (&oldset);
   status = tgetent (tty->termcap_term_buffer, terminal_type);
   if (tty->termcap_term_buffer[TERMCAP_BUFFER_SIZE - 1])
     emacs_abort ();
-  unblock_tty_out_signal ();
+  unblock_tty_out_signal (&oldset);
 
   if (status < 0)
     {
@@ -4556,6 +4589,10 @@ bigger, or it may make it blink, or it may do nothing at all.  */);
   encode_terminal_src = NULL;
   encode_terminal_dst = NULL;
 
+  DEFSYM (Qtty_mode_set_strings, "tty-mode-set-strings");
+  DEFSYM (Qtty_mode_reset_strings, "tty-mode-reset-strings");
+
+#ifndef MSDOS
   DEFSYM (Qtty_menu_next_item, "tty-menu-next-item");
   DEFSYM (Qtty_menu_prev_item, "tty-menu-prev-item");
   DEFSYM (Qtty_menu_next_menu, "tty-menu-next-menu");
@@ -4565,4 +4602,5 @@ bigger, or it may make it blink, or it may do nothing at all.  */);
   DEFSYM (Qtty_menu_exit, "tty-menu-exit");
   DEFSYM (Qtty_menu_mouse_movement, "tty-menu-mouse-movement");
   DEFSYM (Qtty_menu_navigation_map, "tty-menu-navigation-map");
+#endif
 }