1 /* scrollbar implementation -- X interface.
2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
3 Copyright (C) 1994 Amdhal 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"
31 #include "EmacsFrame.h"
32 #include "EmacsManager.h"
34 #include "scrollbar-x.h"
39 static void x_update_vertical_scrollbar_callback (Widget widget, LWLIB_ID id,
40 XtPointer client_data);
41 static void x_update_horizontal_scrollbar_callback (Widget widget, LWLIB_ID id,
42 XtPointer client_data);
44 /* Used to prevent changing the size of the slider while drag
45 scrolling, under Motif. This is necessary because the Motif
46 scrollbar is incredibly stupid about updating the slider and causes
47 lots of flicker if it is done too often. */
48 static int inhibit_slider_size_change;
49 int stupid_vertical_scrollbar_drag_hack;
51 /* Doesn't work with athena */
52 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID)
53 static int vertical_drag_in_progress;
57 /* A device method. */
59 x_inhibit_scrollbar_slider_size_change (void)
61 /* Doesn't work with Athena */
62 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID)
63 return inhibit_slider_size_change;
69 /* A device method. */
71 x_free_scrollbar_instance (struct scrollbar_instance *instance)
73 if (SCROLLBAR_X_NAME (instance))
74 xfree (SCROLLBAR_X_NAME (instance));
76 if (SCROLLBAR_X_WIDGET (instance))
78 if (XtIsManaged (SCROLLBAR_X_WIDGET (instance)))
79 XtUnmanageChild (SCROLLBAR_X_WIDGET (instance));
81 lw_destroy_all_widgets (SCROLLBAR_X_ID (instance));
84 if (instance->scrollbar_data)
85 xfree (instance->scrollbar_data);
88 /* A device method. */
90 x_release_scrollbar_instance (struct scrollbar_instance *instance)
92 if (XtIsManaged (SCROLLBAR_X_WIDGET (instance)))
93 XtUnmanageChild (SCROLLBAR_X_WIDGET (instance));
96 /* A device method. */
98 x_create_scrollbar_instance (struct frame *f, int vertical,
99 struct scrollbar_instance *instance)
103 /* initialize the X specific data section. */
104 instance->scrollbar_data = xnew_and_zero (struct x_scrollbar_data);
106 SCROLLBAR_X_ID (instance) = new_lwlib_id ();
107 sprintf (buffer, "scrollbar_%d", SCROLLBAR_X_ID (instance));
108 SCROLLBAR_X_NAME (instance) = xstrdup (buffer);
109 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) || \
110 defined (LWLIB_SCROLLBARS_ATHENA3D)
111 SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) = -1;
116 SCROLLBAR_X_WIDGET (instance) =
117 lw_create_widget ("vertical-scrollbar", SCROLLBAR_X_NAME (instance),
118 SCROLLBAR_X_ID (instance),
119 NULL, FRAME_X_CONTAINER_WIDGET (f), 0,
120 x_update_vertical_scrollbar_callback, NULL, NULL);
124 SCROLLBAR_X_WIDGET (instance) =
125 lw_create_widget ("horizontal-scrollbar", SCROLLBAR_X_NAME (instance),
126 SCROLLBAR_X_ID (instance),
127 NULL, FRAME_X_CONTAINER_WIDGET (f), 0,
128 x_update_horizontal_scrollbar_callback, NULL, NULL);
132 #define UPDATE_DATA_FIELD(field) \
133 if (new_##field >= 0 && \
134 SCROLLBAR_X_POS_DATA (inst).field != new_##field) { \
135 SCROLLBAR_X_POS_DATA (inst).field = new_##field; \
136 inst->scrollbar_instance_changed = 1; \
139 /* A device method. */
140 /* #### The -1 check is such a hack. */
142 x_update_scrollbar_instance_values (struct window *w,
143 struct scrollbar_instance *inst,
144 int new_line_increment,
145 int new_page_increment,
146 int new_minimum, int new_maximum,
148 int new_slider_position,
149 int new_scrollbar_width,
150 int new_scrollbar_height,
151 int new_scrollbar_x, int new_scrollbar_y)
153 UPDATE_DATA_FIELD (line_increment);
154 UPDATE_DATA_FIELD (page_increment);
155 UPDATE_DATA_FIELD (minimum);
156 UPDATE_DATA_FIELD (maximum);
157 UPDATE_DATA_FIELD (slider_size);
158 UPDATE_DATA_FIELD (slider_position);
159 UPDATE_DATA_FIELD (scrollbar_width);
160 UPDATE_DATA_FIELD (scrollbar_height);
161 UPDATE_DATA_FIELD (scrollbar_x);
162 UPDATE_DATA_FIELD (scrollbar_y);
164 /* This doesn't work with Athena, why? */
165 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID)
166 if (w && !vertical_drag_in_progress)
168 int new_vov = SCROLLBAR_X_POS_DATA (inst).slider_position;
169 int new_vows = marker_position (w->start[CURRENT_DISP]);
171 if (SCROLLBAR_X_VDRAG_ORIG_VALUE (inst) != new_vov)
173 SCROLLBAR_X_VDRAG_ORIG_VALUE (inst) = new_vov;
174 inst->scrollbar_instance_changed = 1;
176 if (SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (inst) != new_vows)
178 SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (inst) = new_vows;
179 inst->scrollbar_instance_changed = 1;
185 /* Used by x_update_scrollbar_instance_status. */
187 update_one_scrollbar_bs (struct frame *f, Widget sb_widget)
189 Boolean use_backing_store;
191 Xt_GET_VALUE (FRAME_X_TEXT_WIDGET (f), XtNuseBackingStore, &use_backing_store);
193 if (use_backing_store && sb_widget)
195 unsigned long mask = CWBackingStore;
196 XSetWindowAttributes attrs;
198 attrs.backing_store = Always;
199 XChangeWindowAttributes (XtDisplay (sb_widget),
200 XtWindow (sb_widget),
206 /* Create a widget value structure for passing down to lwlib so that
207 it can update the scrollbar widgets. Used by
208 x_update_scrollbar_instance_status. */
209 static widget_value *
210 scrollbar_instance_to_widget_value (struct scrollbar_instance *instance)
214 wv = xmalloc_widget_value ();
215 /* #### maybe should add malloc_scrollbar_values to resource these? */
216 wv->scrollbar_data = xnew (scrollbar_values);
218 wv->name = SCROLLBAR_X_NAME (instance);
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 xfree (wv->scrollbar_data);
283 wv->scrollbar_data = 0;
284 free_widget_value (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);
411 win = real_window (mirror, 1);
415 instance = mirror->scrollbar_vertical_instance;
416 frame = WINDOW_FRAME (XWINDOW (win));
418 /* It seems that this is necessary whenever signal_special_Xt_user_event()
419 is called. #### Why??? */
420 DEVICE_X_MOUSE_TIMESTAMP (d) = DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d);
422 switch (data->action)
424 case SCROLLBAR_LINE_UP:
425 signal_special_Xt_user_event (frame, Qscrollbar_line_up, win);
428 case SCROLLBAR_LINE_DOWN:
429 signal_special_Xt_user_event (frame, Qscrollbar_line_down, win);
432 /* The Athena scrollbar paging behavior is that of xterms.
433 Depending on where you click the size of the page varies.
434 Motif always does a standard Emacs page. */
435 case SCROLLBAR_PAGE_UP:
436 #if !defined (LWLIB_SCROLLBARS_MOTIF) && !defined (LWLIB_SCROLLBARS_LUCID) && \
437 !defined (LWLIB_SCROLLBARS_ATHENA3D)
439 double tmp = ((double) data->slider_value /
440 (double) SCROLLBAR_X_POS_DATA(instance).scrollbar_height);
442 (double) window_displayed_height (XWINDOW (win));
446 signal_special_Xt_user_event (frame, Qscrollbar_page_up,
447 Fcons (win, make_int ((int) line)));
450 signal_special_Xt_user_event (frame, Qscrollbar_page_up,
455 case SCROLLBAR_PAGE_DOWN:
456 #if !defined (LWLIB_SCROLLBARS_MOTIF) && !defined (LWLIB_SCROLLBARS_LUCID) && \
457 !defined (LWLIB_SCROLLBARS_ATHENA3D)
459 double tmp = ((double) data->slider_value /
460 (double) SCROLLBAR_X_POS_DATA(instance).scrollbar_height);
462 (double) window_displayed_height (XWINDOW (win));
464 if (SCROLLBAR_X_POS_DATA(instance).maximum >
465 (SCROLLBAR_X_POS_DATA(instance).slider_size + SCROLLBAR_X_POS_DATA(instance).slider_position))
469 signal_special_Xt_user_event (frame, Qscrollbar_page_down,
471 make_int ((int) line)));
475 signal_special_Xt_user_event (frame, Qscrollbar_page_down,
481 signal_special_Xt_user_event (frame, Qscrollbar_to_top, win);
484 case SCROLLBAR_BOTTOM:
485 signal_special_Xt_user_event (frame, Qscrollbar_to_bottom, win);
489 case SCROLLBAR_CHANGE:
490 inhibit_slider_size_change = 0;
491 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID)
492 vertical_drag_in_progress = 0;
493 SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) = data->slider_value;
494 SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance) =
495 XINT (Fwindow_start (win));
497 stupid_vertical_scrollbar_drag_hack = 0;
505 inhibit_slider_size_change = 1;
507 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID)
508 /* Doing drags with Motif-like scrollbars is a mess, since we
509 want to avoid having the window position jump when you
510 first grab the scrollbar, but we also want to ensure that
511 you can scroll all the way to the top or bottom of the
512 buffer. This can all be replaced with something sane when
513 we get line-based scrolling. */
515 vertical_drag_in_progress = 1;
517 if (SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) < 0)
519 SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) = data->slider_value;
520 SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance) =
521 XINT (Fwindow_start (win));
524 /* Could replace this piecewise linear scrolling with a
525 quadratic through the three points, but I'm not sure that
526 would feel any nicer in practice. */
527 if (data->slider_value < SCROLLBAR_X_VDRAG_ORIG_VALUE (instance))
529 /* We've dragged up; slide linearly from original position to
530 window-start=data.minimum, slider-value=data.minimum. */
532 if (SCROLLBAR_X_VDRAG_ORIG_VALUE (instance)
533 <= SCROLLBAR_X_POS_DATA (instance).minimum)
535 /* shouldn't get here, but just in case */
536 value = SCROLLBAR_X_POS_DATA (instance).minimum;
541 (SCROLLBAR_X_POS_DATA (instance).minimum
543 (SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance)
544 - SCROLLBAR_X_POS_DATA (instance).minimum)
545 * (data->slider_value -
546 SCROLLBAR_X_POS_DATA (instance).minimum))
547 / (SCROLLBAR_X_VDRAG_ORIG_VALUE (instance)
548 - SCROLLBAR_X_POS_DATA (instance).minimum)));
553 /* We've dragged down; slide linearly from original position to
554 window-start=data.maximum, slider-value=data.maximum. */
556 if (SCROLLBAR_X_VDRAG_ORIG_VALUE (instance)
557 >= (SCROLLBAR_X_POS_DATA (instance).maximum -
558 SCROLLBAR_X_POS_DATA (instance).slider_size))
560 /* avoid divide by zero */
561 value = SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance);
566 (SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance)
568 (SCROLLBAR_X_POS_DATA (instance).maximum
569 - SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance))
570 * (data->slider_value
571 - SCROLLBAR_X_VDRAG_ORIG_VALUE (instance)))
572 / (SCROLLBAR_X_POS_DATA (instance).maximum
573 - SCROLLBAR_X_POS_DATA (instance).slider_size
574 - SCROLLBAR_X_VDRAG_ORIG_VALUE (instance))));
578 stupid_vertical_scrollbar_drag_hack = 0;
579 value = data->slider_value;
582 if (value >= SCROLLBAR_X_POS_DATA (instance).maximum)
583 value = SCROLLBAR_X_POS_DATA (instance).maximum - 1;
584 if (value < SCROLLBAR_X_POS_DATA (instance).minimum)
585 value = SCROLLBAR_X_POS_DATA (instance).minimum;
587 signal_special_Xt_user_event (frame, Qscrollbar_vertical_drag,
588 Fcons (win, make_int (value)));
596 * This is the only callback provided for horizontal scrollbars. It
597 * should be able to handle all of the scrollbar events in
598 * scroll_action (see lwlib.h). The client data will be of type
599 * scroll_event (see lwlib.h). */
601 x_update_horizontal_scrollbar_callback (Widget widget, LWLIB_ID id,
602 XtPointer client_data)
604 scroll_event *data = (scroll_event *) client_data;
605 struct device *d = get_device_from_display (XtDisplay (widget));
606 struct frame *f = x_any_window_to_frame (d, XtWindow (widget));
607 Lisp_Object win, frame;
608 struct window_mirror *mirror;
613 mirror = find_scrollbar_window_mirror (f, id);
614 win = real_window (mirror, 1);
618 frame = WINDOW_FRAME (XWINDOW (win));
620 /* It seems that this is necessary whenever signal_special_Xt_user_event()
621 is called. #### Why??? */
622 DEVICE_X_MOUSE_TIMESTAMP (d) = DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d);
624 switch (data->action)
626 case SCROLLBAR_LINE_UP:
627 signal_special_Xt_user_event (frame, Qscrollbar_char_left, win);
629 case SCROLLBAR_LINE_DOWN:
630 signal_special_Xt_user_event (frame, Qscrollbar_char_right, win);
632 case SCROLLBAR_PAGE_UP:
633 signal_special_Xt_user_event (frame, Qscrollbar_page_left, win);
635 case SCROLLBAR_PAGE_DOWN:
636 signal_special_Xt_user_event (frame, Qscrollbar_page_right, win);
639 signal_special_Xt_user_event (frame, Qscrollbar_to_left, win);
641 case SCROLLBAR_BOTTOM:
642 signal_special_Xt_user_event (frame, Qscrollbar_to_right, win);
644 case SCROLLBAR_CHANGE:
645 inhibit_slider_size_change = 0;
648 inhibit_slider_size_change = 1;
649 /* #### Fix the damn toolkit code so they all work the same way.
650 Lucid is the one mostly wrong.*/
651 #if defined (LWLIB_SCROLLBARS_LUCID) || defined (LWLIB_SCROLLBARS_ATHENA3D)
652 signal_special_Xt_user_event (frame, Qscrollbar_horizontal_drag,
654 (win, make_int (data->slider_value))));
656 signal_special_Xt_user_event (frame, Qscrollbar_horizontal_drag,
659 make_int (data->slider_value - 1))));
668 x_scrollbar_pointer_changed_in_window (struct window *w)
672 XSETWINDOW (window, w);
673 x_scrollbar_loop (X_SET_SCROLLBAR_POINTER, window, find_window_mirror (w),
677 /* Called directly from x_any_window_to_frame in frame-x.c */
679 x_window_is_scrollbar (struct frame *f, Window win)
685 update_frame_window_mirror (f);
686 return (EMACS_INT) x_scrollbar_loop (X_WINDOW_IS_SCROLLBAR, f->root_window,
687 f->root_mirror, 0, win);
690 /* Make sure that all scrollbars on frame are up-to-date. Called
691 directly from x_set_frame_properties in frame-x.c*/
693 x_update_frame_scrollbars (struct frame *f)
695 /* Consider this code to be "in_display" so that we abort() if Fsignal()
698 x_scrollbar_loop (X_UPDATE_FRAME_SCROLLBARS, f->root_window, f->root_mirror,
701 if (in_display < 0) abort ();
704 #ifdef MEMORY_USAGE_STATS
707 x_compute_scrollbar_instance_usage (struct device *d,
708 struct scrollbar_instance *inst,
709 struct overhead_stats *ovstats)
715 struct x_scrollbar_data *data =
716 (struct x_scrollbar_data *) inst->scrollbar_data;
718 total += malloced_storage_size (data, sizeof (*data), ovstats);
719 total += malloced_storage_size (data->name, 1 + strlen (data->name),
727 #endif /* MEMORY_USAGE_STATS */
730 /************************************************************************/
732 /************************************************************************/
735 console_type_create_scrollbar_x (void)
737 CONSOLE_HAS_METHOD (x, inhibit_scrollbar_slider_size_change);
738 CONSOLE_HAS_METHOD (x, free_scrollbar_instance);
739 CONSOLE_HAS_METHOD (x, release_scrollbar_instance);
740 CONSOLE_HAS_METHOD (x, create_scrollbar_instance);
741 CONSOLE_HAS_METHOD (x, update_scrollbar_instance_values);
742 CONSOLE_HAS_METHOD (x, update_scrollbar_instance_status);
743 CONSOLE_HAS_METHOD (x, scrollbar_pointer_changed_in_window);
744 #ifdef MEMORY_USAGE_STATS
745 CONSOLE_HAS_METHOD (x, compute_scrollbar_instance_usage);
746 #endif /* MEMORY_USAGE_STATS */
750 vars_of_scrollbar_x (void)
752 #if defined (LWLIB_SCROLLBARS_LUCID)
753 Fprovide (intern ("lucid-scrollbars"));
754 #elif defined (LWLIB_SCROLLBARS_MOTIF)
755 Fprovide (intern ("motif-scrollbars"));
756 #elif defined (LWLIB_SCROLLBARS_ATHENA)
757 Fprovide (intern ("athena-scrollbars"));
759 stupid_vertical_scrollbar_drag_hack = 1;