(Faref): Delete codes for a composite character..
[bpt/emacs.git] / src / xterm.c
index f1725b3..270bc76 100644 (file)
@@ -22,17 +22,13 @@ Boston, MA 02111-1307, USA.  */
 /* New display code by Gerd Moellmann <gerd@gnu.org>.  */
 /* Xt features made by Fred Pierresteguy.  */
 
+#include <config.h>
+
 /* On 4.3 these lose if they come after xterm.h.  */
-/* On HP-UX 8.0 signal.h loses if it comes after config.h.  */
 /* Putting these at the beginning seems to be standard for other .c files.  */
 #include <signal.h>
 
-#include <config.h>
-
 #include <stdio.h>
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#endif
 
 #ifdef HAVE_X_WINDOWS
 
@@ -122,13 +118,21 @@ extern void _XEditResCheckMessages ();
 #include <Xm/Xm.h>             /* for LESSTIF_VERSION */
 #include <Xm/ScrollBar.h>
 #include <Xm/ScrollBarP.h>
-#elif defined HAVE_XAW3D
+#else /* !USE_MOTIF i.e. use Xaw */
+
+#ifdef HAVE_XAW3D
 #include <X11/Xaw3d/Simple.h>
-#include <X11/Xaw3d/ThreeD.h>
 #include <X11/Xaw3d/Scrollbar.h>
 #define ARROW_SCROLLBAR
 #include <X11/Xaw3d/ScrollbarP.h>
-#endif /* HAVE_XAW3D */
+#else /* !HAVE_XAW3D */
+#include <X11/Xaw/Simple.h>
+#include <X11/Xaw/Scrollbar.h>
+#endif /* !HAVE_XAW3D */
+#ifndef XtNpickTop
+#define XtNpickTop "pickTop"
+#endif /* !XtNpickTop */
+#endif /* !USE_MOTIF */
 #endif /* USE_TOOLKIT_SCROLL_BARS */
 
 #endif /* USE_X_TOOLKIT */
@@ -145,11 +149,6 @@ extern void _XEditResCheckMessages ();
 #endif
 #endif
 
-#ifdef HAVE_SETLOCALE
-/* So we can do setlocale.  */
-#include <locale.h>
-#endif
-
 #ifdef SOLARIS2
 /* memmove will be defined as a macro in Xfuncs.h unless
    <string.h> is included beforehand.  The declaration for memmove in
@@ -2157,9 +2156,9 @@ static void x_get_glyph_overhangs P_ ((struct glyph *, struct frame *,
                                       int *, int *));
 static void x_compute_overhangs_and_x P_ ((struct glyph_string *, int, int));
 static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
-                                     unsigned long *, float, int));
+                                     unsigned long *, double, int));
 static void x_setup_relief_color P_ ((struct frame *, struct relief *,
-                                     float, int, unsigned long));
+                                     double, int, unsigned long));
 static void x_setup_relief_colors P_ ((struct glyph_string *));
 static void x_draw_image_glyph_string P_ ((struct glyph_string *));
 static void x_draw_image_relief P_ ((struct glyph_string *));
@@ -3049,7 +3048,7 @@ x_alloc_lighter_color (f, display, cmap, pixel, factor, delta)
      Display *display;
      Colormap cmap;
      unsigned long *pixel;
-     float factor;
+     double factor;
      int delta;
 {
   XColor color, new;
@@ -3108,7 +3107,7 @@ static void
 x_setup_relief_color (f, relief, factor, delta, default_pixel)
      struct frame *f;
      struct relief *relief;
-     float factor;
+     double factor;
      int delta;
      unsigned long default_pixel;
 {
@@ -6743,7 +6742,7 @@ show_mouse_face (dpyinfo, draw)
        }
 
       if (end_hpos > start_hpos)
-       x_draw_glyphs (w, start_x, row, updated_area
+       x_draw_glyphs (w, start_x, row, TEXT_AREA
                       start_hpos, end_hpos, draw, NULL, NULL, 0);
     }
 
@@ -7110,9 +7109,20 @@ static Lisp_Object window_being_scrolled;
 
 static int last_scroll_bar_part;
 
+/* Whether this is an Xaw with arrow-scrollbars.  This should imply
+   that movements of 1/20 of the screen size are mapped to up/down.  */
+
+static Boolean xaw3d_arrow_scroll;
+
+/* Whether the drag scrolling maintains the mouse at the top of the
+   thumb.  If not, resizing the thumb needs to be done more carefully
+   to avoid jerkyness.  */
+
+static Boolean xaw3d_pick_top;
+
 
 /* Action hook installed via XtAppAddActionHook when toolkit scroll
-   bars are used..  The hoos is responsible for detecting when
+   bars are used..  The hook is responsible for detecting when
    the user ends an interaction with the scroll bar, and generates
    a `end-scroll' scroll_bar_click' event if so.  */
 
@@ -7132,12 +7142,10 @@ xt_action_hook (widget, client_data, action_name, event, params,
 #ifdef USE_MOTIF
   scroll_bar_p = XmIsScrollBar (widget);
   end_action = "Release";
-#elif defined HAVE_XAW3D
+#else /* !USE_MOTIF i.e. use Xaw */
   scroll_bar_p = XtIsSubclass (widget, scrollbarWidgetClass);
   end_action = "EndScroll";
-#else
-  #error unknown scroll bar toolkit
-#endif /* HAVE_XAW3D */
+#endif /* USE_MOTIF */
 
   /* Although LessTif uses XtTimeouts like Xaw3d, the timer hack to
      let Xt timeouts be processed doesn't work.  */
@@ -7322,40 +7330,39 @@ xm_scroll_callback (widget, client_data, call_data)
 }
 
 
-#else /* not USE_MOTIF, i.e. XAW3D.  */
+#else /* !USE_MOTIF, i.e. Xaw.  */
 
 
-/* Xaw3d scroll bar callback.  Invoked when the thumb is dragged.
+/* Xaw scroll bar callback.  Invoked when the thumb is dragged.
    WIDGET is the scroll bar widget.  CLIENT_DATA is a pointer to the
    scroll bar struct.  CALL_DATA is a pointer to a float saying where
    the thumb is.  */
 
 static void
-xaw3d_jump_callback (widget, client_data, call_data)
+xaw_jump_callback (widget, client_data, call_data)
      Widget widget;
      XtPointer client_data, call_data;
 {
   struct scroll_bar *bar = (struct scroll_bar *) client_data;
   float top = *(float *) call_data;
   float shown;
-  int whole, portion;
-  int dragging_down_p, part;
-  double epsilon = 0.01;
+  int whole, portion, height;
+  int part;
 
   /* Get the size of the thumb, a value between 0 and 1.  */
   BLOCK_INPUT;
-  XtVaGetValues (widget, XtNshown, &shown, NULL);
+  XtVaGetValues (widget, XtNshown, &shown, XtNheight, &height, NULL);
   UNBLOCK_INPUT;
 
   whole = 10000000;
   portion = shown < 1 ? top * whole : 0;
-  dragging_down_p = (INTEGERP (bar->dragging)
-                    && XINT (bar->dragging) < portion);
 
-  if (shown < 1
-      && (abs (top + shown - 1) < epsilon
-         || (dragging_down_p
-             && last_scroll_bar_part == scroll_bar_down_arrow)))
+  if (shown < 1 && (abs (top + shown - 1) < 1.0/height))
+    /* Some derivatives of Xaw refuse to shrink the thumb when you reach
+       the bottom, so we force the scrolling whenever we see that we're
+       too close to the bottom (in x_set_toolkit_scroll_bar_thumb
+       we try to ensure that we always stay two pixels away from the
+       bottom).  */
     part = scroll_bar_down_arrow;
   else
     part = scroll_bar_handle;
@@ -7367,8 +7374,8 @@ xaw3d_jump_callback (widget, client_data, call_data)
 }
 
 
-/* Xaw3d scroll bar callback.  Invoked for incremental scrolling.,
-   i.e. line or page up or down.  WIDGET is the Xaw3d scroll bar
+/* Xaw scroll bar callback.  Invoked for incremental scrolling.,
+   i.e. line or page up or down.  WIDGET is the Xaw scroll bar
    widget.  CLIENT_DATA is a pointer to the scroll_bar structure for
    the scroll bar.  CALL_DATA is an integer specifying the action that
    has taken place.  It's magnitude is in the range 0..height of the
@@ -7376,7 +7383,7 @@ xaw3d_jump_callback (widget, client_data, call_data)
    Values < height of scroll bar mean line-wise movement.  */
 
 static void
-xaw3d_scroll_callback (widget, client_data, call_data)
+xaw_scroll_callback (widget, client_data, call_data)
      Widget widget;
      XtPointer client_data, call_data;
 {
@@ -7390,25 +7397,20 @@ xaw3d_scroll_callback (widget, client_data, call_data)
   XtVaGetValues (widget, XtNheight, &height, NULL);
   UNBLOCK_INPUT;
 
-  if (position < 0)
-    {
-      if (abs (position) < height)
-       part = scroll_bar_up_arrow;
-      else
-       part = scroll_bar_above_handle;
-    }
+  if (abs (position) >= height)
+    part = (position < 0) ? scroll_bar_above_handle : scroll_bar_below_handle;
+
+  /* If Xaw3d was compiled with ARROW_SCROLLBAR,
+     it maps line-movement to call_data = max(5, height/20).  */
+  else if (xaw3d_arrow_scroll && abs (position) <= max (5, height / 20))
+    part = (position < 0) ? scroll_bar_up_arrow : scroll_bar_down_arrow;
   else
-    {
-      if (abs (position) < height)
-       part = scroll_bar_down_arrow;
-      else
-       part = scroll_bar_below_handle;
-    }
+    part = scroll_bar_move_ratio;
 
   window_being_scrolled = bar->window;
   bar->dragging = Qnil;
   last_scroll_bar_part = part;
-  x_send_scroll_bar_event (bar->window, part, 0, 0);
+  x_send_scroll_bar_event (bar->window, part, position, height);
 }
 
 
@@ -7491,7 +7493,7 @@ x_create_toolkit_scroll_bar (f, bar)
   XDefineCursor (XtDisplay (widget), XtWindow (widget),
                 f->output_data.x->nontext_cursor);
   
-#elif defined HAVE_XAW3D
+#else /* !USE_MOTIF i.e. use Xaw */
   
   /* Set resources.  Create the widget.  The background of the
      Xaw3d scroll bar widget is a little bit light for my taste.
@@ -7499,8 +7501,9 @@ x_create_toolkit_scroll_bar (f, bar)
      to their taste with `emacs*verticalScrollBar.background: xxx'.  */
   XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac;
   XtSetArg (av[ac], XtNorientation, XtorientVertical); ++ac;
-  XtSetArg (av[ac], XtNcursorName, "left_ptr"); ++ac;
-  XtSetArg (av[ac], XtNbeNiceToColormap, True); ++ac;
+  /* For smoother scrolling with Xaw3d   -sm */
+  /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */
+  /* XtSetArg (av[ac], XtNbeNiceToColormap, True); ++ac; */
   
   pixel = f->output_data.x->scroll_bar_foreground_pixel;
   if (pixel != -1)
@@ -7518,16 +7521,29 @@ x_create_toolkit_scroll_bar (f, bar)
   
   widget = XtCreateWidget (scroll_bar_name, scrollbarWidgetClass,
                           f->output_data.x->edit_widget, av, ac);
+
+  {
+    char *initial = "";
+    char *val = initial;
+    XtVaGetValues (widget, XtNscrollVCursor, (XtPointer) &val,
+                  XtNpickTop, (XtPointer) &xaw3d_pick_top, NULL);
+    if (val == initial)
+      {        /* ARROW_SCROLL */
+       xaw3d_arrow_scroll = True;
+       /* Isn't that just a personal preference ?   -sm */
+       XtVaSetValues (widget, XtNcursorName, "top_left_arrow", NULL);
+      }
+  }
   
   /* Define callbacks.  */
-  XtAddCallback (widget, XtNjumpProc, xaw3d_jump_callback, (XtPointer) bar);
-  XtAddCallback (widget, XtNscrollProc, xaw3d_scroll_callback,
+  XtAddCallback (widget, XtNjumpProc, xaw_jump_callback, (XtPointer) bar);
+  XtAddCallback (widget, XtNscrollProc, xaw_scroll_callback,
                 (XtPointer) bar);
   
   /* Realize the widget.  Only after that is the X window created.  */
   XtRealizeWidget (widget);
   
-#endif /* HAVE_XAW3D */
+#endif /* !USE_MOTIF */
 
   /* Install an action hook that let's us detect when the user
      finishes interacting with a scroll bar.  */
@@ -7571,7 +7587,7 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
     unsigned char flags;
     XmScrollBarWidget sb;
 
-    /* Slider size.  Must be in the range [1 .. MAX - MIN] where NAX
+    /* Slider size.  Must be in the range [1 .. MAX - MIN] where MAX
        is the scroll bar's maximum and MIN is the scroll bar's minimum
        value.  */
     size = shown * XM_SB_RANGE;
@@ -7599,7 +7615,7 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
       XmScrollBarSetValues (widget, value, size, 0, 0, False);
     else if (last_scroll_bar_part == scroll_bar_down_arrow)
       /* This has the negative side effect that the slider value is
-        not would it would be if we scrolled here using line-wise or
+        not what it would be if we scrolled here using line-wise or
         page-wise movement.  */
       XmScrollBarSetValues (widget, value, XM_SB_RANGE - value, 0, 0, False);
     else
@@ -7619,43 +7635,61 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
     sb->scrollBar.arrow2_selected = arrow2_selected;
     sb->scrollBar.flags = flags;
   }
-#elif defined HAVE_XAW3D
+#else /* !USE_MOTIF i.e. use Xaw */
   {
-    /* Restrict to [0 1].  */
-    top = max (0, min (1, top));
-    shown = max (0, min (1, shown));
+    float old_top, old_shown;
+    Dimension height;
+    XtVaGetValues (widget,
+                  XtNtopOfThumb, &old_top,
+                  XtNshown, &old_shown,
+                  XtNheight, &height,
+                  NULL);
+
+    /* Massage the top+shown values.  */
+    if (NILP (bar->dragging) || last_scroll_bar_part == scroll_bar_down_arrow)
+      top = max (0, min (1, top));
+    else
+      top = old_top;
+    /* Keep two pixels available for moving the thumb down.  */
+    shown = max (0, min (1 - top - (2.0 / height), shown));
 
     /* If the call to XawScrollbarSetThumb below doesn't seem to work,
        check that your system's configuration file contains a define
        for `NARROWPROTO'.  See s/freebsd.h for an example.  */
-    if (NILP (bar->dragging))
+    if (top != old_top || shown != old_shown)
       {
-       float old_top, old_shown;
-       XtVaGetValues (widget, XtNtopOfThumb, &old_top, XtNshown, &old_shown,
-                      NULL);
-       if (top != old_top || shown != old_shown)
+       if (NILP (bar->dragging))
          XawScrollbarSetThumb (widget, top, shown);
-      }
-    else
-      {
-       ScrollbarWidget sb = (ScrollbarWidget) widget;
-       int scroll_mode = sb->scrollbar.scroll_mode;
-
-       sb->scrollbar.scroll_mode = 0;
-       
-       if (last_scroll_bar_part == scroll_bar_down_arrow)
-         XawScrollbarSetThumb (widget, top, 1 - top);
        else
          {
-           float old_top;
-           XtVaGetValues (widget, XtNtopOfThumb, &old_top, NULL);
-           XawScrollbarSetThumb (widget, old_top, min (shown, 1 - old_top));
+#ifdef HAVE_XAW3D
+           ScrollbarWidget sb = (ScrollbarWidget) widget;
+           int scroll_mode;
+           
+           /* `scroll_mode' only exists with Xaw3d + ARROW_SCROLLBAR.  */
+           if (xaw3d_arrow_scroll)
+             {
+               /* Xaw3d stupidly ignores resize requests while dragging
+                  so we have to make it believe it's not in dragging mode.  */
+               scroll_mode = sb->scrollbar.scroll_mode;
+               if (scroll_mode == 2)
+                 sb->scrollbar.scroll_mode = 0;
+             }
+#endif
+           /* Try to make the scrolling a tad smoother.  */
+           if (!xaw3d_pick_top)
+             shown = min (shown, old_shown);
+           
+           XawScrollbarSetThumb (widget, top, shown);
+           
+#ifdef HAVE_XAW3D
+           if (xaw3d_arrow_scroll && scroll_mode == 2)
+             sb->scrollbar.scroll_mode = scroll_mode;
+#endif
          }
-       
-       sb->scrollbar.scroll_mode = scroll_mode;
       }
   }
-#endif /* HAVE_XAW3D */
+#endif /* !USE_MOTIF */
 
   UNBLOCK_INPUT;
 }
@@ -8723,6 +8757,19 @@ XTread_socket (sd, bufp, numchars, expected)
                        if (f && FRAME_XIC (f))
                          XSetICFocus (FRAME_XIC (f));
 #endif
+#if 0 /* Emacs sets WM hints whose `input' field is `true'.  This
+        instructs the WM to set the input focus automatically for
+        Emacs with a call to XSetInputFocus.  Setting WM_TAKE_FOCUS
+        tells the WM to send us a ClientMessage WM_TAKE_FOCUS after
+        it has set the focus.  So, XSetInputFocus below is not
+        needed.
+
+        The call to XSetInputFocus below has also caused trouble.  In
+        cases where the XSetInputFocus done by the WM and the one
+        below are temporally close (on a fast machine), the call
+        below can generate additional FocusIn events which confuse
+        Emacs.  */
+                       
                        /* Since we set WM_TAKE_FOCUS, we must call
                           XSetInputFocus explicitly.  But not if f is null,
                           since that might be an event for a deleted frame.  */
@@ -8743,6 +8790,7 @@ XTread_socket (sd, bufp, numchars, expected)
                            x_uncatch_errors (d, count);
                          }  
                        /* Not certain about handling scroll bars here */
+#endif /* 0 */
                      }
                    else if (event.xclient.data.l[0]
                             == dpyinfo->Xatom_wm_save_yourself)
@@ -8841,6 +8889,8 @@ XTread_socket (sd, bufp, numchars, expected)
                else if (event.xclient.message_type
                         == dpyinfo->Xatom_Scrollbar)
                  {
+                   if (display_busy_cursor_p)
+                     inhibit_busy_cursor = 2;
                    x_scroll_bar_to_input_event (&event, bufp);
                    ++bufp, ++count, --numchars;
                    goto out;
@@ -12378,28 +12428,6 @@ same_x_server (name1, name2)
 }
 #endif
 
-#if defined (HAVE_X_I18N) || (defined (USE_X_TOOLKIT) && defined (HAVE_X11XTR6))
-/* Recover from setlocale (LC_ALL, "").  */
-static void
-fixup_locale ()
-{
-  /* Currently we require strerror to use the "C" locale,
-     since we don't yet support decoding its string result.  */
-#ifdef LC_MESSAGES
-  setlocale (LC_MESSAGES, "C");
-#endif
-
-  /* The Emacs Lisp reader needs LC_NUMERIC to be "C",
-     so that numbers are read and printed properly for Emacs Lisp.  */
-  setlocale (LC_NUMERIC, "C");
-
-  /* Currently we require strftime to use the "C" locale,
-     since we don't yet support encoding its format argument,
-     or decoding its string result.  */
-  setlocale (LC_TIME, "C");
-}
-#endif
-
 struct x_display_info *
 x_term_init (display_name, xrm_option, resource_name)
      Lisp_Object display_name;
@@ -12419,11 +12447,6 @@ x_term_init (display_name, xrm_option, resource_name)
       x_initialized = 1;
     }
 
-#ifdef HAVE_X_I18N
-  setlocale (LC_ALL, "");
-  fixup_locale ();
-#endif
-
 #ifdef USE_X_TOOLKIT
   /* weiner@footloose.sps.mot.com reports that this causes
      errors with X11R5:
@@ -12845,6 +12868,10 @@ x_initialize ()
   Xt_app_con = XtCreateApplicationContext ();
   XtAppSetFallbackResources (Xt_app_con, Xt_default_resources);
 #endif
+#if USE_TOOLKIT_SCROLL_BARS
+  xaw3d_arrow_scroll = False;
+  xaw3d_pick_top = True;
+#endif
 
   /* Note that there is no real way portable across R3/R4 to get the
      original error handler.  */