remove Lisp_Free struct type
[bpt/emacs.git] / src / term.c
index 9d9d682..500c1f2 100644 (file)
@@ -165,7 +165,7 @@ tty_ring_bell (struct frame *f)
 /* Set up termcap modes for Emacs. */
 
 static void
-tty_send_additional_strings (struct terminalterminal, Lisp_Object sym)
+tty_send_additional_strings (struct terminal *terminal, Lisp_Object sym)
 {
   Lisp_Object lisp_terminal;
   Lisp_Object extra_codes;
@@ -180,7 +180,6 @@ tty_send_additional_strings (struct terminal* terminal, Lisp_Object sym)
       if (STRINGP (string))
         {
           fwrite (SDATA (string), 1, SBYTES (string), tty->output);
-          fflush (tty->output);
           if (tty->termscript)
             fwrite (SDATA (string), 1, SBYTES (string), tty->termscript);
         }
@@ -209,8 +208,8 @@ 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);
-      fflush (tty->output);
       tty_send_additional_strings (terminal, Qtty_mode_set_strings);
+      fflush (tty->output);
     }
 }
 
@@ -528,9 +527,6 @@ 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 DOS_NT
-static
-#endif
 unsigned char *
 encode_terminal_code (struct glyph *src, int src_len,
                      struct coding_system *coding)
@@ -1865,7 +1861,7 @@ produce_glyphless_glyph (struct it *it, Lisp_Object acronym)
            acronym = XCDR (acronym);
          buf[0] = '[';
          str = STRINGP (acronym) ? SSDATA (acronym) : "";
-         for (len = 0; len < 6 && str[len] && ASCII_BYTE_P (str[len]); len++)
+         for (len = 0; len < 6 && str[len] && ASCII_CHAR_P (str[len]); len++)
            buf[1 + len] = str[len];
          buf[1 + len] = ']';
          len += 2;
@@ -2925,11 +2921,17 @@ tty_menu_display (tty_menu *menu, int x, int y, int pn, int *faces,
          menu_help_paneno = pn - 1;
          menu_help_itemno = j;
        }
+      /* Take note of the coordinates of the active menu item, to
+        display the cursor there.  */
+      if (mousehere)
+       {
+         row = y + i;
+         col = x;
+       }
       display_tty_menu_item (menu->text[j], max_width, face, x, y + i,
                             menu->submenu[j] != NULL);
     }
-  update_frame_with_menu (sf);
-  cursor_to (sf, row, col);
+  update_frame_with_menu (sf, row, col);
 }
 
 /* --------------------------- X Menu emulation ---------------------- */
@@ -3100,7 +3102,7 @@ static void
 screen_update (struct frame *f, struct glyph_matrix *mtx)
 {
   restore_desired_matrix (f, mtx);
-  update_frame_with_menu (f);
+  update_frame_with_menu (f, -1, -1);
 }
 
 typedef enum {
@@ -3205,6 +3207,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
   bool first_time;
   Lisp_Object selectface;
   int first_item = 0;
+  int col, row;
 
   /* Don't allow non-positive x0 and y0, lest the menu will wrap
      around the display.  */
@@ -3248,7 +3251,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
 
   /* Force update of the current frame, so that the desired and the
      current matrices are identical.  */
-  update_frame_with_menu (sf);
+  update_frame_with_menu (sf, -1, -1);
   state[0].menu = menu;
   state[0].screen_behind = save_and_enable_current_matrix (sf);
 
@@ -3260,7 +3263,10 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
 
   /* Turn off the cursor.  Otherwise it shows through the menu
      panes, which is ugly.  */
+  col = cursorX (tty);
+  row = cursorY (tty);
   tty_hide_cursor (tty);
+
   if (buffers_num_deleted)
     menu->text[0][7] = ' ';
   onepane = menu->count == 1 && menu->submenu[0];
@@ -3390,8 +3396,11 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
                            state[statecount - 1].y,
                            state[statecount - 1].pane,
                            faces, x, y, first_item, 1);
-         tty_hide_cursor (tty);
-         fflush (tty->output);
+         /* The call to display help-echo below will move the cursor,
+            so remember its current position as computed by
+            tty_menu_display.  */
+         col = cursorX (tty);
+         row = cursorY (tty);
        }
 
       /* Display the help-echo message for the currently-selected menu
@@ -3401,10 +3410,17 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
        {
          help_callback (menu_help_message,
                         menu_help_paneno, menu_help_itemno);
-         tty_hide_cursor (tty);
-         fflush (tty->output);
+         /* Move the cursor to the beginning of the current menu
+            item, so that screen readers and other accessibility aids
+            know where the active region is.  */
+         cursor_to (sf, row, col);
          prev_menu_help_message = menu_help_message;
        }
+      /* Both tty_menu_display and help_callback invoke update_end,
+        which calls tty_show_cursor.  Re-hide it, so it doesn't show
+        through the menus.  */
+      tty_hide_cursor (tty);
+      fflush (tty->output);
     }
 
   sf->mouse_moved = 0;
@@ -3563,9 +3579,10 @@ tty_menu_new_item_coords (struct frame *f, int which, int *x, int *y)
     }
 }
 
+/* WINDOWSNT uses this as menu_show_hook, see w32console.c.  */
 Lisp_Object
-tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
-              Lisp_Object title, bool kbd_navigation, const char **error_name)
+tty_menu_show (struct frame *f, int x, int y, int menuflags,
+              Lisp_Object title, const char **error_name)
 {
   tty_menu *menu;
   int pane, selidx, lpane, status;
@@ -3598,9 +3615,11 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
       return Qnil;
     }
 
-  /* Don't GC while we prepare and show the menu, because we give the
-     menu functions pointers to the contents of strings.  */
-  specpdl_count = inhibit_garbage_collection ();
+  specpdl_count = SPECPDL_INDEX ();
+
+  /* Avoid crashes if, e.g., another client will connect while we
+     are in a menu.  */
+  temporarily_switch_to_single_kboard (f);
 
   /* Adjust coordinates to be root-window-relative.  */
   item_x = x += f->left_pos;
@@ -3623,7 +3642,7 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
          prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
          pane_string = (NILP (pane_name)
                         ? "" : SSDATA (pane_name));
-         if (keymaps && !NILP (prefix))
+         if ((menuflags & MENU_KEYMAPS) && !NILP (prefix))
            pane_string++;
 
          lpane = tty_menu_add_pane (menu, pane_string);
@@ -3763,7 +3782,8 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
   specbind (Qoverriding_terminal_local_map,
            Fsymbol_value (Qtty_menu_navigation_map));
   status = tty_menu_activate (menu, &pane, &selidx, x, y, &datap,
-                             tty_menu_help_callback, kbd_navigation);
+                             tty_menu_help_callback,
+                             menuflags & MENU_KBD_NAVIGATION);
   entry = pane_prefix = Qnil;
 
   switch (status)
@@ -3789,7 +3809,7 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
                    {
                      entry
                        = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
-                     if (keymaps != 0)
+                     if (menuflags & MENU_KEYMAPS)
                        {
                          entry = Fcons (entry, Qnil);
                          if (!NILP (pane_prefix))
@@ -3822,7 +3842,7 @@ tty_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
        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)
+      if (!(menuflags & MENU_FOR_CLICK))
         Fsignal (Qquit, Qnil);
       break;
     }
@@ -3903,6 +3923,7 @@ clear_tty_hooks (struct terminal *terminal)
   terminal->frame_rehighlight_hook = 0;
   terminal->frame_raise_lower_hook = 0;
   terminal->fullscreen_hook = 0;
+  terminal->menu_show_hook = 0;
   terminal->set_vertical_scroll_bar_hook = 0;
   terminal->condemn_scroll_bars_hook = 0;
   terminal->redeem_scroll_bar_hook = 0;
@@ -3921,43 +3942,25 @@ clear_tty_hooks (struct terminal *terminal)
 static void
 set_tty_hooks (struct terminal *terminal)
 {
-  terminal->rif = 0; /* ttys don't support window-based redisplay. */
-
   terminal->cursor_to_hook = &tty_cursor_to;
   terminal->raw_cursor_to_hook = &tty_raw_cursor_to;
-
   terminal->clear_to_end_hook = &tty_clear_to_end;
   terminal->clear_frame_hook = &tty_clear_frame;
   terminal->clear_end_of_line_hook = &tty_clear_end_of_line;
-
   terminal->ins_del_lines_hook = &tty_ins_del_lines;
-
   terminal->insert_glyphs_hook = &tty_insert_glyphs;
   terminal->write_glyphs_hook = &tty_write_glyphs;
   terminal->delete_glyphs_hook = &tty_delete_glyphs;
-
   terminal->ring_bell_hook = &tty_ring_bell;
-
   terminal->reset_terminal_modes_hook = &tty_reset_terminal_modes;
   terminal->set_terminal_modes_hook = &tty_set_terminal_modes;
-  terminal->update_begin_hook = 0; /* Not needed. */
   terminal->update_end_hook = &tty_update_end;
+  terminal->menu_show_hook = &tty_menu_show;
   terminal->set_terminal_window_hook = &tty_set_terminal_window;
-
-  terminal->mouse_position_hook = 0; /* Not needed. */
-  terminal->frame_rehighlight_hook = 0; /* Not needed. */
-  terminal->frame_raise_lower_hook = 0; /* Not needed. */
-
-  terminal->set_vertical_scroll_bar_hook = 0; /* Not needed. */
-  terminal->condemn_scroll_bars_hook = 0; /* Not needed. */
-  terminal->redeem_scroll_bar_hook = 0; /* Not needed. */
-  terminal->judge_scroll_bars_hook = 0; /* Not needed. */
-
   terminal->read_socket_hook = &tty_read_avail_input; /* keyboard.c */
-  terminal->frame_up_to_date_hook = 0; /* Not needed. */
-
   terminal->delete_frame_hook = &tty_free_frame_resources;
   terminal->delete_terminal_hook = &delete_tty;
+  /* Other hooks are NULL by default.  */
 }
 
 /* If FD is the controlling terminal, drop it.  */
@@ -4021,7 +4024,7 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed)
   if (terminal)
     return terminal;
 
-  terminal = create_terminal ();
+  terminal = create_terminal (output_termcap, NULL);
 #ifdef MSDOS
   if (been_here > 0)
     maybe_fatal (0, 0, "Attempt to create another terminal %s", "",
@@ -4035,7 +4038,6 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed)
   tty->next = tty_list;
   tty_list = tty;
 
-  terminal->type = output_termcap;
   terminal->display_info.tty = tty;
   tty->terminal = terminal;