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. */
26 /* This file Mule-ized (more like Mule-verified) by Ben Wing, 7-8-00. */
31 #include "console-x.h"
32 #include "EmacsFrame.h"
35 #include "scrollbar-x.h"
40 static void x_update_vertical_scrollbar_callback (Widget widget, LWLIB_ID id,
41 XtPointer client_data);
42 static void x_update_horizontal_scrollbar_callback (Widget widget, LWLIB_ID id,
43 XtPointer client_data);
45 /* Used to prevent changing the size of the slider while drag
46 scrolling, under Motif. This is necessary because the Motif
47 scrollbar is incredibly stupid about updating the slider and causes
48 lots of flicker if it is done too often. */
49 static int inhibit_slider_size_change;
50 int stupid_vertical_scrollbar_drag_hack;
52 /* Doesn't work with athena */
53 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID)
54 static int vertical_drag_in_progress;
58 /* A device method. */
60 x_inhibit_scrollbar_slider_size_change (void)
62 /* Doesn't work with Athena */
63 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID)
64 return inhibit_slider_size_change;
70 /* A device method. */
72 x_free_scrollbar_instance (struct scrollbar_instance *instance)
74 if (SCROLLBAR_X_NAME (instance))
75 xfree (SCROLLBAR_X_NAME (instance));
77 if (SCROLLBAR_X_WIDGET (instance))
79 if (XtIsManaged (SCROLLBAR_X_WIDGET (instance)))
80 XtUnmanageChild (SCROLLBAR_X_WIDGET (instance));
82 lw_destroy_all_widgets (SCROLLBAR_X_ID (instance));
85 if (instance->scrollbar_data)
86 xfree (instance->scrollbar_data);
89 /* A device method. */
91 x_release_scrollbar_instance (struct scrollbar_instance *instance)
93 if (XtIsManaged (SCROLLBAR_X_WIDGET (instance)))
94 XtUnmanageChild (SCROLLBAR_X_WIDGET (instance));
97 /* A device method. */
99 x_create_scrollbar_instance (struct frame *f, int vertical,
100 struct scrollbar_instance *instance)
104 /* initialize the X specific data section. */
105 instance->scrollbar_data = xnew_and_zero (struct x_scrollbar_data);
107 SCROLLBAR_X_ID (instance) = new_lwlib_id ();
108 sprintf (buffer, "scrollbar_%d", SCROLLBAR_X_ID (instance));
109 SCROLLBAR_X_NAME (instance) = xstrdup (buffer);
110 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) || \
111 defined (LWLIB_SCROLLBARS_ATHENA3D)
112 SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) = -1;
117 SCROLLBAR_X_WIDGET (instance) =
118 lw_create_widget ("vertical-scrollbar", SCROLLBAR_X_NAME (instance),
119 SCROLLBAR_X_ID (instance),
120 NULL, FRAME_X_CONTAINER_WIDGET (f), 0,
121 x_update_vertical_scrollbar_callback, NULL, NULL);
125 SCROLLBAR_X_WIDGET (instance) =
126 lw_create_widget ("horizontal-scrollbar", SCROLLBAR_X_NAME (instance),
127 SCROLLBAR_X_ID (instance),
128 NULL, FRAME_X_CONTAINER_WIDGET (f), 0,
129 x_update_horizontal_scrollbar_callback, NULL, NULL);
133 #define UPDATE_DATA_FIELD(field) \
134 if (new_##field >= 0 && \
135 SCROLLBAR_X_POS_DATA (inst).field != new_##field) { \
136 SCROLLBAR_X_POS_DATA (inst).field = new_##field; \
137 inst->scrollbar_instance_changed = 1; \
140 /* A device method. */
141 /* #### The -1 check is such a hack. */
143 x_update_scrollbar_instance_values (struct window *w,
144 struct scrollbar_instance *inst,
145 int new_line_increment,
146 int new_page_increment,
147 int new_minimum, int new_maximum,
149 int new_slider_position,
150 int new_scrollbar_width,
151 int new_scrollbar_height,
152 int new_scrollbar_x, int new_scrollbar_y)
154 UPDATE_DATA_FIELD (line_increment);
155 UPDATE_DATA_FIELD (page_increment);
156 UPDATE_DATA_FIELD (minimum);
157 UPDATE_DATA_FIELD (maximum);
158 UPDATE_DATA_FIELD (slider_size);
159 UPDATE_DATA_FIELD (slider_position);
160 UPDATE_DATA_FIELD (scrollbar_width);
161 UPDATE_DATA_FIELD (scrollbar_height);
162 UPDATE_DATA_FIELD (scrollbar_x);
163 UPDATE_DATA_FIELD (scrollbar_y);
165 /* This doesn't work with Athena, why? */
166 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID)
167 if (w && !vertical_drag_in_progress)
169 int new_vov = SCROLLBAR_X_POS_DATA (inst).slider_position;
170 int new_vows = marker_position (w->start[CURRENT_DISP]);
172 if (SCROLLBAR_X_VDRAG_ORIG_VALUE (inst) != new_vov)
174 SCROLLBAR_X_VDRAG_ORIG_VALUE (inst) = new_vov;
175 inst->scrollbar_instance_changed = 1;
177 if (SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (inst) != new_vows)
179 SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (inst) = new_vows;
180 inst->scrollbar_instance_changed = 1;
186 /* Used by x_update_scrollbar_instance_status. */
188 update_one_scrollbar_bs (struct frame *f, Widget sb_widget)
190 Boolean use_backing_store;
192 Xt_GET_VALUE (FRAME_X_TEXT_WIDGET (f), XtNuseBackingStore, &use_backing_store);
194 if (use_backing_store && sb_widget)
196 unsigned long mask = CWBackingStore;
197 XSetWindowAttributes attrs;
199 attrs.backing_store = Always;
200 XChangeWindowAttributes (XtDisplay (sb_widget),
201 XtWindow (sb_widget),
207 /* Create a widget value structure for passing down to lwlib so that
208 it can update the scrollbar widgets. Used by
209 x_update_scrollbar_instance_status. */
210 static widget_value *
211 scrollbar_instance_to_widget_value (struct scrollbar_instance *instance)
215 wv = xmalloc_widget_value ();
216 /* #### maybe should add malloc_scrollbar_values to resource these? */
217 wv->scrollbar_data = xnew (scrollbar_values);
219 wv->name = SCROLLBAR_X_NAME (instance);
220 wv->name = xstrdup (wv->name);
223 wv->enabled = instance->scrollbar_is_active;
225 wv->call_data = NULL;
227 *wv->scrollbar_data = SCROLLBAR_X_POS_DATA (instance);
234 /* Used by x_update_scrollbar_instance_status. */
236 update_one_widget_scrollbar_pointer (struct window *w, Widget wid)
238 if (POINTER_IMAGE_INSTANCEP (w->scrollbar_pointer))
240 XDefineCursor (XtDisplay (wid), XtWindow (wid),
241 XIMAGE_INSTANCE_X_CURSOR (w->scrollbar_pointer));
242 XSync (XtDisplay (wid), False);
246 /* A device method. */
248 x_update_scrollbar_instance_status (struct window *w, int active, int size,
249 struct scrollbar_instance *instance)
251 struct frame *f = XFRAME (w->frame);
252 Boolean managed = XtIsManaged (SCROLLBAR_X_WIDGET (instance));
256 widget_value *wv = scrollbar_instance_to_widget_value (instance);
258 if (instance->scrollbar_instance_changed)
260 lw_modify_all_widgets (SCROLLBAR_X_ID (instance), wv, 0);
261 instance->scrollbar_instance_changed = 0;
266 XtManageChild (SCROLLBAR_X_WIDGET (instance));
267 if (XtWindow (SCROLLBAR_X_WIDGET (instance)))
269 /* Raise this window so that it's visible on top of the
270 text window below it. */
271 XRaiseWindow (XtDisplay (SCROLLBAR_X_WIDGET (instance)),
272 XtWindow (SCROLLBAR_X_WIDGET (instance)));
273 update_one_widget_scrollbar_pointer
274 (w, SCROLLBAR_X_WIDGET (instance));
275 if (!SCROLLBAR_X_BACKING_STORE_INITIALIZED (instance))
277 update_one_scrollbar_bs (f, SCROLLBAR_X_WIDGET (instance));
278 SCROLLBAR_X_BACKING_STORE_INITIALIZED (instance) = 1;
283 if (!wv->scrollbar_data) abort ();
284 free_widget_value_tree (wv);
288 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID)
289 /* This isn't needed with Athena Scrollbars. It might not be needed */
290 /* with Motif scrollbars (it is apparently needed with Lesstif). */
291 XtUngrabKeyboard (SCROLLBAR_X_WIDGET (instance), CurrentTime);
293 XtUnmanageChild (SCROLLBAR_X_WIDGET (instance));
297 enum x_scrollbar_loop
299 X_FIND_SCROLLBAR_WINDOW_MIRROR,
300 X_SET_SCROLLBAR_POINTER,
301 X_WINDOW_IS_SCROLLBAR,
302 X_UPDATE_FRAME_SCROLLBARS
305 static struct window_mirror *
306 x_scrollbar_loop (enum x_scrollbar_loop type, Lisp_Object window,
307 struct window_mirror *mir,
308 LWLIB_ID id, Window x_win)
310 struct window_mirror *retval = NULL;
314 struct scrollbar_instance *vinstance = mir->scrollbar_vertical_instance;
315 struct scrollbar_instance *hinstance = mir->scrollbar_horizontal_instance;
316 struct window *w = XWINDOW (window);
319 retval = x_scrollbar_loop (type, w->vchild, mir->vchild, id, x_win);
320 else if (mir->hchild)
321 retval = x_scrollbar_loop (type, w->hchild, mir->hchild, id, x_win);
325 if (hinstance || vinstance)
329 case X_FIND_SCROLLBAR_WINDOW_MIRROR:
330 if ((vinstance && SCROLLBAR_X_ID (vinstance) == id) ||
331 (hinstance && SCROLLBAR_X_ID (hinstance) == id))
334 case X_UPDATE_FRAME_SCROLLBARS:
335 if (!mir->vchild && !mir->hchild)
336 update_window_scrollbars (w, mir, 1, 0);
338 case X_SET_SCROLLBAR_POINTER:
339 if (!mir->vchild && !mir->hchild)
343 widget = SCROLLBAR_X_WIDGET (hinstance);
344 if (widget && XtIsManaged (widget))
345 update_one_widget_scrollbar_pointer (w, widget);
347 widget = SCROLLBAR_X_WIDGET (vinstance);
348 if (widget && XtIsManaged (widget))
349 update_one_widget_scrollbar_pointer (w, widget);
352 case X_WINDOW_IS_SCROLLBAR:
353 if (!mir->vchild && !mir->hchild)
357 widget = SCROLLBAR_X_WIDGET (hinstance);
358 if (widget && XtIsManaged (widget) &&
359 XtWindow (widget) == x_win)
360 return (struct window_mirror *) 1;
362 widget = SCROLLBAR_X_WIDGET (vinstance);
363 if (widget && XtIsManaged (widget) &&
364 XtWindow (widget) == x_win)
365 return (struct window_mirror *) 1;
380 /* Used by callbacks. */
381 static struct window_mirror *
382 find_scrollbar_window_mirror (struct frame *f, LWLIB_ID id)
385 update_frame_window_mirror (f);
386 return x_scrollbar_loop (X_FIND_SCROLLBAR_WINDOW_MIRROR, f->root_window,
387 f->root_mirror, id, (Window) NULL);
391 * This is the only callback provided for vertical scrollbars. It
392 * should be able to handle all of the scrollbar events in
393 * scroll_action (see lwlib.h). The client data will be of type
394 * scroll_event (see lwlib.h). */
396 x_update_vertical_scrollbar_callback (Widget widget, LWLIB_ID id,
397 XtPointer client_data)
399 /* This function can GC */
400 scroll_event *data = (scroll_event *) client_data;
401 struct device *d = get_device_from_display (XtDisplay (widget));
402 struct frame *f = x_any_window_to_frame (d, XtWindow (widget));
403 Lisp_Object win, frame;
404 struct scrollbar_instance *instance;
405 struct window_mirror *mirror;
410 mirror = find_scrollbar_window_mirror (f, id);
414 win = real_window (mirror, 1);
418 instance = mirror->scrollbar_vertical_instance;
419 frame = WINDOW_FRAME (XWINDOW (win));
421 /* It seems that this is necessary whenever signal_special_Xt_user_event()
422 is called. #### Why??? */
423 DEVICE_X_MOUSE_TIMESTAMP (d) = DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d);
425 switch (data->action)
427 case SCROLLBAR_LINE_UP:
428 signal_special_Xt_user_event (frame, Qscrollbar_line_up, win);
431 case SCROLLBAR_LINE_DOWN:
432 signal_special_Xt_user_event (frame, Qscrollbar_line_down, win);
435 /* The Athena scrollbar paging behavior is that of xterms.
436 Depending on where you click the size of the page varies.
437 Motif always does a standard Emacs page. */
438 case SCROLLBAR_PAGE_UP:
439 #if !defined (LWLIB_SCROLLBARS_MOTIF) && !defined (LWLIB_SCROLLBARS_LUCID) && \
440 !defined (LWLIB_SCROLLBARS_ATHENA3D)
442 double tmp = ((double) data->slider_value /
443 (double) SCROLLBAR_X_POS_DATA(instance).scrollbar_height);
445 (double) window_displayed_height (XWINDOW (win));
449 signal_special_Xt_user_event (frame, Qscrollbar_page_up,
450 Fcons (win, make_int ((int) line)));
453 signal_special_Xt_user_event (frame, Qscrollbar_page_up,
458 case SCROLLBAR_PAGE_DOWN:
459 #if !defined (LWLIB_SCROLLBARS_MOTIF) && !defined (LWLIB_SCROLLBARS_LUCID) && \
460 !defined (LWLIB_SCROLLBARS_ATHENA3D)
462 double tmp = ((double) data->slider_value /
463 (double) SCROLLBAR_X_POS_DATA(instance).scrollbar_height);
465 (double) window_displayed_height (XWINDOW (win));
467 if (SCROLLBAR_X_POS_DATA(instance).maximum >
468 (SCROLLBAR_X_POS_DATA(instance).slider_size + SCROLLBAR_X_POS_DATA(instance).slider_position))
472 signal_special_Xt_user_event (frame, Qscrollbar_page_down,
474 make_int ((int) line)));
478 signal_special_Xt_user_event (frame, Qscrollbar_page_down,
484 signal_special_Xt_user_event (frame, Qscrollbar_to_top, win);
487 case SCROLLBAR_BOTTOM:
488 signal_special_Xt_user_event (frame, Qscrollbar_to_bottom, win);
492 case SCROLLBAR_CHANGE:
493 inhibit_slider_size_change = 0;
494 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID)
495 vertical_drag_in_progress = 0;
496 SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) = data->slider_value;
497 SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance) =
498 XINT (Fwindow_start (win));
500 stupid_vertical_scrollbar_drag_hack = 0;
508 inhibit_slider_size_change = 1;
510 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID)
511 /* Doing drags with Motif-like scrollbars is a mess, since we
512 want to avoid having the window position jump when you
513 first grab the scrollbar, but we also want to ensure that
514 you can scroll all the way to the top or bottom of the
515 buffer. This can all be replaced with something sane when
516 we get line-based scrolling. */
518 vertical_drag_in_progress = 1;
520 if (SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) < 0)
522 SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) = data->slider_value;
523 SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance) =
524 XINT (Fwindow_start (win));
527 /* Could replace this piecewise linear scrolling with a
528 quadratic through the three points, but I'm not sure that
529 would feel any nicer in practice. */
530 if (data->slider_value < SCROLLBAR_X_VDRAG_ORIG_VALUE (instance))
532 /* We've dragged up; slide linearly from original position to
533 window-start=data.minimum, slider-value=data.minimum. */
535 if (SCROLLBAR_X_VDRAG_ORIG_VALUE (instance)
536 <= SCROLLBAR_X_POS_DATA (instance).minimum)
538 /* shouldn't get here, but just in case */
539 value = SCROLLBAR_X_POS_DATA (instance).minimum;
544 (SCROLLBAR_X_POS_DATA (instance).minimum
546 (SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance)
547 - SCROLLBAR_X_POS_DATA (instance).minimum)
548 * (data->slider_value -
549 SCROLLBAR_X_POS_DATA (instance).minimum))
550 / (SCROLLBAR_X_VDRAG_ORIG_VALUE (instance)
551 - SCROLLBAR_X_POS_DATA (instance).minimum)));
556 /* We've dragged down; slide linearly from original position to
557 window-start=data.maximum, slider-value=data.maximum. */
559 if (SCROLLBAR_X_VDRAG_ORIG_VALUE (instance)
560 >= (SCROLLBAR_X_POS_DATA (instance).maximum -
561 SCROLLBAR_X_POS_DATA (instance).slider_size))
563 /* avoid divide by zero */
564 value = SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance);
569 (SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance)
571 (SCROLLBAR_X_POS_DATA (instance).maximum
572 - SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance))
573 * (data->slider_value
574 - SCROLLBAR_X_VDRAG_ORIG_VALUE (instance)))
575 / (SCROLLBAR_X_POS_DATA (instance).maximum
576 - SCROLLBAR_X_POS_DATA (instance).slider_size
577 - SCROLLBAR_X_VDRAG_ORIG_VALUE (instance))));
581 stupid_vertical_scrollbar_drag_hack = 0;
582 value = data->slider_value;
585 if (value >= SCROLLBAR_X_POS_DATA (instance).maximum)
586 value = SCROLLBAR_X_POS_DATA (instance).maximum - 1;
587 if (value < SCROLLBAR_X_POS_DATA (instance).minimum)
588 value = SCROLLBAR_X_POS_DATA (instance).minimum;
590 signal_special_Xt_user_event (frame, Qscrollbar_vertical_drag,
591 Fcons (win, make_int (value)));
599 * This is the only callback provided for horizontal scrollbars. It
600 * should be able to handle all of the scrollbar events in
601 * scroll_action (see lwlib.h). The client data will be of type
602 * scroll_event (see lwlib.h). */
604 x_update_horizontal_scrollbar_callback (Widget widget, LWLIB_ID id,
605 XtPointer client_data)
607 scroll_event *data = (scroll_event *) client_data;
608 struct device *d = get_device_from_display (XtDisplay (widget));
609 struct frame *f = x_any_window_to_frame (d, XtWindow (widget));
610 Lisp_Object win, frame;
611 struct window_mirror *mirror;
616 mirror = find_scrollbar_window_mirror (f, id);
620 win = real_window (mirror, 1);
624 frame = WINDOW_FRAME (XWINDOW (win));
626 /* It seems that this is necessary whenever signal_special_Xt_user_event()
627 is called. #### Why??? */
628 DEVICE_X_MOUSE_TIMESTAMP (d) = DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d);
630 switch (data->action)
632 case SCROLLBAR_LINE_UP:
633 signal_special_Xt_user_event (frame, Qscrollbar_char_left, win);
635 case SCROLLBAR_LINE_DOWN:
636 signal_special_Xt_user_event (frame, Qscrollbar_char_right, win);
638 case SCROLLBAR_PAGE_UP:
639 signal_special_Xt_user_event (frame, Qscrollbar_page_left, win);
641 case SCROLLBAR_PAGE_DOWN:
642 signal_special_Xt_user_event (frame, Qscrollbar_page_right, win);
645 signal_special_Xt_user_event (frame, Qscrollbar_to_left, win);
647 case SCROLLBAR_BOTTOM:
648 signal_special_Xt_user_event (frame, Qscrollbar_to_right, win);
650 case SCROLLBAR_CHANGE:
651 inhibit_slider_size_change = 0;
654 inhibit_slider_size_change = 1;
655 /* #### Fix the damn toolkit code so they all work the same way.
656 Lucid is the one mostly wrong.*/
657 #if defined (LWLIB_SCROLLBARS_LUCID) || defined (LWLIB_SCROLLBARS_ATHENA3D)
658 signal_special_Xt_user_event (frame, Qscrollbar_horizontal_drag,
660 (win, make_int (data->slider_value))));
662 signal_special_Xt_user_event (frame, Qscrollbar_horizontal_drag,
665 make_int (data->slider_value - 1))));
674 x_scrollbar_pointer_changed_in_window (struct window *w)
678 XSETWINDOW (window, w);
679 x_scrollbar_loop (X_SET_SCROLLBAR_POINTER, window, find_window_mirror (w),
683 /* Make sure that all scrollbars on frame are up-to-date. Called
684 directly from x_set_frame_properties in frame-x.c*/
686 x_update_frame_scrollbars (struct frame *f)
688 /* Consider this code to be "in_display" so that we abort() if Fsignal()
691 x_scrollbar_loop (X_UPDATE_FRAME_SCROLLBARS, f->root_window, f->root_mirror,
694 if (in_display < 0) abort ();
697 #ifdef MEMORY_USAGE_STATS
700 x_compute_scrollbar_instance_usage (struct device *d,
701 struct scrollbar_instance *inst,
702 struct overhead_stats *ovstats)
708 struct x_scrollbar_data *data =
709 (struct x_scrollbar_data *) inst->scrollbar_data;
711 total += malloced_storage_size (data, sizeof (*data), ovstats);
712 total += malloced_storage_size (data->name, 1 + strlen (data->name),
720 #endif /* MEMORY_USAGE_STATS */
723 /************************************************************************/
725 /************************************************************************/
728 console_type_create_scrollbar_x (void)
730 CONSOLE_HAS_METHOD (x, inhibit_scrollbar_slider_size_change);
731 CONSOLE_HAS_METHOD (x, free_scrollbar_instance);
732 CONSOLE_HAS_METHOD (x, release_scrollbar_instance);
733 CONSOLE_HAS_METHOD (x, create_scrollbar_instance);
734 CONSOLE_HAS_METHOD (x, update_scrollbar_instance_values);
735 CONSOLE_HAS_METHOD (x, update_scrollbar_instance_status);
736 CONSOLE_HAS_METHOD (x, scrollbar_pointer_changed_in_window);
737 #ifdef MEMORY_USAGE_STATS
738 CONSOLE_HAS_METHOD (x, compute_scrollbar_instance_usage);
739 #endif /* MEMORY_USAGE_STATS */
743 reinit_vars_of_scrollbar_x (void)
745 stupid_vertical_scrollbar_drag_hack = 1;
749 vars_of_scrollbar_x (void)
751 reinit_vars_of_scrollbar_x ();
753 #if defined (LWLIB_SCROLLBARS_LUCID)
754 Fprovide (intern ("lucid-scrollbars"));
755 #elif defined (LWLIB_SCROLLBARS_MOTIF)
756 Fprovide (intern ("motif-scrollbars"));
757 #elif defined (LWLIB_SCROLLBARS_ATHENA)
758 Fprovide (intern ("athena-scrollbars"));