1 /* scrollbar implementation -- X interface.
2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
3 Copyright (C) 1994 Amdahl Corporation.
4 Copyright (C) 1995 Sun Microsystems, Inc.
5 Copyright (C) 1995 Darrell Kindred <dkindred+@cmu.edu>.
7 This file is part of XEmacs.
9 XEmacs is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 XEmacs is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with XEmacs; see the file COPYING. If not, write to
21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
24 /* Synched up with: Not in FSF. */
29 #include "console-x.h"
30 #include "EmacsFrame.h"
33 #include "scrollbar-x.h"
38 static void x_update_vertical_scrollbar_callback (Widget widget, LWLIB_ID id,
39 XtPointer client_data);
40 static void x_update_horizontal_scrollbar_callback (Widget widget, LWLIB_ID id,
41 XtPointer client_data);
43 /* Used to prevent changing the size of the slider while drag
44 scrolling, under Motif. This is necessary because the Motif
45 scrollbar is incredibly stupid about updating the slider and causes
46 lots of flicker if it is done too often. */
47 static int inhibit_slider_size_change;
48 int stupid_vertical_scrollbar_drag_hack;
50 /* Doesn't work with athena */
51 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID)
52 static int vertical_drag_in_progress;
56 /* A device method. */
58 x_inhibit_scrollbar_slider_size_change (void)
60 /* Doesn't work with Athena */
61 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID)
62 return inhibit_slider_size_change;
68 /* A device method. */
70 x_free_scrollbar_instance (struct scrollbar_instance *instance)
72 if (SCROLLBAR_X_NAME (instance))
73 xfree (SCROLLBAR_X_NAME (instance));
75 if (SCROLLBAR_X_WIDGET (instance))
77 if (XtIsManaged (SCROLLBAR_X_WIDGET (instance)))
78 XtUnmanageChild (SCROLLBAR_X_WIDGET (instance));
80 lw_destroy_all_widgets (SCROLLBAR_X_ID (instance));
83 if (instance->scrollbar_data)
84 xfree (instance->scrollbar_data);
87 /* A device method. */
89 x_release_scrollbar_instance (struct scrollbar_instance *instance)
91 if (XtIsManaged (SCROLLBAR_X_WIDGET (instance)))
92 XtUnmanageChild (SCROLLBAR_X_WIDGET (instance));
95 /* A device method. */
97 x_create_scrollbar_instance (struct frame *f, int vertical,
98 struct scrollbar_instance *instance)
102 /* initialize the X specific data section. */
103 instance->scrollbar_data = xnew_and_zero (struct x_scrollbar_data);
105 SCROLLBAR_X_ID (instance) = new_lwlib_id ();
106 sprintf (buffer, "scrollbar_%d", SCROLLBAR_X_ID (instance));
107 SCROLLBAR_X_NAME (instance) = xstrdup (buffer);
108 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) || \
109 defined (LWLIB_SCROLLBARS_ATHENA3D)
110 SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) = -1;
115 SCROLLBAR_X_WIDGET (instance) =
116 lw_create_widget ("vertical-scrollbar", SCROLLBAR_X_NAME (instance),
117 SCROLLBAR_X_ID (instance),
118 NULL, FRAME_X_CONTAINER_WIDGET (f), 0,
119 x_update_vertical_scrollbar_callback, NULL, NULL);
123 SCROLLBAR_X_WIDGET (instance) =
124 lw_create_widget ("horizontal-scrollbar", SCROLLBAR_X_NAME (instance),
125 SCROLLBAR_X_ID (instance),
126 NULL, FRAME_X_CONTAINER_WIDGET (f), 0,
127 x_update_horizontal_scrollbar_callback, NULL, NULL);
131 #define UPDATE_DATA_FIELD(field) \
132 if (new_##field >= 0 && \
133 SCROLLBAR_X_POS_DATA (inst).field != new_##field) { \
134 SCROLLBAR_X_POS_DATA (inst).field = new_##field; \
135 inst->scrollbar_instance_changed = 1; \
138 /* A device method. */
139 /* #### The -1 check is such a hack. */
141 x_update_scrollbar_instance_values (struct window *w,
142 struct scrollbar_instance *inst,
143 int new_line_increment,
144 int new_page_increment,
145 int new_minimum, int new_maximum,
147 int new_slider_position,
148 int new_scrollbar_width,
149 int new_scrollbar_height,
150 int new_scrollbar_x, int new_scrollbar_y)
152 UPDATE_DATA_FIELD (line_increment);
153 UPDATE_DATA_FIELD (page_increment);
154 UPDATE_DATA_FIELD (minimum);
155 UPDATE_DATA_FIELD (maximum);
156 UPDATE_DATA_FIELD (slider_size);
157 UPDATE_DATA_FIELD (slider_position);
158 UPDATE_DATA_FIELD (scrollbar_width);
159 UPDATE_DATA_FIELD (scrollbar_height);
160 UPDATE_DATA_FIELD (scrollbar_x);
161 UPDATE_DATA_FIELD (scrollbar_y);
163 /* This doesn't work with Athena, why? */
164 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID)
165 if (w && !vertical_drag_in_progress)
167 int new_vov = SCROLLBAR_X_POS_DATA (inst).slider_position;
168 int new_vows = marker_position (w->start[CURRENT_DISP]);
170 if (SCROLLBAR_X_VDRAG_ORIG_VALUE (inst) != new_vov)
172 SCROLLBAR_X_VDRAG_ORIG_VALUE (inst) = new_vov;
173 inst->scrollbar_instance_changed = 1;
175 if (SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (inst) != new_vows)
177 SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (inst) = new_vows;
178 inst->scrollbar_instance_changed = 1;
184 /* Used by x_update_scrollbar_instance_status. */
186 update_one_scrollbar_bs (struct frame *f, Widget sb_widget)
188 Boolean use_backing_store;
190 Xt_GET_VALUE (FRAME_X_TEXT_WIDGET (f), XtNuseBackingStore, &use_backing_store);
192 if (use_backing_store && sb_widget)
194 unsigned long mask = CWBackingStore;
195 XSetWindowAttributes attrs;
197 attrs.backing_store = Always;
198 XChangeWindowAttributes (XtDisplay (sb_widget),
199 XtWindow (sb_widget),
205 /* Create a widget value structure for passing down to lwlib so that
206 it can update the scrollbar widgets. Used by
207 x_update_scrollbar_instance_status. */
208 static widget_value *
209 scrollbar_instance_to_widget_value (struct scrollbar_instance *instance)
213 wv = xmalloc_widget_value ();
214 /* #### maybe should add malloc_scrollbar_values to resource these? */
215 wv->scrollbar_data = xnew (scrollbar_values);
217 wv->name = SCROLLBAR_X_NAME (instance);
218 wv->name = xstrdup (wv->name);
221 wv->enabled = instance->scrollbar_is_active;
223 wv->call_data = NULL;
225 *wv->scrollbar_data = SCROLLBAR_X_POS_DATA (instance);
232 /* Used by x_update_scrollbar_instance_status. */
234 update_one_widget_scrollbar_pointer (struct window *w, Widget wid)
236 if (POINTER_IMAGE_INSTANCEP (w->scrollbar_pointer))
238 XDefineCursor (XtDisplay (wid), XtWindow (wid),
239 XIMAGE_INSTANCE_X_CURSOR (w->scrollbar_pointer));
240 XSync (XtDisplay (wid), False);
244 /* A device method. */
246 x_update_scrollbar_instance_status (struct window *w, int active, int size,
247 struct scrollbar_instance *instance)
249 struct frame *f = XFRAME (w->frame);
250 Boolean managed = XtIsManaged (SCROLLBAR_X_WIDGET (instance));
254 widget_value *wv = scrollbar_instance_to_widget_value (instance);
256 if (instance->scrollbar_instance_changed)
258 lw_modify_all_widgets (SCROLLBAR_X_ID (instance), wv, 0);
259 instance->scrollbar_instance_changed = 0;
264 XtManageChild (SCROLLBAR_X_WIDGET (instance));
265 if (XtWindow (SCROLLBAR_X_WIDGET (instance)))
267 /* Raise this window so that it's visible on top of the
268 text window below it. */
269 XRaiseWindow (XtDisplay (SCROLLBAR_X_WIDGET (instance)),
270 XtWindow (SCROLLBAR_X_WIDGET (instance)));
271 update_one_widget_scrollbar_pointer
272 (w, SCROLLBAR_X_WIDGET (instance));
273 if (!SCROLLBAR_X_BACKING_STORE_INITIALIZED (instance))
275 update_one_scrollbar_bs (f, SCROLLBAR_X_WIDGET (instance));
276 SCROLLBAR_X_BACKING_STORE_INITIALIZED (instance) = 1;
281 if (!wv->scrollbar_data) abort ();
282 free_widget_value_tree (wv);
286 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID)
287 /* This isn't needed with Athena Scrollbars. It might not be needed */
288 /* with Motif scrollbars (it is apparently needed with Lesstif). */
289 XtUngrabKeyboard (SCROLLBAR_X_WIDGET (instance), CurrentTime);
291 XtUnmanageChild (SCROLLBAR_X_WIDGET (instance));
295 enum x_scrollbar_loop
297 X_FIND_SCROLLBAR_WINDOW_MIRROR,
298 X_SET_SCROLLBAR_POINTER,
299 X_WINDOW_IS_SCROLLBAR,
300 X_UPDATE_FRAME_SCROLLBARS
303 static struct window_mirror *
304 x_scrollbar_loop (enum x_scrollbar_loop type, Lisp_Object window,
305 struct window_mirror *mir,
306 LWLIB_ID id, Window x_win)
308 struct window_mirror *retval = NULL;
312 struct scrollbar_instance *vinstance = mir->scrollbar_vertical_instance;
313 struct scrollbar_instance *hinstance = mir->scrollbar_horizontal_instance;
314 struct window *w = XWINDOW (window);
317 retval = x_scrollbar_loop (type, w->vchild, mir->vchild, id, x_win);
318 else if (mir->hchild)
319 retval = x_scrollbar_loop (type, w->hchild, mir->hchild, id, x_win);
323 if (hinstance || vinstance)
327 case X_FIND_SCROLLBAR_WINDOW_MIRROR:
328 if ((vinstance && SCROLLBAR_X_ID (vinstance) == id) ||
329 (hinstance && SCROLLBAR_X_ID (hinstance) == id))
332 case X_UPDATE_FRAME_SCROLLBARS:
333 if (!mir->vchild && !mir->hchild)
334 update_window_scrollbars (w, mir, 1, 0);
336 case X_SET_SCROLLBAR_POINTER:
337 if (!mir->vchild && !mir->hchild)
341 widget = SCROLLBAR_X_WIDGET (hinstance);
342 if (widget && XtIsManaged (widget))
343 update_one_widget_scrollbar_pointer (w, widget);
345 widget = SCROLLBAR_X_WIDGET (vinstance);
346 if (widget && XtIsManaged (widget))
347 update_one_widget_scrollbar_pointer (w, widget);
350 case X_WINDOW_IS_SCROLLBAR:
351 if (!mir->vchild && !mir->hchild)
355 widget = SCROLLBAR_X_WIDGET (hinstance);
356 if (widget && XtIsManaged (widget) &&
357 XtWindow (widget) == x_win)
358 return (struct window_mirror *) 1;
360 widget = SCROLLBAR_X_WIDGET (vinstance);
361 if (widget && XtIsManaged (widget) &&
362 XtWindow (widget) == x_win)
363 return (struct window_mirror *) 1;
378 /* Used by callbacks. */
379 static struct window_mirror *
380 find_scrollbar_window_mirror (struct frame *f, LWLIB_ID id)
383 update_frame_window_mirror (f);
384 return x_scrollbar_loop (X_FIND_SCROLLBAR_WINDOW_MIRROR, f->root_window,
385 f->root_mirror, id, (Window) NULL);
389 * This is the only callback provided for vertical scrollbars. It
390 * should be able to handle all of the scrollbar events in
391 * scroll_action (see lwlib.h). The client data will be of type
392 * scroll_event (see lwlib.h). */
394 x_update_vertical_scrollbar_callback (Widget widget, LWLIB_ID id,
395 XtPointer client_data)
397 /* This function can GC */
398 scroll_event *data = (scroll_event *) client_data;
399 struct device *d = get_device_from_display (XtDisplay (widget));
400 struct frame *f = x_any_window_to_frame (d, XtWindow (widget));
401 Lisp_Object win, frame;
402 struct scrollbar_instance *instance;
403 struct window_mirror *mirror;
408 mirror = find_scrollbar_window_mirror (f, id);
412 win = real_window (mirror, 1);
416 instance = mirror->scrollbar_vertical_instance;
417 frame = WINDOW_FRAME (XWINDOW (win));
419 /* It seems that this is necessary whenever signal_special_Xt_user_event()
420 is called. #### Why??? */
421 DEVICE_X_MOUSE_TIMESTAMP (d) = DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d);
423 switch (data->action)
425 case SCROLLBAR_LINE_UP:
426 signal_special_Xt_user_event (frame, Qscrollbar_line_up, win);
429 case SCROLLBAR_LINE_DOWN:
430 signal_special_Xt_user_event (frame, Qscrollbar_line_down, win);
433 /* The Athena scrollbar paging behavior is that of xterms.
434 Depending on where you click the size of the page varies.
435 Motif always does a standard Emacs page. */
436 case SCROLLBAR_PAGE_UP:
437 #if !defined (LWLIB_SCROLLBARS_MOTIF) && !defined (LWLIB_SCROLLBARS_LUCID) && \
438 !defined (LWLIB_SCROLLBARS_ATHENA3D)
440 double tmp = ((double) data->slider_value /
441 (double) SCROLLBAR_X_POS_DATA(instance).scrollbar_height);
443 (double) window_displayed_height (XWINDOW (win));
447 signal_special_Xt_user_event (frame, Qscrollbar_page_up,
448 Fcons (win, make_int ((int) line)));
451 signal_special_Xt_user_event (frame, Qscrollbar_page_up,
456 case SCROLLBAR_PAGE_DOWN:
457 #if !defined (LWLIB_SCROLLBARS_MOTIF) && !defined (LWLIB_SCROLLBARS_LUCID) && \
458 !defined (LWLIB_SCROLLBARS_ATHENA3D)
460 double tmp = ((double) data->slider_value /
461 (double) SCROLLBAR_X_POS_DATA(instance).scrollbar_height);
463 (double) window_displayed_height (XWINDOW (win));
465 if (SCROLLBAR_X_POS_DATA(instance).maximum >
466 (SCROLLBAR_X_POS_DATA(instance).slider_size + SCROLLBAR_X_POS_DATA(instance).slider_position))
470 signal_special_Xt_user_event (frame, Qscrollbar_page_down,
472 make_int ((int) line)));
476 signal_special_Xt_user_event (frame, Qscrollbar_page_down,
482 signal_special_Xt_user_event (frame, Qscrollbar_to_top, win);
485 case SCROLLBAR_BOTTOM:
486 signal_special_Xt_user_event (frame, Qscrollbar_to_bottom, win);
490 case SCROLLBAR_CHANGE:
491 inhibit_slider_size_change = 0;
492 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID)
493 vertical_drag_in_progress = 0;
494 SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) = data->slider_value;
495 SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance) =
496 XINT (Fwindow_start (win));
498 stupid_vertical_scrollbar_drag_hack = 0;
506 inhibit_slider_size_change = 1;
508 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID)
509 /* Doing drags with Motif-like scrollbars is a mess, since we
510 want to avoid having the window position jump when you
511 first grab the scrollbar, but we also want to ensure that
512 you can scroll all the way to the top or bottom of the
513 buffer. This can all be replaced with something sane when
514 we get line-based scrolling. */
516 vertical_drag_in_progress = 1;
518 if (SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) < 0)
520 SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) = data->slider_value;
521 SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance) =
522 XINT (Fwindow_start (win));
525 /* Could replace this piecewise linear scrolling with a
526 quadratic through the three points, but I'm not sure that
527 would feel any nicer in practice. */
528 if (data->slider_value < SCROLLBAR_X_VDRAG_ORIG_VALUE (instance))
530 /* We've dragged up; slide linearly from original position to
531 window-start=data.minimum, slider-value=data.minimum. */
533 if (SCROLLBAR_X_VDRAG_ORIG_VALUE (instance)
534 <= SCROLLBAR_X_POS_DATA (instance).minimum)
536 /* shouldn't get here, but just in case */
537 value = SCROLLBAR_X_POS_DATA (instance).minimum;
542 (SCROLLBAR_X_POS_DATA (instance).minimum
544 (SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance)
545 - SCROLLBAR_X_POS_DATA (instance).minimum)
546 * (data->slider_value -
547 SCROLLBAR_X_POS_DATA (instance).minimum))
548 / (SCROLLBAR_X_VDRAG_ORIG_VALUE (instance)
549 - SCROLLBAR_X_POS_DATA (instance).minimum)));
554 /* We've dragged down; slide linearly from original position to
555 window-start=data.maximum, slider-value=data.maximum. */
557 if (SCROLLBAR_X_VDRAG_ORIG_VALUE (instance)
558 >= (SCROLLBAR_X_POS_DATA (instance).maximum -
559 SCROLLBAR_X_POS_DATA (instance).slider_size))
561 /* avoid divide by zero */
562 value = SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance);
567 (SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance)
569 (SCROLLBAR_X_POS_DATA (instance).maximum
570 - SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance))
571 * (data->slider_value
572 - SCROLLBAR_X_VDRAG_ORIG_VALUE (instance)))
573 / (SCROLLBAR_X_POS_DATA (instance).maximum
574 - SCROLLBAR_X_POS_DATA (instance).slider_size
575 - SCROLLBAR_X_VDRAG_ORIG_VALUE (instance))));
579 stupid_vertical_scrollbar_drag_hack = 0;
580 value = data->slider_value;
583 if (value >= SCROLLBAR_X_POS_DATA (instance).maximum)
584 value = SCROLLBAR_X_POS_DATA (instance).maximum - 1;
585 if (value < SCROLLBAR_X_POS_DATA (instance).minimum)
586 value = SCROLLBAR_X_POS_DATA (instance).minimum;
588 signal_special_Xt_user_event (frame, Qscrollbar_vertical_drag,
589 Fcons (win, make_int (value)));
597 * This is the only callback provided for horizontal scrollbars. It
598 * should be able to handle all of the scrollbar events in
599 * scroll_action (see lwlib.h). The client data will be of type
600 * scroll_event (see lwlib.h). */
602 x_update_horizontal_scrollbar_callback (Widget widget, LWLIB_ID id,
603 XtPointer client_data)
605 scroll_event *data = (scroll_event *) client_data;
606 struct device *d = get_device_from_display (XtDisplay (widget));
607 struct frame *f = x_any_window_to_frame (d, XtWindow (widget));
608 Lisp_Object win, frame;
609 struct window_mirror *mirror;
614 mirror = find_scrollbar_window_mirror (f, id);
618 win = real_window (mirror, 1);
622 frame = WINDOW_FRAME (XWINDOW (win));
624 /* It seems that this is necessary whenever signal_special_Xt_user_event()
625 is called. #### Why??? */
626 DEVICE_X_MOUSE_TIMESTAMP (d) = DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d);
628 switch (data->action)
630 case SCROLLBAR_LINE_UP:
631 signal_special_Xt_user_event (frame, Qscrollbar_char_left, win);
633 case SCROLLBAR_LINE_DOWN:
634 signal_special_Xt_user_event (frame, Qscrollbar_char_right, win);
636 case SCROLLBAR_PAGE_UP:
637 signal_special_Xt_user_event (frame, Qscrollbar_page_left, win);
639 case SCROLLBAR_PAGE_DOWN:
640 signal_special_Xt_user_event (frame, Qscrollbar_page_right, win);
643 signal_special_Xt_user_event (frame, Qscrollbar_to_left, win);
645 case SCROLLBAR_BOTTOM:
646 signal_special_Xt_user_event (frame, Qscrollbar_to_right, win);
648 case SCROLLBAR_CHANGE:
649 inhibit_slider_size_change = 0;
652 inhibit_slider_size_change = 1;
653 /* #### Fix the damn toolkit code so they all work the same way.
654 Lucid is the one mostly wrong.*/
655 #if defined (LWLIB_SCROLLBARS_LUCID) || defined (LWLIB_SCROLLBARS_ATHENA3D)
656 signal_special_Xt_user_event (frame, Qscrollbar_horizontal_drag,
658 (win, make_int (data->slider_value))));
660 signal_special_Xt_user_event (frame, Qscrollbar_horizontal_drag,
663 make_int (data->slider_value - 1))));
672 x_scrollbar_pointer_changed_in_window (struct window *w)
676 XSETWINDOW (window, w);
677 x_scrollbar_loop (X_SET_SCROLLBAR_POINTER, window, find_window_mirror (w),
681 /* Make sure that all scrollbars on frame are up-to-date. Called
682 directly from x_set_frame_properties in frame-x.c*/
684 x_update_frame_scrollbars (struct frame *f)
686 /* Consider this code to be "in_display" so that we abort() if Fsignal()
689 x_scrollbar_loop (X_UPDATE_FRAME_SCROLLBARS, f->root_window, f->root_mirror,
692 if (in_display < 0) abort ();
695 #ifdef MEMORY_USAGE_STATS
698 x_compute_scrollbar_instance_usage (struct device *d,
699 struct scrollbar_instance *inst,
700 struct overhead_stats *ovstats)
706 struct x_scrollbar_data *data =
707 (struct x_scrollbar_data *) inst->scrollbar_data;
709 total += malloced_storage_size (data, sizeof (*data), ovstats);
710 total += malloced_storage_size (data->name, 1 + strlen (data->name),
718 #endif /* MEMORY_USAGE_STATS */
721 /************************************************************************/
723 /************************************************************************/
726 console_type_create_scrollbar_x (void)
728 CONSOLE_HAS_METHOD (x, inhibit_scrollbar_slider_size_change);
729 CONSOLE_HAS_METHOD (x, free_scrollbar_instance);
730 CONSOLE_HAS_METHOD (x, release_scrollbar_instance);
731 CONSOLE_HAS_METHOD (x, create_scrollbar_instance);
732 CONSOLE_HAS_METHOD (x, update_scrollbar_instance_values);
733 CONSOLE_HAS_METHOD (x, update_scrollbar_instance_status);
734 CONSOLE_HAS_METHOD (x, scrollbar_pointer_changed_in_window);
735 #ifdef MEMORY_USAGE_STATS
736 CONSOLE_HAS_METHOD (x, compute_scrollbar_instance_usage);
737 #endif /* MEMORY_USAGE_STATS */
741 reinit_vars_of_scrollbar_x (void)
743 stupid_vertical_scrollbar_drag_hack = 1;
747 vars_of_scrollbar_x (void)
749 reinit_vars_of_scrollbar_x ();
751 #if defined (LWLIB_SCROLLBARS_LUCID)
752 Fprovide (intern ("lucid-scrollbars"));
753 #elif defined (LWLIB_SCROLLBARS_MOTIF)
754 Fprovide (intern ("motif-scrollbars"));
755 #elif defined (LWLIB_SCROLLBARS_ATHENA)
756 Fprovide (intern ("athena-scrollbars"));