Mercurial > hg > xemacs-beta
annotate src/scrollbar-x.c @ 5127:a9c41067dd88 ben-lisp-object
more cleanups, terminology clarification, lots of doc work
-------------------- ChangeLog entries follow: --------------------
man/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* internals/internals.texi (Introduction to Allocation):
* internals/internals.texi (Integers and Characters):
* internals/internals.texi (Allocation from Frob Blocks):
* internals/internals.texi (lrecords):
* internals/internals.texi (Low-level allocation):
Rewrite section on allocation of Lisp objects to reflect the new
reality. Remove references to nonexistent XSETINT and XSETCHAR.
modules/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* postgresql/postgresql.c (allocate_pgconn):
* postgresql/postgresql.c (allocate_pgresult):
* postgresql/postgresql.h (struct Lisp_PGconn):
* postgresql/postgresql.h (struct Lisp_PGresult):
* ldap/eldap.c (allocate_ldap):
* ldap/eldap.h (struct Lisp_LDAP):
Same changes as in src/ dir. See large log there in ChangeLog,
but basically:
ALLOC_LISP_OBJECT -> ALLOC_NORMAL_LISP_OBJECT
LISP_OBJECT_HEADER -> NORMAL_LISP_OBJECT_HEADER
../hlo/src/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* alloc.c:
* alloc.c (old_alloc_sized_lcrecord):
* alloc.c (very_old_free_lcrecord):
* alloc.c (copy_lisp_object):
* alloc.c (zero_sized_lisp_object):
* alloc.c (zero_nonsized_lisp_object):
* alloc.c (lisp_object_storage_size):
* alloc.c (free_normal_lisp_object):
* alloc.c (FREE_FIXED_TYPE_WHEN_NOT_IN_GC):
* alloc.c (ALLOC_FROB_BLOCK_LISP_OBJECT):
* alloc.c (Fcons):
* alloc.c (noseeum_cons):
* alloc.c (make_float):
* alloc.c (make_bignum):
* alloc.c (make_bignum_bg):
* alloc.c (make_ratio):
* alloc.c (make_ratio_bg):
* alloc.c (make_ratio_rt):
* alloc.c (make_bigfloat):
* alloc.c (make_bigfloat_bf):
* alloc.c (size_vector):
* alloc.c (make_compiled_function):
* alloc.c (Fmake_symbol):
* alloc.c (allocate_extent):
* alloc.c (allocate_event):
* alloc.c (make_key_data):
* alloc.c (make_button_data):
* alloc.c (make_motion_data):
* alloc.c (make_process_data):
* alloc.c (make_timeout_data):
* alloc.c (make_magic_data):
* alloc.c (make_magic_eval_data):
* alloc.c (make_eval_data):
* alloc.c (make_misc_user_data):
* alloc.c (Fmake_marker):
* alloc.c (noseeum_make_marker):
* alloc.c (size_string_direct_data):
* alloc.c (make_uninit_string):
* alloc.c (make_string_nocopy):
* alloc.c (mark_lcrecord_list):
* alloc.c (alloc_managed_lcrecord):
* alloc.c (free_managed_lcrecord):
* alloc.c (sweep_lcrecords_1):
* alloc.c (malloced_storage_size):
* buffer.c (allocate_buffer):
* buffer.c (compute_buffer_usage):
* buffer.c (DEFVAR_BUFFER_LOCAL_1):
* buffer.c (nuke_all_buffer_slots):
* buffer.c (common_init_complex_vars_of_buffer):
* buffer.h (struct buffer_text):
* buffer.h (struct buffer):
* bytecode.c:
* bytecode.c (make_compiled_function_args):
* bytecode.c (size_compiled_function_args):
* bytecode.h (struct compiled_function_args):
* casetab.c (allocate_case_table):
* casetab.h (struct Lisp_Case_Table):
* charset.h (struct Lisp_Charset):
* chartab.c (fill_char_table):
* chartab.c (Fmake_char_table):
* chartab.c (make_char_table_entry):
* chartab.c (copy_char_table_entry):
* chartab.c (Fcopy_char_table):
* chartab.c (put_char_table):
* chartab.h (struct Lisp_Char_Table_Entry):
* chartab.h (struct Lisp_Char_Table):
* console-gtk-impl.h (struct gtk_device):
* console-gtk-impl.h (struct gtk_frame):
* console-impl.h (struct console):
* console-msw-impl.h (struct Lisp_Devmode):
* console-msw-impl.h (struct mswindows_device):
* console-msw-impl.h (struct msprinter_device):
* console-msw-impl.h (struct mswindows_frame):
* console-msw-impl.h (struct mswindows_dialog_id):
* console-stream-impl.h (struct stream_console):
* console-stream.c (stream_init_console):
* console-tty-impl.h (struct tty_console):
* console-tty-impl.h (struct tty_device):
* console-tty.c (allocate_tty_console_struct):
* console-x-impl.h (struct x_device):
* console-x-impl.h (struct x_frame):
* console.c (allocate_console):
* console.c (nuke_all_console_slots):
* console.c (DEFVAR_CONSOLE_LOCAL_1):
* console.c (common_init_complex_vars_of_console):
* data.c (make_weak_list):
* data.c (make_weak_box):
* data.c (make_ephemeron):
* database.c:
* database.c (struct Lisp_Database):
* database.c (allocate_database):
* database.c (finalize_database):
* device-gtk.c (allocate_gtk_device_struct):
* device-impl.h (struct device):
* device-msw.c:
* device-msw.c (mswindows_init_device):
* device-msw.c (msprinter_init_device):
* device-msw.c (finalize_devmode):
* device-msw.c (allocate_devmode):
* device-tty.c (allocate_tty_device_struct):
* device-x.c (allocate_x_device_struct):
* device.c:
* device.c (nuke_all_device_slots):
* device.c (allocate_device):
* dialog-msw.c (handle_question_dialog_box):
* elhash.c:
* elhash.c (struct Lisp_Hash_Table):
* elhash.c (finalize_hash_table):
* elhash.c (make_general_lisp_hash_table):
* elhash.c (Fcopy_hash_table):
* elhash.h (htentry):
* emacs.c (main_1):
* eval.c:
* eval.c (size_multiple_value):
* event-stream.c (finalize_command_builder):
* event-stream.c (allocate_command_builder):
* event-stream.c (free_command_builder):
* event-stream.c (event_stream_generate_wakeup):
* event-stream.c (event_stream_resignal_wakeup):
* event-stream.c (event_stream_disable_wakeup):
* event-stream.c (event_stream_wakeup_pending_p):
* events.h (struct Lisp_Timeout):
* events.h (struct command_builder):
* extents-impl.h:
* extents-impl.h (struct extent_auxiliary):
* extents-impl.h (struct extent_info):
* extents-impl.h (set_extent_no_chase_aux_field):
* extents-impl.h (set_extent_no_chase_normal_field):
* extents.c:
* extents.c (gap_array_marker):
* extents.c (gap_array):
* extents.c (extent_list_marker):
* extents.c (extent_list):
* extents.c (stack_of_extents):
* extents.c (gap_array_make_marker):
* extents.c (extent_list_make_marker):
* extents.c (allocate_extent_list):
* extents.c (SLOT):
* extents.c (mark_extent_auxiliary):
* extents.c (allocate_extent_auxiliary):
* extents.c (attach_extent_auxiliary):
* extents.c (size_gap_array):
* extents.c (finalize_extent_info):
* extents.c (allocate_extent_info):
* extents.c (uninit_buffer_extents):
* extents.c (allocate_soe):
* extents.c (copy_extent):
* extents.c (vars_of_extents):
* extents.h:
* faces.c (allocate_face):
* faces.h (struct Lisp_Face):
* faces.h (struct face_cachel):
* file-coding.c:
* file-coding.c (finalize_coding_system):
* file-coding.c (sizeof_coding_system):
* file-coding.c (Fcopy_coding_system):
* file-coding.h (struct Lisp_Coding_System):
* file-coding.h (MARKED_SLOT):
* fns.c (size_bit_vector):
* font-mgr.c:
* font-mgr.c (finalize_fc_pattern):
* font-mgr.c (print_fc_pattern):
* font-mgr.c (Ffc_pattern_p):
* font-mgr.c (Ffc_pattern_create):
* font-mgr.c (Ffc_name_parse):
* font-mgr.c (Ffc_name_unparse):
* font-mgr.c (Ffc_pattern_duplicate):
* font-mgr.c (Ffc_pattern_add):
* font-mgr.c (Ffc_pattern_del):
* font-mgr.c (Ffc_pattern_get):
* font-mgr.c (fc_config_create_using):
* font-mgr.c (fc_strlist_to_lisp_using):
* font-mgr.c (fontset_to_list):
* font-mgr.c (Ffc_config_p):
* font-mgr.c (Ffc_config_up_to_date):
* font-mgr.c (Ffc_config_build_fonts):
* font-mgr.c (Ffc_config_get_cache):
* font-mgr.c (Ffc_config_get_fonts):
* font-mgr.c (Ffc_config_set_current):
* font-mgr.c (Ffc_config_get_blanks):
* font-mgr.c (Ffc_config_get_rescan_interval):
* font-mgr.c (Ffc_config_set_rescan_interval):
* font-mgr.c (Ffc_config_app_font_add_file):
* font-mgr.c (Ffc_config_app_font_add_dir):
* font-mgr.c (Ffc_config_app_font_clear):
* font-mgr.c (size):
* font-mgr.c (Ffc_config_substitute):
* font-mgr.c (Ffc_font_render_prepare):
* font-mgr.c (Ffc_font_match):
* font-mgr.c (Ffc_font_sort):
* font-mgr.c (finalize_fc_config):
* font-mgr.c (print_fc_config):
* font-mgr.h:
* font-mgr.h (struct fc_pattern):
* font-mgr.h (XFC_PATTERN):
* font-mgr.h (struct fc_config):
* font-mgr.h (XFC_CONFIG):
* frame-gtk.c (allocate_gtk_frame_struct):
* frame-impl.h (struct frame):
* frame-msw.c (mswindows_init_frame_1):
* frame-x.c (allocate_x_frame_struct):
* frame.c (nuke_all_frame_slots):
* frame.c (allocate_frame_core):
* gc.c:
* gc.c (GC_CHECK_NOT_FREE):
* glyphs.c (finalize_image_instance):
* glyphs.c (allocate_image_instance):
* glyphs.c (Fcolorize_image_instance):
* glyphs.c (allocate_glyph):
* glyphs.c (unmap_subwindow_instance_cache_mapper):
* glyphs.c (register_ignored_expose):
* glyphs.h (struct Lisp_Image_Instance):
* glyphs.h (struct Lisp_Glyph):
* glyphs.h (struct glyph_cachel):
* glyphs.h (struct expose_ignore):
* gui.c (allocate_gui_item):
* gui.h (struct Lisp_Gui_Item):
* keymap.c (struct Lisp_Keymap):
* keymap.c (make_keymap):
* lisp.h:
* lisp.h (struct Lisp_String_Direct_Data):
* lisp.h (struct Lisp_String_Indirect_Data):
* lisp.h (struct Lisp_Vector):
* lisp.h (struct Lisp_Bit_Vector):
* lisp.h (DECLARE_INLINE_LISP_BIT_VECTOR):
* lisp.h (struct weak_box):
* lisp.h (struct ephemeron):
* lisp.h (struct weak_list):
* lrecord.h:
* lrecord.h (struct lrecord_implementation):
* lrecord.h (MC_ALLOC_CALL_FINALIZER):
* lrecord.h (struct lcrecord_list):
* lstream.c (finalize_lstream):
* lstream.c (sizeof_lstream):
* lstream.c (Lstream_new):
* lstream.c (Lstream_delete):
* lstream.h (struct lstream):
* marker.c:
* marker.c (finalize_marker):
* marker.c (compute_buffer_marker_usage):
* mule-charset.c:
* mule-charset.c (make_charset):
* mule-charset.c (compute_charset_usage):
* objects-impl.h (struct Lisp_Color_Instance):
* objects-impl.h (struct Lisp_Font_Instance):
* objects-tty-impl.h (struct tty_color_instance_data):
* objects-tty-impl.h (struct tty_font_instance_data):
* objects-tty.c (tty_initialize_color_instance):
* objects-tty.c (tty_initialize_font_instance):
* objects.c (finalize_color_instance):
* objects.c (Fmake_color_instance):
* objects.c (finalize_font_instance):
* objects.c (Fmake_font_instance):
* objects.c (reinit_vars_of_objects):
* opaque.c:
* opaque.c (sizeof_opaque):
* opaque.c (make_opaque_ptr):
* opaque.c (free_opaque_ptr):
* opaque.h:
* opaque.h (Lisp_Opaque):
* opaque.h (Lisp_Opaque_Ptr):
* print.c (printing_unreadable_lcrecord):
* print.c (external_object_printer):
* print.c (debug_p4):
* process.c (finalize_process):
* process.c (make_process_internal):
* procimpl.h (struct Lisp_Process):
* rangetab.c (Fmake_range_table):
* rangetab.c (Fcopy_range_table):
* rangetab.h (struct Lisp_Range_Table):
* scrollbar.c:
* scrollbar.c (create_scrollbar_instance):
* scrollbar.c (compute_scrollbar_instance_usage):
* scrollbar.h (struct scrollbar_instance):
* specifier.c (finalize_specifier):
* specifier.c (sizeof_specifier):
* specifier.c (set_specifier_caching):
* specifier.h (struct Lisp_Specifier):
* specifier.h (struct specifier_caching):
* symeval.h:
* symeval.h (SYMBOL_VALUE_MAGIC_P):
* symeval.h (DEFVAR_SYMVAL_FWD):
* symsinit.h:
* syntax.c (init_buffer_syntax_cache):
* syntax.h (struct syntax_cache):
* toolbar.c:
* toolbar.c (allocate_toolbar_button):
* toolbar.c (update_toolbar_button):
* toolbar.h (struct toolbar_button):
* tooltalk.c (struct Lisp_Tooltalk_Message):
* tooltalk.c (make_tooltalk_message):
* tooltalk.c (struct Lisp_Tooltalk_Pattern):
* tooltalk.c (make_tooltalk_pattern):
* ui-gtk.c:
* ui-gtk.c (allocate_ffi_data):
* ui-gtk.c (emacs_gtk_object_finalizer):
* ui-gtk.c (allocate_emacs_gtk_object_data):
* ui-gtk.c (allocate_emacs_gtk_boxed_data):
* ui-gtk.h:
* window-impl.h (struct window):
* window-impl.h (struct window_mirror):
* window.c (finalize_window):
* window.c (allocate_window):
* window.c (new_window_mirror):
* window.c (mark_window_as_deleted):
* window.c (make_dummy_parent):
* window.c (compute_window_mirror_usage):
* window.c (compute_window_usage):
Overall point of this change and previous ones in this repository:
(1) Introduce new, clearer terminology: everything other than int
or char is a "record" object, which comes in two types: "normal
objects" and "frob-block objects". Fix up all places that
referred to frob-block objects as "simple", "basic", etc.
(2) Provide an advertised interface for doing operations on Lisp
objects, including creating new types, that is clean and
consistent in its naming, uses the above-referenced terms and
avoids referencing "lrecords", "old lcrecords", etc., which should
hide under the surface.
(3) Make the size_in_bytes and finalizer methods take a
Lisp_Object rather than a void * for consistency with other methods.
(4) Separate finalizer method into finalizer and disksaver, so
that normal finalize methods don't have to worry about disksaving.
Other specifics:
(1) Renaming:
LISP_OBJECT_HEADER -> NORMAL_LISP_OBJECT_HEADER
ALLOC_LISP_OBJECT -> ALLOC_NORMAL_LISP_OBJECT
implementation->basic_p -> implementation->frob_block_p
ALLOCATE_FIXED_TYPE_AND_SET_IMPL -> ALLOC_FROB_BLOCK_LISP_OBJECT
*FCCONFIG*, wrap_fcconfig -> *FC_CONFIG*, wrap_fc_config
*FCPATTERN*, wrap_fcpattern -> *FC_PATTERN*, wrap_fc_pattern
(the last two changes make the naming of these macros consistent
with the naming of all other macros, since the objects are named
fc-config and fc-pattern with a hyphen)
(2) Lots of documentation fixes in lrecord.h.
(3) Eliminate macros for copying, freeing, zeroing objects, getting
their storage size. Instead, new functions:
zero_sized_lisp_object()
zero_nonsized_lisp_object()
lisp_object_storage_size()
free_normal_lisp_object()
(copy_lisp_object() already exists)
LISP_OBJECT_FROB_BLOCK_P() (actually a macro)
Eliminated:
free_lrecord()
zero_lrecord()
copy_lrecord()
copy_sized_lrecord()
old_copy_lcrecord()
old_copy_sized_lcrecord()
old_zero_lcrecord()
old_zero_sized_lcrecord()
LISP_OBJECT_STORAGE_SIZE()
COPY_SIZED_LISP_OBJECT()
COPY_SIZED_LCRECORD()
COPY_LISP_OBJECT()
ZERO_LISP_OBJECT()
FREE_LISP_OBJECT()
(4) Catch the remaining places where lrecord stuff was used directly
and use the advertised interface, e.g. alloc_sized_lrecord() ->
ALLOC_SIZED_LISP_OBJECT().
(5) Make certain statically-declared pseudo-objects
(buffer_local_flags, console_local_flags) have their lheader
initialized correctly, so things like copy_lisp_object() can work
on them. Make extent_auxiliary_defaults a proper heap object
Vextent_auxiliary_defaults, and make extent auxiliaries dumpable
so that this object can be dumped. allocate_extent_auxiliary()
now just creates the object, and attach_extent_auxiliary()
creates an extent auxiliary and attaches to an extent, like the
old allocate_extent_auxiliary().
(6) Create EXTENT_AUXILIARY_SLOTS macro, similar to the foo-slots.h
files but in a macro instead of a file. The purpose is to avoid
duplication when iterating over all the slots in an extent auxiliary.
Use it.
(7) In lstream.c, don't zero out object after allocation because
allocation routines take care of this.
(8) In marker.c, fix a mistake in computing marker overhead.
(9) In print.c, clean up printing_unreadable_lcrecord(),
external_object_printer() to avoid lots of ifdef NEW_GC's.
(10) Separate toolbar-button allocation into a separate
allocate_toolbar_button() function for use in the example code
in lrecord.h.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Fri, 05 Mar 2010 04:08:17 -0600 |
parents | 6f2158fa75ed |
children | 1fae11d56ad2 |
rev | line source |
---|---|
428 | 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>. | |
5050
6f2158fa75ed
Fix quick-build, use asserts() in place of ABORT()
Ben Wing <ben@xemacs.org>
parents:
4976
diff
changeset
|
6 Copyright (C) 2010 Ben Wing. |
428 | 7 |
8 This file is part of XEmacs. | |
9 | |
10 XEmacs is free software; you can redistribute it and/or modify it | |
11 under the terms of the GNU General Public License as published by the | |
12 Free Software Foundation; either version 2, or (at your option) any | |
13 later version. | |
14 | |
15 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
18 for more details. | |
19 | |
20 You should have received a copy of the GNU General Public License | |
21 along with XEmacs; see the file COPYING. If not, write to | |
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
23 Boston, MA 02111-1307, USA. */ | |
24 | |
25 /* Synched up with: Not in FSF. */ | |
26 | |
442 | 27 /* This file Mule-ized (more like Mule-verified) by Ben Wing, 7-8-00. */ |
28 | |
428 | 29 #include <config.h> |
30 #include "lisp.h" | |
31 | |
872 | 32 #include "device-impl.h" |
33 #include "frame-impl.h" | |
800 | 34 #include "window.h" |
35 | |
872 | 36 #include "console-x-impl.h" |
428 | 37 #include "glyphs-x.h" |
38 #include "scrollbar-x.h" | |
39 | |
800 | 40 #include "EmacsFrame.h" |
428 | 41 |
42 static void x_update_vertical_scrollbar_callback (Widget widget, LWLIB_ID id, | |
43 XtPointer client_data); | |
44 static void x_update_horizontal_scrollbar_callback (Widget widget, LWLIB_ID id, | |
45 XtPointer client_data); | |
46 | |
47 /* Used to prevent changing the size of the slider while drag | |
48 scrolling, under Motif. This is necessary because the Motif | |
49 scrollbar is incredibly stupid about updating the slider and causes | |
50 lots of flicker if it is done too often. */ | |
51 static int inhibit_slider_size_change; | |
52 int stupid_vertical_scrollbar_drag_hack; | |
53 | |
54 /* Doesn't work with athena */ | |
55 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) | |
56 static int vertical_drag_in_progress; | |
57 #endif | |
58 | |
59 | |
60 /* A device method. */ | |
61 static int | |
62 x_inhibit_scrollbar_slider_size_change (void) | |
63 { | |
64 /* Doesn't work with Athena */ | |
65 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) | |
66 return inhibit_slider_size_change; | |
67 #else | |
68 return 0; | |
69 #endif | |
70 } | |
71 | |
72 /* A device method. */ | |
73 static void | |
74 x_free_scrollbar_instance (struct scrollbar_instance *instance) | |
75 { | |
3462 | 76 if (instance->scrollbar_data) |
428 | 77 { |
3462 | 78 if (SCROLLBAR_X_NAME (instance)) |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
3462
diff
changeset
|
79 xfree (SCROLLBAR_X_NAME (instance)); |
428 | 80 |
3462 | 81 if (SCROLLBAR_X_WIDGET (instance)) |
82 { | |
83 if (XtIsManaged (SCROLLBAR_X_WIDGET (instance))) | |
84 XtUnmanageChild (SCROLLBAR_X_WIDGET (instance)); | |
428 | 85 |
3462 | 86 lw_destroy_all_widgets (SCROLLBAR_X_ID (instance)); |
87 } | |
88 | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
3462
diff
changeset
|
89 xfree (instance->scrollbar_data); |
3462 | 90 } |
428 | 91 } |
92 | |
93 /* A device method. */ | |
94 static void | |
95 x_release_scrollbar_instance (struct scrollbar_instance *instance) | |
96 { | |
97 if (XtIsManaged (SCROLLBAR_X_WIDGET (instance))) | |
98 XtUnmanageChild (SCROLLBAR_X_WIDGET (instance)); | |
99 } | |
100 | |
101 /* A device method. */ | |
102 static void | |
103 x_create_scrollbar_instance (struct frame *f, int vertical, | |
104 struct scrollbar_instance *instance) | |
105 { | |
106 char buffer[32]; | |
107 | |
108 /* initialize the X specific data section. */ | |
109 instance->scrollbar_data = xnew_and_zero (struct x_scrollbar_data); | |
110 | |
111 SCROLLBAR_X_ID (instance) = new_lwlib_id (); | |
112 sprintf (buffer, "scrollbar_%d", SCROLLBAR_X_ID (instance)); | |
113 SCROLLBAR_X_NAME (instance) = xstrdup (buffer); | |
114 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) || \ | |
115 defined (LWLIB_SCROLLBARS_ATHENA3D) | |
116 SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) = -1; | |
117 #endif | |
118 | |
119 if (vertical) | |
120 { | |
121 SCROLLBAR_X_WIDGET (instance) = | |
122 lw_create_widget ("vertical-scrollbar", SCROLLBAR_X_NAME (instance), | |
123 SCROLLBAR_X_ID (instance), | |
124 NULL, FRAME_X_CONTAINER_WIDGET (f), 0, | |
125 x_update_vertical_scrollbar_callback, NULL, NULL); | |
126 } | |
127 else | |
128 { | |
129 SCROLLBAR_X_WIDGET (instance) = | |
130 lw_create_widget ("horizontal-scrollbar", SCROLLBAR_X_NAME (instance), | |
131 SCROLLBAR_X_ID (instance), | |
132 NULL, FRAME_X_CONTAINER_WIDGET (f), 0, | |
133 x_update_horizontal_scrollbar_callback, NULL, NULL); | |
134 } | |
135 } | |
136 | |
137 #define UPDATE_DATA_FIELD(field) \ | |
138 if (new_##field >= 0 && \ | |
139 SCROLLBAR_X_POS_DATA (inst).field != new_##field) { \ | |
140 SCROLLBAR_X_POS_DATA (inst).field = new_##field; \ | |
141 inst->scrollbar_instance_changed = 1; \ | |
142 } | |
143 | |
144 /* A device method. */ | |
145 /* #### The -1 check is such a hack. */ | |
146 static void | |
147 x_update_scrollbar_instance_values (struct window *w, | |
148 struct scrollbar_instance *inst, | |
149 int new_line_increment, | |
150 int new_page_increment, | |
151 int new_minimum, int new_maximum, | |
152 int new_slider_size, | |
153 int new_slider_position, | |
154 int new_scrollbar_width, | |
155 int new_scrollbar_height, | |
156 int new_scrollbar_x, int new_scrollbar_y) | |
157 { | |
158 UPDATE_DATA_FIELD (line_increment); | |
159 UPDATE_DATA_FIELD (page_increment); | |
160 UPDATE_DATA_FIELD (minimum); | |
161 UPDATE_DATA_FIELD (maximum); | |
162 UPDATE_DATA_FIELD (slider_size); | |
163 UPDATE_DATA_FIELD (slider_position); | |
164 UPDATE_DATA_FIELD (scrollbar_width); | |
165 UPDATE_DATA_FIELD (scrollbar_height); | |
166 UPDATE_DATA_FIELD (scrollbar_x); | |
167 UPDATE_DATA_FIELD (scrollbar_y); | |
168 | |
169 /* This doesn't work with Athena, why? */ | |
170 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) | |
171 if (w && !vertical_drag_in_progress) | |
172 { | |
173 int new_vov = SCROLLBAR_X_POS_DATA (inst).slider_position; | |
174 int new_vows = marker_position (w->start[CURRENT_DISP]); | |
175 | |
176 if (SCROLLBAR_X_VDRAG_ORIG_VALUE (inst) != new_vov) | |
177 { | |
178 SCROLLBAR_X_VDRAG_ORIG_VALUE (inst) = new_vov; | |
179 inst->scrollbar_instance_changed = 1; | |
180 } | |
181 if (SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (inst) != new_vows) | |
182 { | |
183 SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (inst) = new_vows; | |
184 inst->scrollbar_instance_changed = 1; | |
185 } | |
186 } | |
187 #endif | |
188 } | |
189 | |
190 /* Used by x_update_scrollbar_instance_status. */ | |
191 static void | |
192 update_one_scrollbar_bs (struct frame *f, Widget sb_widget) | |
193 { | |
194 Boolean use_backing_store; | |
195 | |
196 Xt_GET_VALUE (FRAME_X_TEXT_WIDGET (f), XtNuseBackingStore, &use_backing_store); | |
197 | |
198 if (use_backing_store && sb_widget) | |
199 { | |
200 unsigned long mask = CWBackingStore; | |
201 XSetWindowAttributes attrs; | |
202 | |
203 attrs.backing_store = Always; | |
204 XChangeWindowAttributes (XtDisplay (sb_widget), | |
205 XtWindow (sb_widget), | |
206 mask, | |
207 &attrs); | |
208 } | |
209 } | |
210 | |
211 /* Create a widget value structure for passing down to lwlib so that | |
212 it can update the scrollbar widgets. Used by | |
213 x_update_scrollbar_instance_status. */ | |
214 static widget_value * | |
215 scrollbar_instance_to_widget_value (struct scrollbar_instance *instance) | |
216 { | |
217 widget_value *wv; | |
218 | |
219 wv = xmalloc_widget_value (); | |
220 /* #### maybe should add malloc_scrollbar_values to resource these? */ | |
221 wv->scrollbar_data = xnew (scrollbar_values); | |
222 | |
223 wv->name = SCROLLBAR_X_NAME (instance); | |
436 | 224 wv->name = xstrdup (wv->name); |
428 | 225 wv->value = 0; |
226 wv->key = 0; | |
227 wv->enabled = instance->scrollbar_is_active; | |
228 wv->selected = 0; | |
229 wv->call_data = NULL; | |
230 | |
231 *wv->scrollbar_data = SCROLLBAR_X_POS_DATA (instance); | |
232 | |
233 wv->next = NULL; | |
234 | |
235 return wv; | |
236 } | |
237 | |
238 /* Used by x_update_scrollbar_instance_status. */ | |
239 static void | |
240 update_one_widget_scrollbar_pointer (struct window *w, Widget wid) | |
241 { | |
242 if (POINTER_IMAGE_INSTANCEP (w->scrollbar_pointer)) | |
243 { | |
244 XDefineCursor (XtDisplay (wid), XtWindow (wid), | |
245 XIMAGE_INSTANCE_X_CURSOR (w->scrollbar_pointer)); | |
246 XSync (XtDisplay (wid), False); | |
247 } | |
248 } | |
249 | |
250 /* A device method. */ | |
251 static void | |
252 x_update_scrollbar_instance_status (struct window *w, int active, int size, | |
253 struct scrollbar_instance *instance) | |
254 { | |
255 struct frame *f = XFRAME (w->frame); | |
256 Boolean managed = XtIsManaged (SCROLLBAR_X_WIDGET (instance)); | |
257 | |
258 if (active && size) | |
259 { | |
260 widget_value *wv = scrollbar_instance_to_widget_value (instance); | |
261 | |
262 if (instance->scrollbar_instance_changed) | |
263 { | |
264 lw_modify_all_widgets (SCROLLBAR_X_ID (instance), wv, 0); | |
265 instance->scrollbar_instance_changed = 0; | |
266 } | |
267 | |
268 if (!managed) | |
269 { | |
270 XtManageChild (SCROLLBAR_X_WIDGET (instance)); | |
271 if (XtWindow (SCROLLBAR_X_WIDGET (instance))) | |
272 { | |
273 /* Raise this window so that it's visible on top of the | |
274 text window below it. */ | |
275 XRaiseWindow (XtDisplay (SCROLLBAR_X_WIDGET (instance)), | |
276 XtWindow (SCROLLBAR_X_WIDGET (instance))); | |
277 update_one_widget_scrollbar_pointer | |
278 (w, SCROLLBAR_X_WIDGET (instance)); | |
279 if (!SCROLLBAR_X_BACKING_STORE_INITIALIZED (instance)) | |
280 { | |
281 update_one_scrollbar_bs (f, SCROLLBAR_X_WIDGET (instance)); | |
282 SCROLLBAR_X_BACKING_STORE_INITIALIZED (instance) = 1; | |
283 } | |
284 } | |
285 } | |
286 | |
5050
6f2158fa75ed
Fix quick-build, use asserts() in place of ABORT()
Ben Wing <ben@xemacs.org>
parents:
4976
diff
changeset
|
287 assert (wv->scrollbar_data); |
436 | 288 free_widget_value_tree (wv); |
428 | 289 } |
290 else if (managed) | |
291 { | |
292 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) | |
293 /* This isn't needed with Athena Scrollbars. It might not be needed */ | |
294 /* with Motif scrollbars (it is apparently needed with Lesstif). */ | |
295 XtUngrabKeyboard (SCROLLBAR_X_WIDGET (instance), CurrentTime); | |
296 #endif | |
297 XtUnmanageChild (SCROLLBAR_X_WIDGET (instance)); | |
298 } | |
299 } | |
300 | |
301 enum x_scrollbar_loop | |
302 { | |
303 X_FIND_SCROLLBAR_WINDOW_MIRROR, | |
304 X_SET_SCROLLBAR_POINTER, | |
305 X_WINDOW_IS_SCROLLBAR, | |
306 X_UPDATE_FRAME_SCROLLBARS | |
307 }; | |
308 | |
309 static struct window_mirror * | |
310 x_scrollbar_loop (enum x_scrollbar_loop type, Lisp_Object window, | |
311 struct window_mirror *mir, | |
312 LWLIB_ID id, Window x_win) | |
313 { | |
314 struct window_mirror *retval = NULL; | |
315 | |
316 while (mir) | |
317 { | |
318 struct scrollbar_instance *vinstance = mir->scrollbar_vertical_instance; | |
319 struct scrollbar_instance *hinstance = mir->scrollbar_horizontal_instance; | |
320 struct window *w = XWINDOW (window); | |
321 | |
322 if (mir->vchild) | |
323 retval = x_scrollbar_loop (type, w->vchild, mir->vchild, id, x_win); | |
324 else if (mir->hchild) | |
325 retval = x_scrollbar_loop (type, w->hchild, mir->hchild, id, x_win); | |
326 if (retval) | |
327 return retval; | |
328 | |
329 if (hinstance || vinstance) | |
330 { | |
331 switch (type) | |
332 { | |
333 case X_FIND_SCROLLBAR_WINDOW_MIRROR: | |
334 if ((vinstance && SCROLLBAR_X_ID (vinstance) == id) || | |
335 (hinstance && SCROLLBAR_X_ID (hinstance) == id)) | |
336 return mir; | |
337 break; | |
338 case X_UPDATE_FRAME_SCROLLBARS: | |
339 if (!mir->vchild && !mir->hchild) | |
340 update_window_scrollbars (w, mir, 1, 0); | |
341 break; | |
342 case X_SET_SCROLLBAR_POINTER: | |
343 if (!mir->vchild && !mir->hchild) | |
344 { | |
345 Widget widget; | |
346 | |
347 widget = SCROLLBAR_X_WIDGET (hinstance); | |
348 if (widget && XtIsManaged (widget)) | |
349 update_one_widget_scrollbar_pointer (w, widget); | |
350 | |
351 widget = SCROLLBAR_X_WIDGET (vinstance); | |
352 if (widget && XtIsManaged (widget)) | |
353 update_one_widget_scrollbar_pointer (w, widget); | |
354 } | |
355 break; | |
356 case X_WINDOW_IS_SCROLLBAR: | |
357 if (!mir->vchild && !mir->hchild) | |
358 { | |
359 Widget widget; | |
360 | |
361 widget = SCROLLBAR_X_WIDGET (hinstance); | |
362 if (widget && XtIsManaged (widget) && | |
363 XtWindow (widget) == x_win) | |
364 return (struct window_mirror *) 1; | |
365 | |
366 widget = SCROLLBAR_X_WIDGET (vinstance); | |
367 if (widget && XtIsManaged (widget) && | |
368 XtWindow (widget) == x_win) | |
369 return (struct window_mirror *) 1; | |
370 } | |
371 break; | |
372 default: | |
2500 | 373 ABORT (); |
428 | 374 } |
375 } | |
376 | |
377 mir = mir->next; | |
378 window = w->next; | |
379 } | |
380 | |
381 return NULL; | |
382 } | |
383 | |
384 /* Used by callbacks. */ | |
385 static struct window_mirror * | |
386 find_scrollbar_window_mirror (struct frame *f, LWLIB_ID id) | |
387 { | |
388 if (f->mirror_dirty) | |
389 update_frame_window_mirror (f); | |
390 return x_scrollbar_loop (X_FIND_SCROLLBAR_WINDOW_MIRROR, f->root_window, | |
617 | 391 XWINDOW_MIRROR (f->root_mirror), id, (Window) NULL); |
428 | 392 } |
393 | |
394 /* | |
395 * This is the only callback provided for vertical scrollbars. It | |
396 * should be able to handle all of the scrollbar events in | |
397 * scroll_action (see lwlib.h). The client data will be of type | |
398 * scroll_event (see lwlib.h). */ | |
399 static void | |
400 x_update_vertical_scrollbar_callback (Widget widget, LWLIB_ID id, | |
401 XtPointer client_data) | |
402 { | |
403 /* This function can GC */ | |
404 scroll_event *data = (scroll_event *) client_data; | |
405 struct device *d = get_device_from_display (XtDisplay (widget)); | |
406 struct frame *f = x_any_window_to_frame (d, XtWindow (widget)); | |
407 Lisp_Object win, frame; | |
408 struct scrollbar_instance *instance; | |
409 struct window_mirror *mirror; | |
410 | |
411 if (!f) | |
412 return; | |
413 | |
414 mirror = find_scrollbar_window_mirror (f, id); | |
442 | 415 if (!mirror) |
416 return; | |
417 | |
428 | 418 win = real_window (mirror, 1); |
419 | |
420 if (NILP (win)) | |
421 return; | |
422 instance = mirror->scrollbar_vertical_instance; | |
423 frame = WINDOW_FRAME (XWINDOW (win)); | |
424 | |
425 /* It seems that this is necessary whenever signal_special_Xt_user_event() | |
426 is called. #### Why??? */ | |
427 DEVICE_X_MOUSE_TIMESTAMP (d) = DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d); | |
428 | |
429 switch (data->action) | |
430 { | |
431 case SCROLLBAR_LINE_UP: | |
432 signal_special_Xt_user_event (frame, Qscrollbar_line_up, win); | |
433 break; | |
434 | |
435 case SCROLLBAR_LINE_DOWN: | |
436 signal_special_Xt_user_event (frame, Qscrollbar_line_down, win); | |
437 break; | |
438 | |
439 /* The Athena scrollbar paging behavior is that of xterms. | |
440 Depending on where you click the size of the page varies. | |
441 Motif always does a standard Emacs page. */ | |
442 case SCROLLBAR_PAGE_UP: | |
443 #if !defined (LWLIB_SCROLLBARS_MOTIF) && !defined (LWLIB_SCROLLBARS_LUCID) && \ | |
444 !defined (LWLIB_SCROLLBARS_ATHENA3D) | |
445 { | |
446 double tmp = ((double) data->slider_value / | |
447 (double) SCROLLBAR_X_POS_DATA(instance).scrollbar_height); | |
448 double line = tmp * | |
449 (double) window_displayed_height (XWINDOW (win)); | |
450 | |
451 if (line > -1.0) | |
452 line = -1.0; | |
453 signal_special_Xt_user_event (frame, Qscrollbar_page_up, | |
454 Fcons (win, make_int ((int) line))); | |
455 } | |
456 #else | |
457 signal_special_Xt_user_event (frame, Qscrollbar_page_up, | |
458 Fcons (win, Qnil)); | |
459 #endif | |
460 break; | |
461 | |
462 case SCROLLBAR_PAGE_DOWN: | |
463 #if !defined (LWLIB_SCROLLBARS_MOTIF) && !defined (LWLIB_SCROLLBARS_LUCID) && \ | |
464 !defined (LWLIB_SCROLLBARS_ATHENA3D) | |
465 { | |
466 double tmp = ((double) data->slider_value / | |
467 (double) SCROLLBAR_X_POS_DATA(instance).scrollbar_height); | |
468 double line = tmp * | |
469 (double) window_displayed_height (XWINDOW (win)); | |
470 | |
471 if (SCROLLBAR_X_POS_DATA(instance).maximum > | |
472 (SCROLLBAR_X_POS_DATA(instance).slider_size + SCROLLBAR_X_POS_DATA(instance).slider_position)) | |
473 { | |
474 if (line < 1.0) | |
475 line = 1.0; | |
476 signal_special_Xt_user_event (frame, Qscrollbar_page_down, | |
477 Fcons (win, | |
478 make_int ((int) line))); | |
479 } | |
480 } | |
481 #else | |
482 signal_special_Xt_user_event (frame, Qscrollbar_page_down, | |
483 Fcons (win, Qnil)); | |
484 #endif | |
485 break; | |
486 | |
487 case SCROLLBAR_TOP: | |
488 signal_special_Xt_user_event (frame, Qscrollbar_to_top, win); | |
489 break; | |
490 | |
491 case SCROLLBAR_BOTTOM: | |
492 signal_special_Xt_user_event (frame, Qscrollbar_to_bottom, win); | |
493 break; | |
494 | |
495 | |
496 case SCROLLBAR_CHANGE: | |
497 inhibit_slider_size_change = 0; | |
498 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) | |
499 vertical_drag_in_progress = 0; | |
500 SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) = data->slider_value; | |
501 SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance) = | |
502 XINT (Fwindow_start (win)); | |
503 #else | |
504 stupid_vertical_scrollbar_drag_hack = 0; | |
505 #endif | |
506 break; | |
507 | |
508 case SCROLLBAR_DRAG: | |
509 { | |
510 int value; | |
511 | |
512 inhibit_slider_size_change = 1; | |
513 | |
514 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) | |
515 /* Doing drags with Motif-like scrollbars is a mess, since we | |
516 want to avoid having the window position jump when you | |
517 first grab the scrollbar, but we also want to ensure that | |
518 you can scroll all the way to the top or bottom of the | |
519 buffer. This can all be replaced with something sane when | |
520 we get line-based scrolling. */ | |
521 | |
522 vertical_drag_in_progress = 1; | |
523 | |
524 if (SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) < 0) | |
525 { | |
526 SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) = data->slider_value; | |
527 SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance) = | |
528 XINT (Fwindow_start (win)); | |
529 } | |
530 | |
531 /* Could replace this piecewise linear scrolling with a | |
532 quadratic through the three points, but I'm not sure that | |
533 would feel any nicer in practice. */ | |
534 if (data->slider_value < SCROLLBAR_X_VDRAG_ORIG_VALUE (instance)) | |
535 { | |
536 /* We've dragged up; slide linearly from original position to | |
537 window-start=data.minimum, slider-value=data.minimum. */ | |
538 | |
539 if (SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) | |
540 <= SCROLLBAR_X_POS_DATA (instance).minimum) | |
541 { | |
542 /* shouldn't get here, but just in case */ | |
543 value = SCROLLBAR_X_POS_DATA (instance).minimum; | |
544 } | |
545 else | |
546 { | |
547 value = (int) | |
548 (SCROLLBAR_X_POS_DATA (instance).minimum | |
549 + (((double) | |
550 (SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance) | |
551 - SCROLLBAR_X_POS_DATA (instance).minimum) | |
552 * (data->slider_value - | |
553 SCROLLBAR_X_POS_DATA (instance).minimum)) | |
554 / (SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) | |
555 - SCROLLBAR_X_POS_DATA (instance).minimum))); | |
556 } | |
557 } | |
558 else | |
559 { | |
560 /* We've dragged down; slide linearly from original position to | |
561 window-start=data.maximum, slider-value=data.maximum. */ | |
562 | |
563 if (SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) | |
564 >= (SCROLLBAR_X_POS_DATA (instance).maximum - | |
565 SCROLLBAR_X_POS_DATA (instance).slider_size)) | |
566 { | |
567 /* avoid divide by zero */ | |
568 value = SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance); | |
569 } | |
570 else | |
571 { | |
572 value = (int) | |
573 (SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance) | |
574 + (((double) | |
575 (SCROLLBAR_X_POS_DATA (instance).maximum | |
576 - SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance)) | |
577 * (data->slider_value | |
578 - SCROLLBAR_X_VDRAG_ORIG_VALUE (instance))) | |
579 / (SCROLLBAR_X_POS_DATA (instance).maximum | |
580 - SCROLLBAR_X_POS_DATA (instance).slider_size | |
581 - SCROLLBAR_X_VDRAG_ORIG_VALUE (instance)))); | |
582 } | |
583 } | |
584 #else | |
585 stupid_vertical_scrollbar_drag_hack = 0; | |
586 value = data->slider_value; | |
587 #endif | |
588 | |
589 if (value >= SCROLLBAR_X_POS_DATA (instance).maximum) | |
590 value = SCROLLBAR_X_POS_DATA (instance).maximum - 1; | |
591 if (value < SCROLLBAR_X_POS_DATA (instance).minimum) | |
592 value = SCROLLBAR_X_POS_DATA (instance).minimum; | |
593 | |
594 signal_special_Xt_user_event (frame, Qscrollbar_vertical_drag, | |
595 Fcons (win, make_int (value))); | |
596 } | |
597 break; | |
598 | |
599 } | |
600 } | |
601 | |
602 /* | |
603 * This is the only callback provided for horizontal scrollbars. It | |
604 * should be able to handle all of the scrollbar events in | |
605 * scroll_action (see lwlib.h). The client data will be of type | |
606 * scroll_event (see lwlib.h). */ | |
607 static void | |
608 x_update_horizontal_scrollbar_callback (Widget widget, LWLIB_ID id, | |
609 XtPointer client_data) | |
610 { | |
611 scroll_event *data = (scroll_event *) client_data; | |
612 struct device *d = get_device_from_display (XtDisplay (widget)); | |
613 struct frame *f = x_any_window_to_frame (d, XtWindow (widget)); | |
614 Lisp_Object win, frame; | |
615 struct window_mirror *mirror; | |
616 | |
617 if (!f) | |
618 return; | |
619 | |
620 mirror = find_scrollbar_window_mirror (f, id); | |
442 | 621 if (!mirror) |
622 return; | |
623 | |
428 | 624 win = real_window (mirror, 1); |
625 | |
626 if (NILP (win)) | |
627 return; | |
628 frame = WINDOW_FRAME (XWINDOW (win)); | |
629 | |
630 /* It seems that this is necessary whenever signal_special_Xt_user_event() | |
631 is called. #### Why??? */ | |
632 DEVICE_X_MOUSE_TIMESTAMP (d) = DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d); | |
633 | |
634 switch (data->action) | |
635 { | |
636 case SCROLLBAR_LINE_UP: | |
637 signal_special_Xt_user_event (frame, Qscrollbar_char_left, win); | |
638 break; | |
639 case SCROLLBAR_LINE_DOWN: | |
640 signal_special_Xt_user_event (frame, Qscrollbar_char_right, win); | |
641 break; | |
642 case SCROLLBAR_PAGE_UP: | |
643 signal_special_Xt_user_event (frame, Qscrollbar_page_left, win); | |
644 break; | |
645 case SCROLLBAR_PAGE_DOWN: | |
646 signal_special_Xt_user_event (frame, Qscrollbar_page_right, win); | |
647 break; | |
648 case SCROLLBAR_TOP: | |
649 signal_special_Xt_user_event (frame, Qscrollbar_to_left, win); | |
650 break; | |
651 case SCROLLBAR_BOTTOM: | |
652 signal_special_Xt_user_event (frame, Qscrollbar_to_right, win); | |
653 break; | |
654 case SCROLLBAR_CHANGE: | |
655 inhibit_slider_size_change = 0; | |
656 break; | |
657 case SCROLLBAR_DRAG: | |
658 inhibit_slider_size_change = 1; | |
659 /* #### Fix the damn toolkit code so they all work the same way. | |
660 Lucid is the one mostly wrong.*/ | |
661 #if defined (LWLIB_SCROLLBARS_LUCID) || defined (LWLIB_SCROLLBARS_ATHENA3D) | |
662 signal_special_Xt_user_event (frame, Qscrollbar_horizontal_drag, | |
663 (Fcons | |
664 (win, make_int (data->slider_value)))); | |
665 #else | |
666 signal_special_Xt_user_event (frame, Qscrollbar_horizontal_drag, | |
667 (Fcons | |
668 (win, | |
669 make_int (data->slider_value - 1)))); | |
670 #endif | |
671 break; | |
672 default: | |
673 break; | |
674 } | |
675 } | |
676 | |
677 static void | |
678 x_scrollbar_pointer_changed_in_window (struct window *w) | |
679 { | |
793 | 680 Lisp_Object window = wrap_window (w); |
428 | 681 |
682 x_scrollbar_loop (X_SET_SCROLLBAR_POINTER, window, find_window_mirror (w), | |
683 0, (Window) NULL); | |
684 } | |
685 | |
686 /* Make sure that all scrollbars on frame are up-to-date. Called | |
687 directly from x_set_frame_properties in frame-x.c*/ | |
688 void | |
689 x_update_frame_scrollbars (struct frame *f) | |
690 { | |
617 | 691 x_scrollbar_loop (X_UPDATE_FRAME_SCROLLBARS, f->root_window, |
692 XWINDOW_MIRROR (f->root_mirror), 0, (Window) NULL); | |
428 | 693 } |
694 | |
695 #ifdef MEMORY_USAGE_STATS | |
696 | |
697 static int | |
2286 | 698 x_compute_scrollbar_instance_usage (struct device *UNUSED (d), |
428 | 699 struct scrollbar_instance *inst, |
700 struct overhead_stats *ovstats) | |
701 { | |
702 int total = 0; | |
703 | |
704 while (inst) | |
705 { | |
706 struct x_scrollbar_data *data = | |
707 (struct x_scrollbar_data *) inst->scrollbar_data; | |
708 | |
3024 | 709 total += malloced_storage_size (data, sizeof (*data), ovstats); |
710 total += malloced_storage_size (data->name, 1 + strlen (data->name), | |
428 | 711 ovstats); |
712 inst = inst->next; | |
713 } | |
714 | |
715 return total; | |
716 } | |
717 | |
718 #endif /* MEMORY_USAGE_STATS */ | |
719 | |
720 | |
721 /************************************************************************/ | |
722 /* initialization */ | |
723 /************************************************************************/ | |
724 | |
725 void | |
726 console_type_create_scrollbar_x (void) | |
727 { | |
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 */ | |
738 } | |
739 | |
740 void | |
741 reinit_vars_of_scrollbar_x (void) | |
742 { | |
743 stupid_vertical_scrollbar_drag_hack = 1; | |
744 } | |
745 | |
746 void | |
747 vars_of_scrollbar_x (void) | |
748 { | |
749 #if defined (LWLIB_SCROLLBARS_LUCID) | |
750 Fprovide (intern ("lucid-scrollbars")); | |
751 #elif defined (LWLIB_SCROLLBARS_MOTIF) | |
752 Fprovide (intern ("motif-scrollbars")); | |
753 #elif defined (LWLIB_SCROLLBARS_ATHENA) | |
754 Fprovide (intern ("athena-scrollbars")); | |
755 #endif | |
756 } |