Commit ec18280f authored by Stefan Monnier's avatar Stefan Monnier
Browse files

(#includes): Allow compilation with only Xaw.

(xaw3d_arrow_scroll, xaw3d_pick_top): New variables.
(xt_action_hook): Replace XAW3D by XAW.
(xaw3d_jump_callback): Renamed to xaw_jump_callback.
(xaw_jump_callback): Renamed from xaw3d_jump_callback.
Determine epsilon dynamically and don't try to be too clever.
(xaw3d_scroll_callback): Renamed to xaw_scroll_callback.
(xaw_scroll_callback): Renamed from xaw3d_scroll_callback.
Handle both Xaw3d with arrow-scrollbars and with Xaw-style
scrollbar (using `ratio').
(x_create_toolkit_scroll_bar): Try to detect which style of Xaw3d
scrollbar we have so as to set it up more optimally and to fix
xaw3d_arrow_scroll and xaw3d_pick_top.
(x_set_toolkit_scroll_bar_thumb): Try to maintain 2 spare pixels at the
bottom of the Xaw3d scrollbar, to work around its tendency to refuse
shrinking the thumb.  Also make sure that `XawScrollbarSetThumb'
is not ignored, using a major gross hack.
(x_initialize): Init default values for xaw3d_arrow_scroll and
xaw3d_pick_top.
parent eef28553
No preview for this file type
...@@ -118,13 +118,21 @@ extern void _XEditResCheckMessages (); ...@@ -118,13 +118,21 @@ extern void _XEditResCheckMessages ();
#include <Xm/Xm.h> /* for LESSTIF_VERSION */ #include <Xm/Xm.h> /* for LESSTIF_VERSION */
#include <Xm/ScrollBar.h> #include <Xm/ScrollBar.h>
#include <Xm/ScrollBarP.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/Simple.h>
#include <X11/Xaw3d/ThreeD.h>
#include <X11/Xaw3d/Scrollbar.h> #include <X11/Xaw3d/Scrollbar.h>
#define ARROW_SCROLLBAR #define ARROW_SCROLLBAR
#include <X11/Xaw3d/ScrollbarP.h> #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_TOOLKIT_SCROLL_BARS */
#endif /* USE_X_TOOLKIT */ #endif /* USE_X_TOOLKIT */
...@@ -7101,9 +7109,20 @@ static Lisp_Object window_being_scrolled; ...@@ -7101,9 +7109,20 @@ static Lisp_Object window_being_scrolled;
static int last_scroll_bar_part; 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 /* 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 the user ends an interaction with the scroll bar, and generates
a `end-scroll' scroll_bar_click' event if so. */ a `end-scroll' scroll_bar_click' event if so. */
...@@ -7123,12 +7142,10 @@ xt_action_hook (widget, client_data, action_name, event, params, ...@@ -7123,12 +7142,10 @@ xt_action_hook (widget, client_data, action_name, event, params,
#ifdef USE_MOTIF #ifdef USE_MOTIF
scroll_bar_p = XmIsScrollBar (widget); scroll_bar_p = XmIsScrollBar (widget);
end_action = "Release"; end_action = "Release";
#elif defined HAVE_XAW3D #else /* !USE_MOTIF i.e. use Xaw */
scroll_bar_p = XtIsSubclass (widget, scrollbarWidgetClass); scroll_bar_p = XtIsSubclass (widget, scrollbarWidgetClass);
end_action = "EndScroll"; end_action = "EndScroll";
#else #endif /* USE_MOTIF */
#error unknown scroll bar toolkit
#endif /* HAVE_XAW3D */
/* Although LessTif uses XtTimeouts like Xaw3d, the timer hack to /* Although LessTif uses XtTimeouts like Xaw3d, the timer hack to
let Xt timeouts be processed doesn't work. */ let Xt timeouts be processed doesn't work. */
...@@ -7313,40 +7330,39 @@ xm_scroll_callback (widget, client_data, call_data) ...@@ -7313,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 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 scroll bar struct. CALL_DATA is a pointer to a float saying where
the thumb is. */ the thumb is. */
static void static void
xaw3d_jump_callback (widget, client_data, call_data) xaw_jump_callback (widget, client_data, call_data)
Widget widget; Widget widget;
XtPointer client_data, call_data; XtPointer client_data, call_data;
{ {
struct scroll_bar *bar = (struct scroll_bar *) client_data; struct scroll_bar *bar = (struct scroll_bar *) client_data;
float top = *(float *) call_data; float top = *(float *) call_data;
float shown; float shown;
int whole, portion; int whole, portion, height;
int dragging_down_p, part; int part;
double epsilon = 0.01;
/* Get the size of the thumb, a value between 0 and 1. */ /* Get the size of the thumb, a value between 0 and 1. */
BLOCK_INPUT; BLOCK_INPUT;
XtVaGetValues (widget, XtNshown, &shown, NULL); XtVaGetValues (widget, XtNshown, &shown, XtNheight, &height, NULL);
UNBLOCK_INPUT; UNBLOCK_INPUT;
whole = 10000000; whole = 10000000;
portion = shown < 1 ? top * whole : 0; portion = shown < 1 ? top * whole : 0;
dragging_down_p = (INTEGERP (bar->dragging)
&& XINT (bar->dragging) < portion);
if (shown < 1 if (shown < 1 && (abs (top + shown - 1) < 1.0/height))
&& (abs (top + shown - 1) < epsilon /* Some derivatives of Xaw refuse to shrink the thumb when you reach
|| (dragging_down_p the bottom, so we force the scrolling whenever we see that we're
&& last_scroll_bar_part == scroll_bar_down_arrow))) 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; part = scroll_bar_down_arrow;
else else
part = scroll_bar_handle; part = scroll_bar_handle;
...@@ -7358,8 +7374,8 @@ xaw3d_jump_callback (widget, client_data, call_data) ...@@ -7358,8 +7374,8 @@ xaw3d_jump_callback (widget, client_data, call_data)
} }
/* Xaw3d scroll bar callback. Invoked for incremental scrolling., /* Xaw scroll bar callback. Invoked for incremental scrolling.,
i.e. line or page up or down. WIDGET is the Xaw3d scroll bar 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 widget. CLIENT_DATA is a pointer to the scroll_bar structure for
the scroll bar. CALL_DATA is an integer specifying the action that 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 has taken place. It's magnitude is in the range 0..height of the
...@@ -7367,7 +7383,7 @@ xaw3d_jump_callback (widget, client_data, call_data) ...@@ -7367,7 +7383,7 @@ xaw3d_jump_callback (widget, client_data, call_data)
Values < height of scroll bar mean line-wise movement. */ Values < height of scroll bar mean line-wise movement. */
static void static void
xaw3d_scroll_callback (widget, client_data, call_data) xaw_scroll_callback (widget, client_data, call_data)
Widget widget; Widget widget;
XtPointer client_data, call_data; XtPointer client_data, call_data;
{ {
...@@ -7381,25 +7397,20 @@ xaw3d_scroll_callback (widget, client_data, call_data) ...@@ -7381,25 +7397,20 @@ xaw3d_scroll_callback (widget, client_data, call_data)
XtVaGetValues (widget, XtNheight, &height, NULL); XtVaGetValues (widget, XtNheight, &height, NULL);
UNBLOCK_INPUT; UNBLOCK_INPUT;
if (position < 0) if (abs (position) >= height)
{ part = (position < 0) ? scroll_bar_above_handle : scroll_bar_below_handle;
if (abs (position) < height)
part = scroll_bar_up_arrow; /* If Xaw3d was compiled with ARROW_SCROLLBAR,
else it maps line-movement to call_data = max(5, height/20). */
part = scroll_bar_above_handle; 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 else
part = scroll_bar_below_handle; part = scroll_bar_move_ratio;
}
window_being_scrolled = bar->window; window_being_scrolled = bar->window;
bar->dragging = Qnil; bar->dragging = Qnil;
last_scroll_bar_part = part; 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);
} }
...@@ -7482,7 +7493,7 @@ x_create_toolkit_scroll_bar (f, bar) ...@@ -7482,7 +7493,7 @@ x_create_toolkit_scroll_bar (f, bar)
XDefineCursor (XtDisplay (widget), XtWindow (widget), XDefineCursor (XtDisplay (widget), XtWindow (widget),
f->output_data.x->nontext_cursor); 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 /* Set resources. Create the widget. The background of the
Xaw3d scroll bar widget is a little bit light for my taste. Xaw3d scroll bar widget is a little bit light for my taste.
...@@ -7490,8 +7501,9 @@ x_create_toolkit_scroll_bar (f, bar) ...@@ -7490,8 +7501,9 @@ x_create_toolkit_scroll_bar (f, bar)
to their taste with `emacs*verticalScrollBar.background: xxx'. */ to their taste with `emacs*verticalScrollBar.background: xxx'. */
XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac; XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac;
XtSetArg (av[ac], XtNorientation, XtorientVertical); ++ac; XtSetArg (av[ac], XtNorientation, XtorientVertical); ++ac;
XtSetArg (av[ac], XtNcursorName, "left_ptr"); ++ac; /* For smoother scrolling with Xaw3d -sm */
XtSetArg (av[ac], XtNbeNiceToColormap, True); ++ac; /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */
/* XtSetArg (av[ac], XtNbeNiceToColormap, True); ++ac; */
pixel = f->output_data.x->scroll_bar_foreground_pixel; pixel = f->output_data.x->scroll_bar_foreground_pixel;
if (pixel != -1) if (pixel != -1)
...@@ -7510,15 +7522,28 @@ x_create_toolkit_scroll_bar (f, bar) ...@@ -7510,15 +7522,28 @@ x_create_toolkit_scroll_bar (f, bar)
widget = XtCreateWidget (scroll_bar_name, scrollbarWidgetClass, widget = XtCreateWidget (scroll_bar_name, scrollbarWidgetClass,
f->output_data.x->edit_widget, av, ac); 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. */ /* Define callbacks. */
XtAddCallback (widget, XtNjumpProc, xaw3d_jump_callback, (XtPointer) bar); XtAddCallback (widget, XtNjumpProc, xaw_jump_callback, (XtPointer) bar);
XtAddCallback (widget, XtNscrollProc, xaw3d_scroll_callback, XtAddCallback (widget, XtNscrollProc, xaw_scroll_callback,
(XtPointer) bar); (XtPointer) bar);
/* Realize the widget. Only after that is the X window created. */ /* Realize the widget. Only after that is the X window created. */
XtRealizeWidget (widget); XtRealizeWidget (widget);
#endif /* HAVE_XAW3D */ #endif /* !USE_MOTIF */
/* Install an action hook that let's us detect when the user /* Install an action hook that let's us detect when the user
finishes interacting with a scroll bar. */ finishes interacting with a scroll bar. */
...@@ -7562,7 +7587,7 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole) ...@@ -7562,7 +7587,7 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
unsigned char flags; unsigned char flags;
XmScrollBarWidget sb; 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 is the scroll bar's maximum and MIN is the scroll bar's minimum
value. */ value. */
size = shown * XM_SB_RANGE; size = shown * XM_SB_RANGE;
...@@ -7590,7 +7615,7 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole) ...@@ -7590,7 +7615,7 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
XmScrollBarSetValues (widget, value, size, 0, 0, False); XmScrollBarSetValues (widget, value, size, 0, 0, False);
else if (last_scroll_bar_part == scroll_bar_down_arrow) else if (last_scroll_bar_part == scroll_bar_down_arrow)
/* This has the negative side effect that the slider value is /* 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. */ page-wise movement. */
XmScrollBarSetValues (widget, value, XM_SB_RANGE - value, 0, 0, False); XmScrollBarSetValues (widget, value, XM_SB_RANGE - value, 0, 0, False);
else else
...@@ -7610,43 +7635,61 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole) ...@@ -7610,43 +7635,61 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
sb->scrollBar.arrow2_selected = arrow2_selected; sb->scrollBar.arrow2_selected = arrow2_selected;
sb->scrollBar.flags = flags; sb->scrollBar.flags = flags;
} }
#elif defined HAVE_XAW3D #else /* !USE_MOTIF i.e. use Xaw */
{ {
/* Restrict to [0 1]. */ 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)); top = max (0, min (1, top));
shown = max (0, min (1, shown)); 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, /* If the call to XawScrollbarSetThumb below doesn't seem to work,
check that your system's configuration file contains a define check that your system's configuration file contains a define
for `NARROWPROTO'. See s/freebsd.h for an example. */ for `NARROWPROTO'. See s/freebsd.h for an example. */
if (NILP (bar->dragging))
{
float old_top, old_shown;
XtVaGetValues (widget, XtNtopOfThumb, &old_top, XtNshown, &old_shown,
NULL);
if (top != old_top || shown != old_shown) if (top != old_top || shown != old_shown)
{
if (NILP (bar->dragging))
XawScrollbarSetThumb (widget, top, shown); XawScrollbarSetThumb (widget, top, shown);
}
else else
{ {
#ifdef HAVE_XAW3D
ScrollbarWidget sb = (ScrollbarWidget) widget; ScrollbarWidget sb = (ScrollbarWidget) widget;
int scroll_mode = sb->scrollbar.scroll_mode; int scroll_mode;
sb->scrollbar.scroll_mode = 0;
if (last_scroll_bar_part == scroll_bar_down_arrow) /* `scroll_mode' only exists with Xaw3d + ARROW_SCROLLBAR. */
XawScrollbarSetThumb (widget, top, 1 - top); if (xaw3d_arrow_scroll)
else
{ {
float old_top; /* Xaw3d stupidly ignores resize requests while dragging
XtVaGetValues (widget, XtNtopOfThumb, &old_top, NULL); so we have to make it believe it's not in dragging mode. */
XawScrollbarSetThumb (widget, old_top, min (shown, 1 - old_top)); 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; sb->scrollbar.scroll_mode = scroll_mode;
#endif
}
} }
} }
#endif /* HAVE_XAW3D */ #endif /* !USE_MOTIF */
UNBLOCK_INPUT; UNBLOCK_INPUT;
} }
...@@ -12824,6 +12867,8 @@ x_initialize () ...@@ -12824,6 +12867,8 @@ x_initialize ()
XtToolkitInitialize (); XtToolkitInitialize ();
Xt_app_con = XtCreateApplicationContext (); Xt_app_con = XtCreateApplicationContext ();
XtAppSetFallbackResources (Xt_app_con, Xt_default_resources); XtAppSetFallbackResources (Xt_app_con, Xt_default_resources);
xaw3d_arrow_scroll = False;
xaw3d_pick_top = True;
#endif #endif
/* Note that there is no real way portable across R3/R4 to get the /* Note that there is no real way portable across R3/R4 to get the
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment