]> code.delx.au - gnu-emacs/blobdiff - src/term.c
Some changes from Michael K. Johnson for Linux.
[gnu-emacs] / src / term.c
index 5fbfcc461079f76b9a1661af4e3d5ce629ff26ad..0b59e13b9fc9827ad24d09d764414f6527243bc3 100644 (file)
@@ -1,5 +1,5 @@
 /* terminal control module for terminals described by TERMCAP
-   Copyright (C) 1985, 1986, 1987, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1987, 1992, 1993 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -94,12 +94,26 @@ int (*set_terminal_window_hook) ();
 int (*read_socket_hook) ();
 
 /* Return the current position of the mouse.
-   Set `bar' to point to the scrollbar if the mouse movement started
-   in a scrollbar, or zero if it started elsewhere in the frame.
-   This should clear mouse_moved until the next motion event arrives.  */
+
+   Set *f to the frame the mouse is in, or zero if the mouse is in no
+   Emacs frame.  If it is set to zero, all the other arguments are
+   garbage.
+
+   If the motion started in a scroll bar, set *bar_window to the
+   scroll bar's window, *part to the part the mouse is currently over,
+   *x to the position of the mouse along the scroll bar, and *y to the
+   overall length of the scroll bar.
+
+   Otherwise, set *bar_window to Qnil, and *x and *y to the column and
+   row of the character cell the mouse is over.
+
+   Set *time to the time the mouse was at the returned position.
+
+   This should clear mouse_moved until the next motion
+   event arrives.  */
 void (*mouse_position_hook) ( /* FRAME_PTR *f,
-                                struct scrollbar **bar,
-                                enum scrollbar_part *part,
+                                Lisp_Object *bar_window,
+                                enum scroll_bar_part *part,
                                 Lisp_Object *x,
                                 Lisp_Object *y,
                                 unsigned long *time */ );
@@ -111,36 +125,66 @@ void (*mouse_position_hook) ( /* FRAME_PTR *f,
    the highlight.  */
 void (*frame_rehighlight_hook) ( /* FRAME_PTR f */ );
 
-/* Set vertical scollbar BAR to have its upper left corner at (TOP,
-   LEFT), and be LENGTH rows high.  Set its handle to indicate that we
-   are displaying PORTION characters out of a total of WHOLE
-   characters, starting at POSITION.  Return BAR.  If BAR is zero,
-   create a new scrollbar and return a pointer to it.  */
-struct scrollbar *(*set_vertical_scrollbar_hook)
-     ( /* struct scrollbar *BAR,
-         struct window *window,
+/* If we're displaying frames using a window system that can stack
+   frames on top of each other, this hook allows you to bring a frame
+   to the front, or bury it behind all the other windows.  If this
+   hook is zero, that means the device we're displaying on doesn't
+   support overlapping frames, so there's no need to raise or lower
+   anything.
+
+   If RAISE is non-zero, F is brought to the front, before all other
+   windows.  If RAISE is zero, F is sent to the back, behind all other
+   windows.  */
+void (*frame_raise_lower_hook) ( /* FRAME_PTR f, int raise */ );
+
+/* Set the vertical scroll bar for WINDOW to have its upper left corner
+   at (TOP, LEFT), and be LENGTH rows high.  Set its handle to
+   indicate that we are displaying PORTION characters out of a total
+   of WHOLE characters, starting at POSITION.  If WINDOW doesn't yet
+   have a scroll bar, create one for it.  */
+void (*set_vertical_scroll_bar_hook)
+     ( /* struct window *window,
          int portion, int whole, int position */ );
 
+
 /* The following three hooks are used when we're doing a thorough
-   redisplay of the frame.  We don't explicitly know which scrollbars
+   redisplay of the frame.  We don't explicitly know which scroll bars
    are going to be deleted, because keeping track of when windows go
    away is a real pain - can you say set-window-configuration?
    Instead, we just assert at the beginning of redisplay that *all*
-   scrollbars are to be removed, and then save scrollbars from the
+   scroll bars are to be removed, and then save scroll bars from the
    firey pit when we actually redisplay their window.  */
 
-/* Arrange for all scrollbars on FRAME to be removed at the next call
-   to `*judge_scrollbars_hook'.  A scrollbar may be spared if
-   `*redeem_scrollbar_hook' is applied to it before the judgement.  */
-void (*condemn_scrollbars_hook)( /* FRAME_PTR *FRAME */ );
+/* Arrange for all scroll bars on FRAME to be removed at the next call
+   to `*judge_scroll_bars_hook'.  A scroll bar may be spared if
+   `*redeem_scroll_bar_hook' is applied to its window before the judgement. 
+
+   This should be applied to each frame each time its window tree is
+   redisplayed, even if it is not displaying scroll bars at the moment;
+   if the HAS_SCROLL_BARS flag has just been turned off, only calling
+   this and the judge_scroll_bars_hook will get rid of them.
 
-/* Unmark BAR for deletion in this judgement cycle.  */
-void (*redeem_scrollbar_hook)( /* struct scrollbar *BAR */ );
+   If non-zero, this hook should be safe to apply to any frame,
+   whether or not it can support scroll bars, and whether or not it is
+   currently displaying them.  */
+void (*condemn_scroll_bars_hook)( /* FRAME_PTR *frame */ );
 
-/* Remove all scrollbars on FRAME that haven't been saved since the
-   last call to `*condemn_scrollbars_hook'.  */
-void (*judge_scrollbars_hook)( /* FRAME_PTR *FRAME */ );
+/* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
+   Note that it's okay to redeem a scroll bar that is not condemned.  */
+void (*redeem_scroll_bar_hook)( /* struct window *window */ );
 
+/* Remove all scroll bars on FRAME that haven't been saved since the
+   last call to `*condemn_scroll_bars_hook'.  
+
+   This should be applied to each frame after each time its window
+   tree is redisplayed, even if it is not displaying scroll bars at the
+   moment; if the HAS_SCROLL_BARS flag has just been turned off, only
+   calling this and condemn_scroll_bars_hook will get rid of them.
+
+   If non-zero, this hook should be safe to apply to any frame,
+   whether or not it can support scroll bars, and whether or not it is
+   currently displaying them.  */
+void (*judge_scroll_bars_hook)( /* FRAME_PTR *FRAME */ );
 
 
 /* Strings, numbers and flags taken from the termcap entry.  */
@@ -338,7 +382,7 @@ set_scroll_region (start, stop)
       buf = tparam (TS_set_window, 0, 0, start, 0, stop, FRAME_WIDTH (selected_frame));
     }
   OUTPUT (buf);
-  free (buf);
+  xfree (buf);
   losecursor ();
 }
 \f
@@ -743,7 +787,7 @@ insert_glyphs (start, len)
     {
       buf = tparam (TS_ins_multi_chars, 0, 0, len);
       OUTPUT1 (buf);
-      free (buf);
+      xfree (buf);
       if (start)
        write_glyphs (start, len);
       return;
@@ -807,7 +851,7 @@ delete_glyphs (n)
     {
       buf = tparam (TS_del_multi_chars, 0, 0, n);
       OUTPUT1 (buf);
-      free (buf);
+      xfree (buf);
     }
   else
     for (i = 0; i < n; i++)
@@ -852,7 +896,7 @@ ins_del_lines (vpos, n)
       background_highlight ();
       buf = tparam (multi, 0, 0, i);
       OUTPUT (buf);
-      free (buf);
+      xfree (buf);
     }
   else if (single)
     {
@@ -1021,6 +1065,8 @@ calculate_ins_del_char_costs (frame)
 extern int x_screen_planes;
 #endif
 
+extern do_line_insertion_deletion_costs ();
+
 calculate_costs (frame)
      FRAME_PTR frame;
 {
@@ -1096,49 +1142,97 @@ calculate_costs (frame)
   cmcostinit ();               /* set up cursor motion costs */
 }
 \f
-/* Find the escape codes sent by the function keys for Vfunction_key_map.
-   This function scans the termcap function key sequence entries, and 
-   adds entries to Vfunction_key_map for each function key it finds.  */
-
 struct fkey_table {
   char *cap, *name;
 };
 
+  /* Termcap capability names that correspond directly to X keysyms.
+     Some of these (marked "terminfo") aren't supplied by old-style
+     (Berkeley) termcap entries.  They're listed in X keysym order;
+     except we put the keypad keys first, so that if they clash with
+     other keys (as on the IBM PC keyboard) they get overridden.
+  */
+
 static struct fkey_table keys[] = {
-  "kl", "left",
-  "kr", "right",
-  "ku", "up",
-  "kd", "down",
-  "K2", "center",
-  "k1", "f1",
-  "k2", "f2",
-  "k3", "f3",
-  "k4", "f4",
-  "k5", "f5",
-  "k6", "f6",
-  "k7", "f7",
-  "k8", "f8",
-  "k9", "f9",
-  "F1", "f11",
-  "F2", "f12",
-  "kh", "home",
-  "kH", "home-down",
-  "ka", "clear-tabs",
-  "kt", "clear-tab",
-  "kT", "set-tab",
-  "kC", "clear",
-  "kL", "deleteline",
-  "kM", "exit-insert",
-  "kE", "clear-eol",
-  "kS", "clear-eos",
-  "kI", "insert",
-  "kA", "insertline",
-  "kN", "next",
-  "kP", "prior",
-  "kF", "scroll-forward",
-  "kR", "scroll-reverse"
+  "kh", "home",                /* termcap */
+  "kl", "left",                /* termcap */
+  "ku", "up",          /* termcap */
+  "kr", "right",       /* termcap */
+  "kd", "down",                /* termcap */
+  "%8", "prior",       /* terminfo */
+  "%5", "next",                /* terminfo */
+  "@7",        "end",          /* terminfo */
+  "@1", "begin",       /* terminfo */
+  "*6", "select",      /* terminfo */
+  "%9", "print",       /* terminfo */
+  "@4", "execute",     /* terminfo --- actually the `command' key */
+  /*
+   * "insert" --- see below
+   */
+  "&8",        "undo",         /* terminfo */
+  "%0",        "redo",         /* terminfo */
+  "%7",        "menu",         /* terminfo --- actually the `options' key */
+  "@0",        "find",         /* terminfo */
+  "@2",        "cancel",       /* terminfo */
+  "%1", "help",                /* terminfo */
+  /*
+   * "break" goes here, but can't be reliably intercepted with termcap
+   */
+  "&4", "reset",       /* terminfo --- actually `restart' */
+  /*
+   * "system" and "user" --- no termcaps
+   */
+  "kE", "clearline",   /* terminfo */
+  "kA", "insertline",  /* terminfo */
+  "kL", "deleteline",  /* terminfo */
+  "kI", "insertchar",  /* terminfo */
+  "kD", "deletechar",  /* terminfo */
+  "kB", "backtab",     /* terminfo */
+  /*
+   * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
+   */
+  "@8", "kp-enter",    /* terminfo */
+  /*
+   * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
+   * "kp-multiply", "kp-add", "kp-separator",
+   * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
+   * --- no termcaps for any of these.
+   */
+  "K4", "kp-1",                /* terminfo */
+  /*
+   * "kp-2" --- no termcap
+   */
+  "K5", "kp-3",                /* terminfo */
+  /*
+   * "kp-4" --- no termcap
+   */
+  "K2", "kp-5",                /* terminfo */
+  /*
+   * "kp-6" --- no termcap
+   */
+  "K1", "kp-7",                /* terminfo */
+  /*
+   * "kp-8" --- no termcap
+   */
+  "K3", "kp-9",                /* terminfo */
+  /*
+   * "kp-equal" --- no termcap
+   */
+  "k1",        "f1",
+  "k2",        "f2",
+  "k3",        "f3",
+  "k4",        "f4",
+  "k5",        "f5",
+  "k6",        "f6",
+  "k7",        "f7",
+  "k8",        "f8",
+  "k9",        "f9",
   };
 
+/* Find the escape codes sent by the function keys for Vfunction_key_map.
+   This function scans the termcap function key sequence entries, and 
+   adds entries to Vfunction_key_map for each function key it finds.  */
+
 void
 term_get_fkeys (address)
      char **address;
@@ -1178,6 +1272,49 @@ term_get_fkeys (address)
                   build_string (k0),
                   Fmake_vector (make_number (1), intern (k0_name)));
   }
+
+  /* Set up cookies for numbered function keys above f10. */
+  {
+    char fcap[3], fkey[4];
+
+    fcap[0] = 'k'; fcap[2] = '\0';
+    for (i = 11; i < 64; i++)
+      {
+       if (i <= 19)
+         fcap[1] = '1' + i - 11;
+       else if (i <= 45)
+         fcap[1] = 'A' + i - 11;
+       else
+         fcap[1] = 'a' + i - 11;
+
+       if (tgetstr (fcap, address))
+         {
+           (void) sprintf (fkey, "f%d", i);        
+           Fdefine_key (Vfunction_key_map,
+                        build_string (fcap),
+                        Fmake_vector (make_number (1), intern (fkey)));
+         }
+      }
+   }
+
+  /*
+   * Various mappings to try and get a better fit.
+   */
+  {
+#define CONDITIONAL_REASSIGN(cap1, cap2, sym)                  \
+      if (!tgetstr (cap1, address) && tgetstr (cap2, address)) \
+       Fdefine_key (Vfunction_key_map,                         \
+                    build_string (cap2),                       \
+                    Fmake_vector (make_number (1), intern (sym)))
+         
+      /* if there's no key_next keycap, map key_npage to `next' keysym */
+      CONDITIONAL_REASSIGN ("%5", "kN", "next");
+      /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
+      CONDITIONAL_REASSIGN ("%8", "kP", "previous");
+      /* if there's no key_dc keycap, map key_ic to `insert' keysym */
+      CONDITIONAL_REASSIGN ("kD", "kI", "insert");
+#undef CONDITIONAL_REASSIGN
+  }
 }
 
 \f
@@ -1451,8 +1588,8 @@ It may be necessary to do `unsetenv TERMCAP' as well.\n",
                                /* meaningless in this case */
     baud_rate = 9600;
 
-  FRAME_CAN_HAVE_SCROLLBARS (selected_frame) = 0;
-  FRAME_HAS_VERTICAL_SCROLLBARS (selected_frame) = 0;
+  FRAME_CAN_HAVE_SCROLL_BARS (selected_frame) = 0;
+  FRAME_HAS_VERTICAL_SCROLL_BARS (selected_frame) = 0;
 }
 
 /* VARARGS 1 */