Mercurial > hg > xemacs-beta
annotate src/scrollbar-x.c @ 2720:6fa9919a9a0b
[xemacs-hg @ 2005-04-08 23:10:01 by crestani]
ChangeLog addition:
2005-04-01 Marcus Crestani <crestani@xemacs.org>
The new allocator.
New configure flag: `MC_ALLOC':
* configure.ac (XE_COMPLEX_ARG_ENABLE): Add `--enable-mc-alloc' as
a new configure flag.
* configure.in (AC_INIT_PARSE_ARGS): Add `--mc-alloc' as a new
configure flag.
* configure.usage: Add description for `mc-alloc'.
DUMP_IN_EXEC:
* Makefile.in.in: Condition the installation of a separate dump
file on !DUMP_ON_EXEC.
* configure.ac (XE_COMPLEX_ARG_ENABLE): Add
`--enable-dump-in-exec' as a new configure flag.
* configure.ac: DUMP_IN_EXEC is define as default for PDUMP but
not default for MC_ALLOC.
* configure.in (AC_INIT_PARSE_ARGS): Add `--dump-in-exec' as a
new configure flag.
* configure.in: DUMP_IN_EXEC is define as default for PDUMP but
not default for MC_ALLOC.
* configure.usage: Add description for `dump-in-exec'.
lib-src/ChangeLog addition:
2005-04-01 Marcus Crestani <crestani@xemacs.org>
The new allocator.
DUMP_IN_EXEC:
* Makefile.in.in: Only compile insert-data-in-exec if
DUMP_IN_EXEC is defined.
lisp/ChangeLog addition:
2005-04-01 Marcus Crestani <crestani@xemacs.org>
The new allocator.
MEMORY_USAGE_STATS
* diagnose.el: Add new lisp function to pretty print statistics
about the new allocator.
* diagnose.el (show-mc-alloc-memory-usage): New.
modules/ChangeLog addition:
2005-04-01 Marcus Crestani <crestani@xemacs.org>
The new allocator.
Remove Lcrecords:
* postgresql/postgresql.c (allocate_pgconn): Allocate with new
allocator.
* postgresql/postgresql.c (allocate_pgresult): Allocate PGresult
with new allocator.
* postgresql/postgresql.h (struct Lisp_PGconn): Add
lrecord_header.
* postgresql/postgresql.h (struct Lisp_PGresult): Add
lrecord_header.
* ldap/eldap.c (allocate_ldap): Allocate with new allocator.
* ldap/eldap.h (struct Lisp_LDAP): Add lrecord_header.
nt/ChangeLog addition:
2005-04-01 Marcus Crestani <crestani@xemacs.org>
The new allocator.
New configure flag: `MC_ALLOC':
* config.inc.samp: Add new flag `MC_ALLOC'.
* xemacs.mak: Add flag and configuration output for `MC_ALLOC'.
New files:
* xemacs.dsp: Add source files mc-alloc.c and mc-alloc.h.
* xemacs.mak: Add new object file mc-alloc.obj to dependencies.
src/ChangeLog addition:
2005-04-01 Marcus Crestani <crestani@xemacs.org>
The new allocator.
New configure flag: `MC_ALLOC':
* config.h.in: Add new flag `MC_ALLOC'.
New files:
* Makefile.in.in: Add new object file mc-alloc.o.
* depend: Add new files to dependencies.
* mc-alloc.c: New.
* mc-alloc.h: New.
Running the new allocator from XEmacs:
* alloc.c (deadbeef_memory): Moved to mc-alloc.c.
* emacs.c (main_1): Initialize the new allocator and add
syms_of_mc_alloc.
* symsinit.h: Add syms_of_mc_alloc.
New lrecord allocation and free functions:
* alloc.c (alloc_lrecord): New. Allocates an lrecord, includes
type checking and initializing of the lrecord_header.
* alloc.c (noseeum_alloc_lrecord): Same as above, but increments
the NOSEEUM cons counter.
* alloc.c (free_lrecord): New. Calls the finalizer and frees the
lrecord.
* lrecord.h: Add lrecord allocation prototypes and comments.
Remove old lrecord FROB block allocation:
* alloc.c (allocate_lisp_storage): Former function to expand
heap. Not needed anymore, remove.
* alloc.c: Completely remove `Fixed-size type macros'
* alloc.c (release_breathing_space): Remove.
* alloc.c (memory_full): Remove release_breathing_space.
* alloc.c (refill_memory_reserve): Remove.
* alloc.c (TYPE_ALLOC_SIZE): Remove.
* alloc.c (DECLARE_FIXED_TYPE_ALLOC): Remove.
* alloc.c (ALLOCATE_FIXED_TYPE_FROM_BLOCK): Remove.
* alloc.c (ALLOCATE_FIXED_TYPE_1): Remove.
* alloc.c (ALLOCATE_FIXED_TYPE): Remove.
* alloc.c (NOSEEUM_ALLOCATE_FIXED_TYPE): Remove.
* alloc.c (struct Lisp_Free): Remove.
* alloc.c (LRECORD_FREE_P): Remove.
* alloc.c (MARK_LRECORD_AS_FREE): Remove.
* alloc.c (MARK_LRECORD_AS_NOT_FREE): Remove.
* alloc.c (PUT_FIXED_TYPE_ON_FREE_LIST): Remove.
* alloc.c (FREE_FIXED_TYPE): Remove.
* alloc.c (FREE_FIXED_TYPE_WHEN_NOT_IN_GC): Remove.
Allocate old lrecords with new allocator:
* alloc.c: DECLARE_FIXED_TYPE_ALLOC removed for all lrecords
defined in alloc.c.
* alloc.c (Fcons): Allocate with new allocator.
* alloc.c (noseeum_cons): Allocate with new allocator.
* alloc.c (make_float): Allocate with new allocator.
* alloc.c (make_bignum): Allocate with new allocator.
* alloc.c (make_bignum_bg): Allocate with new allocator.
* alloc.c (make_ratio): Allocate with new allocator.
* alloc.c (make_ratio_bg): Allocate with new allocator.
* alloc.c (make_ratio_rt): Allocate with new allocator.
* alloc.c (make_bigfloat): Allocate with new allocator.
* alloc.c (make_bigfloat_bf): Allocate with new allocator.
* alloc.c (make_compiled_function): Allocate with new allocator.
* alloc.c (Fmake_symbol): Allocate with new allocator.
* alloc.c (allocate_extent): Allocate with new allocator.
* alloc.c (allocate_event): Allocate with new allocator.
* alloc.c (make_key_data): Allocate with new allocator.
* alloc.c (make_button_data): Allocate with new allocator.
* alloc.c (make_motion_data): Allocate with new allocator.
* alloc.c (make_process_data): Allocate with new allocator.
* alloc.c (make_timeout_data): Allocate with new allocator.
* alloc.c (make_magic_data): Allocate with new allocator.
* alloc.c (make_magic_eval_data): Allocate with new allocator.
* alloc.c (make_eval_data): Allocate with new allocator.
* alloc.c (make_misc_user_data): Allocate with new allocator.
* alloc.c (Fmake_marker): Allocate with new allocator.
* alloc.c (noseeum_make_marker): Allocate with new allocator.
* alloc.c (make_uninit_string): Allocate with new allocator.
* alloc.c (resize_string): Allocate with new allocator.
* alloc.c (make_string_nocopy): Allocate with new allocator.
Garbage Collection:
* alloc.c (GC_CHECK_NOT_FREE): Remove obsolete assertions.
* alloc.c (SWEEP_FIXED_TYPE_BLOCK): Remove.
* alloc.c (SWEEP_FIXED_TYPE_BLOCK_1): Remove.
* alloc.c (sweep_conses): Remove.
* alloc.c (free_cons): Use new allocator to free.
* alloc.c (sweep_compiled_functions): Remove.
* alloc.c (sweep_floats): Remove.
* alloc.c (sweep_bignums): Remove.
* alloc.c (sweep_ratios): Remove.
* alloc.c (sweep_bigfloats): Remove.
* alloc.c (sweep_symbols): Remove.
* alloc.c (sweep_extents): Remove.
* alloc.c (sweep_events): Remove.
* alloc.c (sweep_key_data): Remove.
* alloc.c (free_key_data): Use new allocator to free.
* alloc.c (sweep_button_data): Remove.
* alloc.c (free_button_data): Use new allocator to free.
* alloc.c (sweep_motion_data): Remove.
* alloc.c (free_motion_data): Use new allocator to free.
* alloc.c (sweep_process_data): Remove.
* alloc.c (free_process_data): Use new allocator to free.
* alloc.c (sweep_timeout_data): Remove.
* alloc.c (free_timeout_data): Use new allocator to free.
* alloc.c (sweep_magic_data): Remove.
* alloc.c (free_magic_data): Use new allocator to free.
* alloc.c (sweep_magic_eval_data): Remove.
* alloc.c (free_magic_eval_data): Use new allocator to free.
* alloc.c (sweep_eval_data): Remove.
* alloc.c (free_eval_data): Use new allocator to free.
* alloc.c (sweep_misc_user_data): Remove.
* alloc.c (free_misc_user_data): Use new allocator to free.
* alloc.c (sweep_markers): Remove.
* alloc.c (free_marker): Use new allocator to free.
* alloc.c (garbage_collect_1): Remove release_breathing_space.
* alloc.c (gc_sweep): Remove all the old lcrecord and lrecord
related stuff. Sweeping now works like this: compact string
chars, finalize, sweep.
* alloc.c (common_init_alloc_early): Remove old lrecord
initializations, remove breathing_space.
* emacs.c (Fdump_emacs): Remove release_breathing_space.
* lisp.h: Remove prototype for release_breathing_space.
* lisp.h: Adjust the special cons mark makros.
Lrecord Finalizer:
* alloc.c: Add finalizer to lrecord definition.
* alloc.c (finalize_string): Add finalizer for string.
* bytecode.c: Add finalizer to lrecord definition.
* bytecode.c (finalize_compiled_function): Add finalizer for
compiled function.
* marker.c: Add finalizer to lrecord definition.
* marker.c (finalize_marker): Add finalizer for marker.
These changes build the interface to mc-alloc:
* lrecord.h (MC_ALLOC_CALL_FINALIZER): Tell mc-alloc how to
finalize lrecords.
* lrecord.h (MC_ALLOC_CALL_FINALIZER_FOR_DISKSAVE): Tell
mc-alloc how to finalize for disksave.
Unify lrecords and lcrecords:
* lisp.h (struct Lisp_String): Adjust string union hack to
new lrecord header.
* lrecord.h: Adjust comments.
* lrecord.h (struct lrecord_header): The new lrecord header
includes type, lisp-readonly, free, and uid.
* lrecord.h (set_lheader_implementation): Adjust to new
lrecord_header.
* lrecord.h (struct lrecord_implementation): The field basic_p
for indication of an old lrecord is not needed anymore, remove.
* lrecord.h (MAKE_LRECORD_IMPLEMENTATION): Remove basic_p.
* lrecord.h (MAKE_EXTERNAL_LRECORD_IMPLEMENTATION): Remove
basic_p.
* lrecord.h (copy_sized_lrecord): Remove distinction between
old lrecords and lcrecords.
* lrecord.h (copy_lrecord): Remove distinction between old
lrecords and lcrecords.
* lrecord.h (zero_sized_lrecord): Remove distinction between
old lrecords and lcrecords.
* lrecord.h (zero_lrecord): Remove distinction between old
lrecords and lcrecords.
Remove lcrecords and lcrecord lists:
* alloc.c (basic_alloc_lcrecord): Not needed anymore, remove.
* alloc.c (very_old_free_lcrecord): Not needed anymore, remove.
* alloc.c (copy_lisp_object): No more distinction between
lrecords and lcrecords.
* alloc.c (all_lcrecords): Not needed anymore, remove.
* alloc.c (make_vector_internal): Allocate as lrecord.
* alloc.c (make_bit_vector_internal): Allocate as lrecord.
* alloc.c: Completely remove `lcrecord lists'.
* alloc.c (free_description): Remove.
* alloc.c (lcrecord_list_description): Remove.
* alloc.c (mark_lcrecord_list): Remove.
* alloc.c (make_lcrecord_list): Remove.
* alloc.c (alloc_managed_lcrecord): Remove.
* alloc.c (free_managed_lcrecord): Remove.
* alloc.c (alloc_automanaged_lcrecord): Remove.
* alloc.c (free_lcrecord): Remove.
* alloc.c (lcrecord_stats): Remove.
* alloc.c (tick_lcrecord_stats): Remove.
* alloc.c (disksave_object_finalization_1): Add call to
mc_finalize_for_disksave. Remove the lcrecord way to visit all
objects.
* alloc.c (kkcc_marking): Remove XD_FLAG_FREE_LISP_OBJECT
* alloc.c (sweep_lcrecords_1): Remove.
* alloc.c (common_init_alloc_early): Remove everything related
to lcrecords, remove old lrecord initializations,
* alloc.c (init_lcrecord_lists): Not needed anymore, remove.
* alloc.c (reinit_alloc_early): Remove everything related to
lcrecords.
* alloc.c (init_alloc_once_early): Remove everything related to
lcrecords.
* buffer.c (allocate_buffer): Allocate as lrecord.
* buffer.c (nuke_all_buffer_slots): Use lrecord functions.
* buffer.c (common_init_complex_vars_of_buffer): Allocate as
lrecord.
* buffer.h (struct buffer): Add lrecord_header.
* casetab.c (allocate_case_table): Allocate as lrecord.
* casetab.h (struct Lisp_Case_Table): Add lrecord_header.
* charset.h (struct Lisp_Charset): Add lrecord_header.
* chartab.c (fill_char_table): Use lrecord functions.
* chartab.c (Fmake_char_table): Allocate as lrecord.
* chartab.c (make_char_table_entry): Allocate as lrecord.
* chartab.c (copy_char_table_entry): Allocate as lrecord.
* chartab.c (Fcopy_char_table): Allocate as lrecord.
* chartab.c (put_char_table): Use lrecord functions.
* chartab.h (struct Lisp_Char_Table_Entry): Add lrecord_header.
* chartab.h (struct Lisp_Char_Table): Add lrecord_header.
* console-impl.h (struct console): Add lrecord_header.
* console-msw-impl.h (struct Lisp_Devmode): Add lrecord_header.
* console-msw-impl.h (struct mswindows_dialog_id): Add
lrecord_header.
* console.c (allocate_console): Allocate as lrecord.
* console.c (nuke_all_console_slots): Use lrecord functions.
* console.c (common_init_complex_vars_of_console): Allocate as
lrecord.
* data.c (make_weak_list): Allocate as lrecord.
* data.c (make_weak_box): Allocate as lrecord.
* data.c (make_ephemeron): Allocate as lrecord.
* database.c (struct Lisp_Database): Add lrecord_header.
* database.c (allocate_database): Allocate as lrecord.
* device-impl.h (struct device): Add lrecord_header.
* device-msw.c (allocate_devmode): Allocate as lrecord.
* device.c (nuke_all_device_slots): Use lrecord functions.
* device.c (allocate_device): Allocate as lrecord.
* dialog-msw.c (handle_question_dialog_box): Allocate as lrecord.
* elhash.c (struct Lisp_Hash_Table): Add lrecord_header.
* elhash.c (make_general_lisp_hash_table): Allocate as lrecord.
* elhash.c (Fcopy_hash_table): Allocate as lrecord.
* event-stream.c: Lcrecord lists Vcommand_builder_free_list and
Vtimeout_free_list are no longer needed. Remove.
* event-stream.c (allocate_command_builder): Allocate as lrecord.
* event-stream.c (free_command_builder): Use lrecord functions.
* event-stream.c (event_stream_generate_wakeup): Allocate as
lrecord.
* event-stream.c (event_stream_resignal_wakeup): Use lrecord
functions.
* event-stream.c (event_stream_disable_wakeup): Use lrecord
functions.
* event-stream.c (reinit_vars_of_event_stream): Lcrecord lists
remove.
* events.h (struct Lisp_Timeout): Add lrecord_header.
* events.h (struct command_builder): Add lrecord_header.
* extents-impl.h (struct extent_auxiliary): Add lrecord_header.
* extents-impl.h (struct extent_info): Add lrecord_header.
* extents.c (allocate_extent_auxiliary): Allocate as lrecord.
* extents.c (allocate_extent_info): Allocate as lrecord.
* extents.c (copy_extent): Allocate as lrecord.
* faces.c (allocate_face): Allocate as lrecord.
* faces.h (struct Lisp_Face): Add lrecord_header.
* file-coding.c (allocate_coding_system): Allocate as lrecord.
* file-coding.c (Fcopy_coding_system): Allocate as lrecord.
* file-coding.h (struct Lisp_Coding_System): Add lrecord_header.
* fns.c (Ffillarray): Allocate as lrecord.
* frame-impl.h (struct frame): Add lrecord_header.
* frame.c (nuke_all_frame_slots): Use lrecord functions.
* frame.c (allocate_frame_core): Allocate as lrecord.
* glyphs.c (allocate_image_instance): Allocate as lrecord.
* glyphs.c (Fcolorize_image_instance): Allocate as lrecord.
* glyphs.c (allocate_glyph): Allocate as lrecord.
* glyphs.h (struct Lisp_Image_Instance): Add lrecord_header.
* glyphs.h (struct Lisp_Glyph): Add lrecord_header.
* gui.c (allocate_gui_item): Allocate as lrecord.
* gui.h (struct Lisp_Gui_Item): Add lrecord_header.
* keymap.c (struct Lisp_Keymap): Add lrecord_header.
* keymap.c (make_keymap): Allocate as lrecord.
* lisp.h (struct Lisp_Vector): Add lrecord_header.
* lisp.h (struct Lisp_Bit_Vector): Add lrecord_header.
* lisp.h (struct weak_box): Add lrecord_header.
* lisp.h (struct ephemeron): Add lrecord_header.
* lisp.h (struct weak_list): Add lrecord_header.
* lrecord.h (struct lcrecord_header): Not used, remove.
* lrecord.h (struct free_lcrecord_header): Not used, remove.
* lrecord.h (struct lcrecord_list): Not needed anymore, remove.
* lrecord.h (lcrecord_list): Not needed anymore, remove.
* lrecord.h: (enum data_description_entry_flags): Remove
XD_FLAG_FREE_LISP_OBJECT.
* lstream.c: Lrecord list Vlstream_free_list remove.
* lstream.c (Lstream_new): Allocate as lrecord.
* lstream.c (Lstream_delete): Use lrecod functions.
* lstream.c (reinit_vars_of_lstream): Vlstream_free_list
initialization remove.
* lstream.h (struct lstream): Add lrecord_header.
* emacs.c (main_1): Remove lstream initialization.
* mule-charset.c (make_charset): Allocate as lrecord.
* objects-impl.h (struct Lisp_Color_Instance): Add
lrecord_header.
* objects-impl.h (struct Lisp_Font_Instance): Add lrecord_header.
* objects.c (Fmake_color_instance): Allocate as lrecord.
* objects.c (Fmake_font_instance): Allocate as lrecord.
* objects.c (reinit_vars_of_objects): Allocate as lrecord.
* opaque.c: Lcreord list Vopaque_ptr_list remove.
* opaque.c (make_opaque): Allocate as lrecord.
* opaque.c (make_opaque_ptr): Allocate as lrecord.
* opaque.c (free_opaque_ptr): Use lrecord functions.
* opaque.c (reinit_opaque_early):
* opaque.c (init_opaque_once_early): Vopaque_ptr_list
initialization remove.
* opaque.h (Lisp_Opaque): Add lrecord_header.
* opaque.h (Lisp_Opaque_Ptr): Add lrecord_header.
* emacs.c (main_1): Remove opaque variable initialization.
* print.c (default_object_printer): Use new lrecord_header.
* print.c (print_internal): Use new lrecord_header.
* print.c (debug_p4): Use new lrecord_header.
* process.c (make_process_internal): Allocate as lrecord.
* procimpl.h (struct Lisp_Process): Add lrecord_header.
* rangetab.c (Fmake_range_table): Allocate as lrecord.
* rangetab.c (Fcopy_range_table): Allocate as lrecord.
* rangetab.h (struct Lisp_Range_Table): Add lrecord_header.
* scrollbar.c (create_scrollbar_instance): Allocate as lrecord.
* scrollbar.h (struct scrollbar_instance): Add lrecord_header.
* specifier.c (make_specifier_internal): Allocate as lrecord.
* specifier.h (struct Lisp_Specifier): Add lrecord_header.
* symbols.c:
* symbols.c (Fmake_variable_buffer_local): Allocate as lrecord.
* symbols.c (Fdontusethis_set_symbol_value_handler): Allocate
as lrecord.
* symbols.c (Fdefvaralias): Allocate as lrecord.
* symeval.h (struct symbol_value_magic): Add lrecord_header.
* toolbar.c (update_toolbar_button): Allocate as lrecord.
* toolbar.h (struct toolbar_button): Add lrecord_header.
* tooltalk.c (struct Lisp_Tooltalk_Message): Add lrecord_header.
* tooltalk.c (make_tooltalk_message): Allocate as lrecord.
* tooltalk.c (struct Lisp_Tooltalk_Pattern): Add lrecord_header.
* tooltalk.c (make_tooltalk_pattern): Allocate as lrecord.
* ui-gtk.c (allocate_ffi_data): Allocate as lrecord.
* ui-gtk.c (allocate_emacs_gtk_object_data): Allocate as lrecord.
* ui-gtk.c (allocate_emacs_gtk_boxed_data): Allocate as lrecord.
* ui-gtk.h (structs): Add lrecord_header.
* window-impl.h (struct window): Add lrecord_header.
* window-impl.h (struct window_mirror): Add lrecord_header.
* window.c (allocate_window): Allocate as lrecord.
* window.c (new_window_mirror): Allocate as lrecord.
* window.c (make_dummy_parent): Allocate as lrecord.
MEMORY_USAGE_STATS
* alloc.c (fixed_type_block_overhead): Not used anymore, remove.
* buffer.c (compute_buffer_usage): Get storage size from new
allocator.
* marker.c (compute_buffer_marker_usage): Get storage size from
new allocator.
* mule-charset.c (compute_charset_usage): Get storage size from
new allocator.
* scrollbar-gtk.c (gtk_compute_scrollbar_instance_usage): Get
storage size from new allocator.
* scrollbar-msw.c (mswindows_compute_scrollbar_instance_usage):
Get storage size from new allocator.
* scrollbar-x.c (x_compute_scrollbar_instance_usage): Get
storage size from new allocator.
* scrollbar.c (compute_scrollbar_instance_usage): Get storage
size from new allocator.
* unicode.c (compute_from_unicode_table_size_1): Get storage
size from new allocator.
* unicode.c (compute_to_unicode_table_size_1): Get storage size
from new allocator.
* window.c (compute_window_mirror_usage): Get storage size from
new allocator.
* window.c (compute_window_usage): Get storage size from new
allocator.
MC_ALLOC_TYPE_STATS:
* alloc.c (alloc_lrecord): Bump lrecord count.
* alloc.c (noseeum_alloc_lrecord): Bump lrecord count.
* alloc.c (struct lrecord_stats): Storage for counts.
* alloc.c (init_lrecord_stats): Zero statistics.
* alloc.c (inc_lrecord_stats): Increase the statistic.
* alloc.c (dec_lrecord_stats): Decrease the statistic.
* alloc.c (gc_plist_hack): Used to print the information.
* alloc.c (Fgarbage_collect): Return the collected information.
* mc-alloc.c (remove_cell): Decrease lrecord count.
* mc-alloc.h: Set flag MC_ALLOC_TYPE_STATS.
* emacs.c (main_1): Init lrecord statistics.
* lrecord.h: Add prototypes for *_lrecord_stats.
Strings:
* alloc.c (Fmake_string): Initialize ascii_begin to zero.
* alloc.c (gc_count_num_short_string_in_use): Remove.
* alloc.c (gc_count_string_total_size): Remove.
* alloc.c (gc_count_short_string_total_size): Remove.
* alloc.c (debug_string_purity): Remove.
* alloc.c (debug_string_purity_print): Remove.
* alloc.c (sweep_strings): Remove.
Remove static C-readonly Lisp objects:
* alloc.c (c_readonly): Not needed anymore, remove.
* alloc.c (GC_CHECK_LHEADER_INVARIANTS): Remove some obsolete
lheader invariants assertions.
* buffer.c (DEFVAR_BUFFER_LOCAL_1): Allocate dynamically.
* console.c (DEFVAR_CONSOLE_LOCAL_1): Allocate dynamically.
* gpmevent.c: Indirection via MC_ALLOC_Freceive_gpm_event.
* gpmevent.c (Fgpm_enable): Allocate dynamically.
* gpmevent.c (syms_of_gpmevent): Allocate dynamically.
* lisp.h (C_READONLY): Not needed anymore, remove.
* lisp.h (DEFUN): Allocate dynamically.
* lrecord.h (C_READONLY_RECORD_HEADER_P): Not needed anymore,
remove.
* lrecord.h (SET_C_READONLY_RECORD_HEADER): Not needed anymore,
remove.
* symbols.c (guts_of_unbound_marker):
* symeval.h (defsubr): Allocate dynamically.
* symeval.h (DEFSUBR_MACRO): Allocate dynamically.
* symeval.h (DEFVAR_ SYMVAL_FWD): Allocate dynamically.
* tests.c (TESTS_DEFSUBR): Allocate dynamically.
Definition of mcpro:
* lisp.h: Add mcpro prototypes.
* alloc.c (common_init_alloc_early): Add initialization for
mcpros.
* alloc.c (mcpro_description_1): New.
* alloc.c (mcpro_description): New.
* alloc.c (mcpros_description_1): New.
* alloc.c (mcpros_description): New.
* alloc.c (mcpro_one_name_description_1): New.
* alloc.c (mcpro_one_name_description): New.
* alloc.c (mcpro_names_description_1): New.
* alloc.c (mcpro_names_description): New.
* alloc.c (mcpros): New.
* alloc.c (mcpro_names): New.
* alloc.c (mcpro_1): New.
* alloc.c (mc_pro): New.
* alloc.c (garbage_collect_1): Add mcpros to root set.
Usage of mcpro:
* alloc.c (make_string_nocopy): Add string to root set.
* symbols.c (init_symbols_once_early): Add Qunbound to root set.
Changes to the Portable Dumper:
* alloc.c (FREE_OR_REALLOC_BEGIN): Since dumped objects can be
freed with the new allocator, remove assertion for !DUMPEDP.
* dumper.c: Adjust comments, increase PDUMP_HASHSIZE.
* dumper.c (pdump_make_hash): Shift address only 2 bytes, to
avoid collisions.
* dumper.c (pdump_objects_unmark): No more mark bits within
the object, remove.
* dumper.c (mc_addr_elt): New. Element data structure for mc
hash table.
* dumper.c (pdump_mc_hash): New hash table: `lookup table'.
* dumper.c (pdump_get_mc_addr): New. Lookup for hash table.
* dumper.c (pdump_get_indirect_mc_addr): New. Lookup for
convertibles.
* dumper.c (pdump_put_mc_addr): New. Putter for hash table.
* dumper.c (pdump_dump_mc_data): New. Writes the table for
relocation at load time to the dump file.
* dumper.c (pdump_scan_lisp_objects_by_alignment): New.
Visits all dumped Lisp objects.
* dumper.c (pdump_scan_non_lisp_objects_by_alignment): New.
Visits all other dumped objects.
* dumper.c (pdump_reloc_one_mc): New. Updates all pointers
of an object by using the hash table pdump_mc_hash.
* dumper.c (pdump_reloc_one): Replaced by pdump_reloc_one_mc.
* dumper.c (pdump): Change the structure of the dump file, add
the mc post dump relocation table to dump file.
* dumper.c (pdump_load_finish): Hand all dumped objects to the
new allocator and use the mc post dump relocation table for
relocating the dumped objects at dump file load time, free not
longer used data structures.
* dumper.c (pdump_load): Free the dump file.
* dumper.h: Remove pdump_objects_unmark.
* lrecord.h (DUMPEDP): Dumped objects can be freed, remove.
DUMP_IN_EXEC:
* Makefile.in.in: Linking for and with dump in executable only if
DUMP_IN_EXEC is defined.
* config.h.in: Add new flag `DUMP_IN_EXEC'
* emacs.c: Condition dump-data.h on DUMP_IN_EXEC.
* emacs.c (main_1): Flag `-si' only works if dump image is
written into executable.
Miscellanious
* lrecord.h (enum lrecord_type): Added numbers to all types,
very handy for debugging.
* xemacs.def.in.in: Add mc-alloc functions to make them visible
to the modules.
author | crestani |
---|---|
date | Fri, 08 Apr 2005 23:11:35 +0000 |
parents | 3d8143fc88e1 |
children | 1e7cc382eb16 |
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>. | |
6 | |
7 This file is part of XEmacs. | |
8 | |
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 | |
12 later version. | |
13 | |
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 | |
17 for more details. | |
18 | |
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. */ | |
23 | |
24 /* Synched up with: Not in FSF. */ | |
25 | |
442 | 26 /* This file Mule-ized (more like Mule-verified) by Ben Wing, 7-8-00. */ |
27 | |
428 | 28 #include <config.h> |
29 #include "lisp.h" | |
30 | |
872 | 31 #include "device-impl.h" |
32 #include "frame-impl.h" | |
800 | 33 #include "window.h" |
34 | |
872 | 35 #include "console-x-impl.h" |
428 | 36 #include "glyphs-x.h" |
37 #include "scrollbar-x.h" | |
38 | |
800 | 39 #include "EmacsFrame.h" |
428 | 40 |
41 static void x_update_vertical_scrollbar_callback (Widget widget, LWLIB_ID id, | |
42 XtPointer client_data); | |
43 static void x_update_horizontal_scrollbar_callback (Widget widget, LWLIB_ID id, | |
44 XtPointer client_data); | |
45 | |
46 /* Used to prevent changing the size of the slider while drag | |
47 scrolling, under Motif. This is necessary because the Motif | |
48 scrollbar is incredibly stupid about updating the slider and causes | |
49 lots of flicker if it is done too often. */ | |
50 static int inhibit_slider_size_change; | |
51 int stupid_vertical_scrollbar_drag_hack; | |
52 | |
53 /* Doesn't work with athena */ | |
54 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) | |
55 static int vertical_drag_in_progress; | |
56 #endif | |
57 | |
58 | |
59 /* A device method. */ | |
60 static int | |
61 x_inhibit_scrollbar_slider_size_change (void) | |
62 { | |
63 /* Doesn't work with Athena */ | |
64 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) | |
65 return inhibit_slider_size_change; | |
66 #else | |
67 return 0; | |
68 #endif | |
69 } | |
70 | |
71 /* A device method. */ | |
72 static void | |
73 x_free_scrollbar_instance (struct scrollbar_instance *instance) | |
74 { | |
75 if (SCROLLBAR_X_NAME (instance)) | |
1726 | 76 xfree (SCROLLBAR_X_NAME (instance), char *); |
428 | 77 |
78 if (SCROLLBAR_X_WIDGET (instance)) | |
79 { | |
80 if (XtIsManaged (SCROLLBAR_X_WIDGET (instance))) | |
81 XtUnmanageChild (SCROLLBAR_X_WIDGET (instance)); | |
82 | |
83 lw_destroy_all_widgets (SCROLLBAR_X_ID (instance)); | |
84 } | |
85 | |
86 if (instance->scrollbar_data) | |
1726 | 87 xfree (instance->scrollbar_data, void *); |
428 | 88 } |
89 | |
90 /* A device method. */ | |
91 static void | |
92 x_release_scrollbar_instance (struct scrollbar_instance *instance) | |
93 { | |
94 if (XtIsManaged (SCROLLBAR_X_WIDGET (instance))) | |
95 XtUnmanageChild (SCROLLBAR_X_WIDGET (instance)); | |
96 } | |
97 | |
98 /* A device method. */ | |
99 static void | |
100 x_create_scrollbar_instance (struct frame *f, int vertical, | |
101 struct scrollbar_instance *instance) | |
102 { | |
103 char buffer[32]; | |
104 | |
105 /* initialize the X specific data section. */ | |
106 instance->scrollbar_data = xnew_and_zero (struct x_scrollbar_data); | |
107 | |
108 SCROLLBAR_X_ID (instance) = new_lwlib_id (); | |
109 sprintf (buffer, "scrollbar_%d", SCROLLBAR_X_ID (instance)); | |
110 SCROLLBAR_X_NAME (instance) = xstrdup (buffer); | |
111 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) || \ | |
112 defined (LWLIB_SCROLLBARS_ATHENA3D) | |
113 SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) = -1; | |
114 #endif | |
115 | |
116 if (vertical) | |
117 { | |
118 SCROLLBAR_X_WIDGET (instance) = | |
119 lw_create_widget ("vertical-scrollbar", SCROLLBAR_X_NAME (instance), | |
120 SCROLLBAR_X_ID (instance), | |
121 NULL, FRAME_X_CONTAINER_WIDGET (f), 0, | |
122 x_update_vertical_scrollbar_callback, NULL, NULL); | |
123 } | |
124 else | |
125 { | |
126 SCROLLBAR_X_WIDGET (instance) = | |
127 lw_create_widget ("horizontal-scrollbar", SCROLLBAR_X_NAME (instance), | |
128 SCROLLBAR_X_ID (instance), | |
129 NULL, FRAME_X_CONTAINER_WIDGET (f), 0, | |
130 x_update_horizontal_scrollbar_callback, NULL, NULL); | |
131 } | |
132 } | |
133 | |
134 #define UPDATE_DATA_FIELD(field) \ | |
135 if (new_##field >= 0 && \ | |
136 SCROLLBAR_X_POS_DATA (inst).field != new_##field) { \ | |
137 SCROLLBAR_X_POS_DATA (inst).field = new_##field; \ | |
138 inst->scrollbar_instance_changed = 1; \ | |
139 } | |
140 | |
141 /* A device method. */ | |
142 /* #### The -1 check is such a hack. */ | |
143 static void | |
144 x_update_scrollbar_instance_values (struct window *w, | |
145 struct scrollbar_instance *inst, | |
146 int new_line_increment, | |
147 int new_page_increment, | |
148 int new_minimum, int new_maximum, | |
149 int new_slider_size, | |
150 int new_slider_position, | |
151 int new_scrollbar_width, | |
152 int new_scrollbar_height, | |
153 int new_scrollbar_x, int new_scrollbar_y) | |
154 { | |
155 UPDATE_DATA_FIELD (line_increment); | |
156 UPDATE_DATA_FIELD (page_increment); | |
157 UPDATE_DATA_FIELD (minimum); | |
158 UPDATE_DATA_FIELD (maximum); | |
159 UPDATE_DATA_FIELD (slider_size); | |
160 UPDATE_DATA_FIELD (slider_position); | |
161 UPDATE_DATA_FIELD (scrollbar_width); | |
162 UPDATE_DATA_FIELD (scrollbar_height); | |
163 UPDATE_DATA_FIELD (scrollbar_x); | |
164 UPDATE_DATA_FIELD (scrollbar_y); | |
165 | |
166 /* This doesn't work with Athena, why? */ | |
167 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) | |
168 if (w && !vertical_drag_in_progress) | |
169 { | |
170 int new_vov = SCROLLBAR_X_POS_DATA (inst).slider_position; | |
171 int new_vows = marker_position (w->start[CURRENT_DISP]); | |
172 | |
173 if (SCROLLBAR_X_VDRAG_ORIG_VALUE (inst) != new_vov) | |
174 { | |
175 SCROLLBAR_X_VDRAG_ORIG_VALUE (inst) = new_vov; | |
176 inst->scrollbar_instance_changed = 1; | |
177 } | |
178 if (SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (inst) != new_vows) | |
179 { | |
180 SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (inst) = new_vows; | |
181 inst->scrollbar_instance_changed = 1; | |
182 } | |
183 } | |
184 #endif | |
185 } | |
186 | |
187 /* Used by x_update_scrollbar_instance_status. */ | |
188 static void | |
189 update_one_scrollbar_bs (struct frame *f, Widget sb_widget) | |
190 { | |
191 Boolean use_backing_store; | |
192 | |
193 Xt_GET_VALUE (FRAME_X_TEXT_WIDGET (f), XtNuseBackingStore, &use_backing_store); | |
194 | |
195 if (use_backing_store && sb_widget) | |
196 { | |
197 unsigned long mask = CWBackingStore; | |
198 XSetWindowAttributes attrs; | |
199 | |
200 attrs.backing_store = Always; | |
201 XChangeWindowAttributes (XtDisplay (sb_widget), | |
202 XtWindow (sb_widget), | |
203 mask, | |
204 &attrs); | |
205 } | |
206 } | |
207 | |
208 /* Create a widget value structure for passing down to lwlib so that | |
209 it can update the scrollbar widgets. Used by | |
210 x_update_scrollbar_instance_status. */ | |
211 static widget_value * | |
212 scrollbar_instance_to_widget_value (struct scrollbar_instance *instance) | |
213 { | |
214 widget_value *wv; | |
215 | |
216 wv = xmalloc_widget_value (); | |
217 /* #### maybe should add malloc_scrollbar_values to resource these? */ | |
218 wv->scrollbar_data = xnew (scrollbar_values); | |
219 | |
220 wv->name = SCROLLBAR_X_NAME (instance); | |
436 | 221 wv->name = xstrdup (wv->name); |
428 | 222 wv->value = 0; |
223 wv->key = 0; | |
224 wv->enabled = instance->scrollbar_is_active; | |
225 wv->selected = 0; | |
226 wv->call_data = NULL; | |
227 | |
228 *wv->scrollbar_data = SCROLLBAR_X_POS_DATA (instance); | |
229 | |
230 wv->next = NULL; | |
231 | |
232 return wv; | |
233 } | |
234 | |
235 /* Used by x_update_scrollbar_instance_status. */ | |
236 static void | |
237 update_one_widget_scrollbar_pointer (struct window *w, Widget wid) | |
238 { | |
239 if (POINTER_IMAGE_INSTANCEP (w->scrollbar_pointer)) | |
240 { | |
241 XDefineCursor (XtDisplay (wid), XtWindow (wid), | |
242 XIMAGE_INSTANCE_X_CURSOR (w->scrollbar_pointer)); | |
243 XSync (XtDisplay (wid), False); | |
244 } | |
245 } | |
246 | |
247 /* A device method. */ | |
248 static void | |
249 x_update_scrollbar_instance_status (struct window *w, int active, int size, | |
250 struct scrollbar_instance *instance) | |
251 { | |
252 struct frame *f = XFRAME (w->frame); | |
253 Boolean managed = XtIsManaged (SCROLLBAR_X_WIDGET (instance)); | |
254 | |
255 if (active && size) | |
256 { | |
257 widget_value *wv = scrollbar_instance_to_widget_value (instance); | |
258 | |
259 if (instance->scrollbar_instance_changed) | |
260 { | |
261 lw_modify_all_widgets (SCROLLBAR_X_ID (instance), wv, 0); | |
262 instance->scrollbar_instance_changed = 0; | |
263 } | |
264 | |
265 if (!managed) | |
266 { | |
267 XtManageChild (SCROLLBAR_X_WIDGET (instance)); | |
268 if (XtWindow (SCROLLBAR_X_WIDGET (instance))) | |
269 { | |
270 /* Raise this window so that it's visible on top of the | |
271 text window below it. */ | |
272 XRaiseWindow (XtDisplay (SCROLLBAR_X_WIDGET (instance)), | |
273 XtWindow (SCROLLBAR_X_WIDGET (instance))); | |
274 update_one_widget_scrollbar_pointer | |
275 (w, SCROLLBAR_X_WIDGET (instance)); | |
276 if (!SCROLLBAR_X_BACKING_STORE_INITIALIZED (instance)) | |
277 { | |
278 update_one_scrollbar_bs (f, SCROLLBAR_X_WIDGET (instance)); | |
279 SCROLLBAR_X_BACKING_STORE_INITIALIZED (instance) = 1; | |
280 } | |
281 } | |
282 } | |
283 | |
2500 | 284 if (!wv->scrollbar_data) ABORT (); |
436 | 285 free_widget_value_tree (wv); |
428 | 286 } |
287 else if (managed) | |
288 { | |
289 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) | |
290 /* This isn't needed with Athena Scrollbars. It might not be needed */ | |
291 /* with Motif scrollbars (it is apparently needed with Lesstif). */ | |
292 XtUngrabKeyboard (SCROLLBAR_X_WIDGET (instance), CurrentTime); | |
293 #endif | |
294 XtUnmanageChild (SCROLLBAR_X_WIDGET (instance)); | |
295 } | |
296 } | |
297 | |
298 enum x_scrollbar_loop | |
299 { | |
300 X_FIND_SCROLLBAR_WINDOW_MIRROR, | |
301 X_SET_SCROLLBAR_POINTER, | |
302 X_WINDOW_IS_SCROLLBAR, | |
303 X_UPDATE_FRAME_SCROLLBARS | |
304 }; | |
305 | |
306 static struct window_mirror * | |
307 x_scrollbar_loop (enum x_scrollbar_loop type, Lisp_Object window, | |
308 struct window_mirror *mir, | |
309 LWLIB_ID id, Window x_win) | |
310 { | |
311 struct window_mirror *retval = NULL; | |
312 | |
313 while (mir) | |
314 { | |
315 struct scrollbar_instance *vinstance = mir->scrollbar_vertical_instance; | |
316 struct scrollbar_instance *hinstance = mir->scrollbar_horizontal_instance; | |
317 struct window *w = XWINDOW (window); | |
318 | |
319 if (mir->vchild) | |
320 retval = x_scrollbar_loop (type, w->vchild, mir->vchild, id, x_win); | |
321 else if (mir->hchild) | |
322 retval = x_scrollbar_loop (type, w->hchild, mir->hchild, id, x_win); | |
323 if (retval) | |
324 return retval; | |
325 | |
326 if (hinstance || vinstance) | |
327 { | |
328 switch (type) | |
329 { | |
330 case X_FIND_SCROLLBAR_WINDOW_MIRROR: | |
331 if ((vinstance && SCROLLBAR_X_ID (vinstance) == id) || | |
332 (hinstance && SCROLLBAR_X_ID (hinstance) == id)) | |
333 return mir; | |
334 break; | |
335 case X_UPDATE_FRAME_SCROLLBARS: | |
336 if (!mir->vchild && !mir->hchild) | |
337 update_window_scrollbars (w, mir, 1, 0); | |
338 break; | |
339 case X_SET_SCROLLBAR_POINTER: | |
340 if (!mir->vchild && !mir->hchild) | |
341 { | |
342 Widget widget; | |
343 | |
344 widget = SCROLLBAR_X_WIDGET (hinstance); | |
345 if (widget && XtIsManaged (widget)) | |
346 update_one_widget_scrollbar_pointer (w, widget); | |
347 | |
348 widget = SCROLLBAR_X_WIDGET (vinstance); | |
349 if (widget && XtIsManaged (widget)) | |
350 update_one_widget_scrollbar_pointer (w, widget); | |
351 } | |
352 break; | |
353 case X_WINDOW_IS_SCROLLBAR: | |
354 if (!mir->vchild && !mir->hchild) | |
355 { | |
356 Widget widget; | |
357 | |
358 widget = SCROLLBAR_X_WIDGET (hinstance); | |
359 if (widget && XtIsManaged (widget) && | |
360 XtWindow (widget) == x_win) | |
361 return (struct window_mirror *) 1; | |
362 | |
363 widget = SCROLLBAR_X_WIDGET (vinstance); | |
364 if (widget && XtIsManaged (widget) && | |
365 XtWindow (widget) == x_win) | |
366 return (struct window_mirror *) 1; | |
367 } | |
368 break; | |
369 default: | |
2500 | 370 ABORT (); |
428 | 371 } |
372 } | |
373 | |
374 mir = mir->next; | |
375 window = w->next; | |
376 } | |
377 | |
378 return NULL; | |
379 } | |
380 | |
381 /* Used by callbacks. */ | |
382 static struct window_mirror * | |
383 find_scrollbar_window_mirror (struct frame *f, LWLIB_ID id) | |
384 { | |
385 if (f->mirror_dirty) | |
386 update_frame_window_mirror (f); | |
387 return x_scrollbar_loop (X_FIND_SCROLLBAR_WINDOW_MIRROR, f->root_window, | |
617 | 388 XWINDOW_MIRROR (f->root_mirror), id, (Window) NULL); |
428 | 389 } |
390 | |
391 /* | |
392 * This is the only callback provided for vertical scrollbars. It | |
393 * should be able to handle all of the scrollbar events in | |
394 * scroll_action (see lwlib.h). The client data will be of type | |
395 * scroll_event (see lwlib.h). */ | |
396 static void | |
397 x_update_vertical_scrollbar_callback (Widget widget, LWLIB_ID id, | |
398 XtPointer client_data) | |
399 { | |
400 /* This function can GC */ | |
401 scroll_event *data = (scroll_event *) client_data; | |
402 struct device *d = get_device_from_display (XtDisplay (widget)); | |
403 struct frame *f = x_any_window_to_frame (d, XtWindow (widget)); | |
404 Lisp_Object win, frame; | |
405 struct scrollbar_instance *instance; | |
406 struct window_mirror *mirror; | |
407 | |
408 if (!f) | |
409 return; | |
410 | |
411 mirror = find_scrollbar_window_mirror (f, id); | |
442 | 412 if (!mirror) |
413 return; | |
414 | |
428 | 415 win = real_window (mirror, 1); |
416 | |
417 if (NILP (win)) | |
418 return; | |
419 instance = mirror->scrollbar_vertical_instance; | |
420 frame = WINDOW_FRAME (XWINDOW (win)); | |
421 | |
422 /* It seems that this is necessary whenever signal_special_Xt_user_event() | |
423 is called. #### Why??? */ | |
424 DEVICE_X_MOUSE_TIMESTAMP (d) = DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d); | |
425 | |
426 switch (data->action) | |
427 { | |
428 case SCROLLBAR_LINE_UP: | |
429 signal_special_Xt_user_event (frame, Qscrollbar_line_up, win); | |
430 break; | |
431 | |
432 case SCROLLBAR_LINE_DOWN: | |
433 signal_special_Xt_user_event (frame, Qscrollbar_line_down, win); | |
434 break; | |
435 | |
436 /* The Athena scrollbar paging behavior is that of xterms. | |
437 Depending on where you click the size of the page varies. | |
438 Motif always does a standard Emacs page. */ | |
439 case SCROLLBAR_PAGE_UP: | |
440 #if !defined (LWLIB_SCROLLBARS_MOTIF) && !defined (LWLIB_SCROLLBARS_LUCID) && \ | |
441 !defined (LWLIB_SCROLLBARS_ATHENA3D) | |
442 { | |
443 double tmp = ((double) data->slider_value / | |
444 (double) SCROLLBAR_X_POS_DATA(instance).scrollbar_height); | |
445 double line = tmp * | |
446 (double) window_displayed_height (XWINDOW (win)); | |
447 | |
448 if (line > -1.0) | |
449 line = -1.0; | |
450 signal_special_Xt_user_event (frame, Qscrollbar_page_up, | |
451 Fcons (win, make_int ((int) line))); | |
452 } | |
453 #else | |
454 signal_special_Xt_user_event (frame, Qscrollbar_page_up, | |
455 Fcons (win, Qnil)); | |
456 #endif | |
457 break; | |
458 | |
459 case SCROLLBAR_PAGE_DOWN: | |
460 #if !defined (LWLIB_SCROLLBARS_MOTIF) && !defined (LWLIB_SCROLLBARS_LUCID) && \ | |
461 !defined (LWLIB_SCROLLBARS_ATHENA3D) | |
462 { | |
463 double tmp = ((double) data->slider_value / | |
464 (double) SCROLLBAR_X_POS_DATA(instance).scrollbar_height); | |
465 double line = tmp * | |
466 (double) window_displayed_height (XWINDOW (win)); | |
467 | |
468 if (SCROLLBAR_X_POS_DATA(instance).maximum > | |
469 (SCROLLBAR_X_POS_DATA(instance).slider_size + SCROLLBAR_X_POS_DATA(instance).slider_position)) | |
470 { | |
471 if (line < 1.0) | |
472 line = 1.0; | |
473 signal_special_Xt_user_event (frame, Qscrollbar_page_down, | |
474 Fcons (win, | |
475 make_int ((int) line))); | |
476 } | |
477 } | |
478 #else | |
479 signal_special_Xt_user_event (frame, Qscrollbar_page_down, | |
480 Fcons (win, Qnil)); | |
481 #endif | |
482 break; | |
483 | |
484 case SCROLLBAR_TOP: | |
485 signal_special_Xt_user_event (frame, Qscrollbar_to_top, win); | |
486 break; | |
487 | |
488 case SCROLLBAR_BOTTOM: | |
489 signal_special_Xt_user_event (frame, Qscrollbar_to_bottom, win); | |
490 break; | |
491 | |
492 | |
493 case SCROLLBAR_CHANGE: | |
494 inhibit_slider_size_change = 0; | |
495 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) | |
496 vertical_drag_in_progress = 0; | |
497 SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) = data->slider_value; | |
498 SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance) = | |
499 XINT (Fwindow_start (win)); | |
500 #else | |
501 stupid_vertical_scrollbar_drag_hack = 0; | |
502 #endif | |
503 break; | |
504 | |
505 case SCROLLBAR_DRAG: | |
506 { | |
507 int value; | |
508 | |
509 inhibit_slider_size_change = 1; | |
510 | |
511 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) | |
512 /* Doing drags with Motif-like scrollbars is a mess, since we | |
513 want to avoid having the window position jump when you | |
514 first grab the scrollbar, but we also want to ensure that | |
515 you can scroll all the way to the top or bottom of the | |
516 buffer. This can all be replaced with something sane when | |
517 we get line-based scrolling. */ | |
518 | |
519 vertical_drag_in_progress = 1; | |
520 | |
521 if (SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) < 0) | |
522 { | |
523 SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) = data->slider_value; | |
524 SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance) = | |
525 XINT (Fwindow_start (win)); | |
526 } | |
527 | |
528 /* Could replace this piecewise linear scrolling with a | |
529 quadratic through the three points, but I'm not sure that | |
530 would feel any nicer in practice. */ | |
531 if (data->slider_value < SCROLLBAR_X_VDRAG_ORIG_VALUE (instance)) | |
532 { | |
533 /* We've dragged up; slide linearly from original position to | |
534 window-start=data.minimum, slider-value=data.minimum. */ | |
535 | |
536 if (SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) | |
537 <= SCROLLBAR_X_POS_DATA (instance).minimum) | |
538 { | |
539 /* shouldn't get here, but just in case */ | |
540 value = SCROLLBAR_X_POS_DATA (instance).minimum; | |
541 } | |
542 else | |
543 { | |
544 value = (int) | |
545 (SCROLLBAR_X_POS_DATA (instance).minimum | |
546 + (((double) | |
547 (SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance) | |
548 - SCROLLBAR_X_POS_DATA (instance).minimum) | |
549 * (data->slider_value - | |
550 SCROLLBAR_X_POS_DATA (instance).minimum)) | |
551 / (SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) | |
552 - SCROLLBAR_X_POS_DATA (instance).minimum))); | |
553 } | |
554 } | |
555 else | |
556 { | |
557 /* We've dragged down; slide linearly from original position to | |
558 window-start=data.maximum, slider-value=data.maximum. */ | |
559 | |
560 if (SCROLLBAR_X_VDRAG_ORIG_VALUE (instance) | |
561 >= (SCROLLBAR_X_POS_DATA (instance).maximum - | |
562 SCROLLBAR_X_POS_DATA (instance).slider_size)) | |
563 { | |
564 /* avoid divide by zero */ | |
565 value = SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance); | |
566 } | |
567 else | |
568 { | |
569 value = (int) | |
570 (SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance) | |
571 + (((double) | |
572 (SCROLLBAR_X_POS_DATA (instance).maximum | |
573 - SCROLLBAR_X_VDRAG_ORIG_WINDOW_START (instance)) | |
574 * (data->slider_value | |
575 - SCROLLBAR_X_VDRAG_ORIG_VALUE (instance))) | |
576 / (SCROLLBAR_X_POS_DATA (instance).maximum | |
577 - SCROLLBAR_X_POS_DATA (instance).slider_size | |
578 - SCROLLBAR_X_VDRAG_ORIG_VALUE (instance)))); | |
579 } | |
580 } | |
581 #else | |
582 stupid_vertical_scrollbar_drag_hack = 0; | |
583 value = data->slider_value; | |
584 #endif | |
585 | |
586 if (value >= SCROLLBAR_X_POS_DATA (instance).maximum) | |
587 value = SCROLLBAR_X_POS_DATA (instance).maximum - 1; | |
588 if (value < SCROLLBAR_X_POS_DATA (instance).minimum) | |
589 value = SCROLLBAR_X_POS_DATA (instance).minimum; | |
590 | |
591 signal_special_Xt_user_event (frame, Qscrollbar_vertical_drag, | |
592 Fcons (win, make_int (value))); | |
593 } | |
594 break; | |
595 | |
596 } | |
597 } | |
598 | |
599 /* | |
600 * This is the only callback provided for horizontal scrollbars. It | |
601 * should be able to handle all of the scrollbar events in | |
602 * scroll_action (see lwlib.h). The client data will be of type | |
603 * scroll_event (see lwlib.h). */ | |
604 static void | |
605 x_update_horizontal_scrollbar_callback (Widget widget, LWLIB_ID id, | |
606 XtPointer client_data) | |
607 { | |
608 scroll_event *data = (scroll_event *) client_data; | |
609 struct device *d = get_device_from_display (XtDisplay (widget)); | |
610 struct frame *f = x_any_window_to_frame (d, XtWindow (widget)); | |
611 Lisp_Object win, frame; | |
612 struct window_mirror *mirror; | |
613 | |
614 if (!f) | |
615 return; | |
616 | |
617 mirror = find_scrollbar_window_mirror (f, id); | |
442 | 618 if (!mirror) |
619 return; | |
620 | |
428 | 621 win = real_window (mirror, 1); |
622 | |
623 if (NILP (win)) | |
624 return; | |
625 frame = WINDOW_FRAME (XWINDOW (win)); | |
626 | |
627 /* It seems that this is necessary whenever signal_special_Xt_user_event() | |
628 is called. #### Why??? */ | |
629 DEVICE_X_MOUSE_TIMESTAMP (d) = DEVICE_X_GLOBAL_MOUSE_TIMESTAMP (d); | |
630 | |
631 switch (data->action) | |
632 { | |
633 case SCROLLBAR_LINE_UP: | |
634 signal_special_Xt_user_event (frame, Qscrollbar_char_left, win); | |
635 break; | |
636 case SCROLLBAR_LINE_DOWN: | |
637 signal_special_Xt_user_event (frame, Qscrollbar_char_right, win); | |
638 break; | |
639 case SCROLLBAR_PAGE_UP: | |
640 signal_special_Xt_user_event (frame, Qscrollbar_page_left, win); | |
641 break; | |
642 case SCROLLBAR_PAGE_DOWN: | |
643 signal_special_Xt_user_event (frame, Qscrollbar_page_right, win); | |
644 break; | |
645 case SCROLLBAR_TOP: | |
646 signal_special_Xt_user_event (frame, Qscrollbar_to_left, win); | |
647 break; | |
648 case SCROLLBAR_BOTTOM: | |
649 signal_special_Xt_user_event (frame, Qscrollbar_to_right, win); | |
650 break; | |
651 case SCROLLBAR_CHANGE: | |
652 inhibit_slider_size_change = 0; | |
653 break; | |
654 case SCROLLBAR_DRAG: | |
655 inhibit_slider_size_change = 1; | |
656 /* #### Fix the damn toolkit code so they all work the same way. | |
657 Lucid is the one mostly wrong.*/ | |
658 #if defined (LWLIB_SCROLLBARS_LUCID) || defined (LWLIB_SCROLLBARS_ATHENA3D) | |
659 signal_special_Xt_user_event (frame, Qscrollbar_horizontal_drag, | |
660 (Fcons | |
661 (win, make_int (data->slider_value)))); | |
662 #else | |
663 signal_special_Xt_user_event (frame, Qscrollbar_horizontal_drag, | |
664 (Fcons | |
665 (win, | |
666 make_int (data->slider_value - 1)))); | |
667 #endif | |
668 break; | |
669 default: | |
670 break; | |
671 } | |
672 } | |
673 | |
674 static void | |
675 x_scrollbar_pointer_changed_in_window (struct window *w) | |
676 { | |
793 | 677 Lisp_Object window = wrap_window (w); |
428 | 678 |
679 x_scrollbar_loop (X_SET_SCROLLBAR_POINTER, window, find_window_mirror (w), | |
680 0, (Window) NULL); | |
681 } | |
682 | |
683 /* Make sure that all scrollbars on frame are up-to-date. Called | |
684 directly from x_set_frame_properties in frame-x.c*/ | |
685 void | |
686 x_update_frame_scrollbars (struct frame *f) | |
687 { | |
617 | 688 x_scrollbar_loop (X_UPDATE_FRAME_SCROLLBARS, f->root_window, |
689 XWINDOW_MIRROR (f->root_mirror), 0, (Window) NULL); | |
428 | 690 } |
691 | |
692 #ifdef MEMORY_USAGE_STATS | |
693 | |
694 static int | |
2286 | 695 x_compute_scrollbar_instance_usage (struct device *UNUSED (d), |
428 | 696 struct scrollbar_instance *inst, |
697 struct overhead_stats *ovstats) | |
698 { | |
699 int total = 0; | |
700 | |
701 while (inst) | |
702 { | |
703 struct x_scrollbar_data *data = | |
704 (struct x_scrollbar_data *) inst->scrollbar_data; | |
705 | |
2720 | 706 #ifdef MC_ALLOC |
707 total += mc_alloced_storage_size (sizeof (*data), ovstats); | |
708 total += mc_alloced_storage_size (1 + strlen (data->name), ovstats); | |
709 #else /* not MC_ALLOC */ | |
428 | 710 total += malloced_storage_size (data, sizeof (*data), ovstats); |
711 total += malloced_storage_size (data->name, 1 + strlen (data->name), | |
712 ovstats); | |
2720 | 713 #endif /* not MC_ALLOC */ |
428 | 714 inst = inst->next; |
715 } | |
716 | |
717 return total; | |
718 } | |
719 | |
720 #endif /* MEMORY_USAGE_STATS */ | |
721 | |
722 | |
723 /************************************************************************/ | |
724 /* initialization */ | |
725 /************************************************************************/ | |
726 | |
727 void | |
728 console_type_create_scrollbar_x (void) | |
729 { | |
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 */ | |
740 } | |
741 | |
742 void | |
743 reinit_vars_of_scrollbar_x (void) | |
744 { | |
745 stupid_vertical_scrollbar_drag_hack = 1; | |
746 } | |
747 | |
748 void | |
749 vars_of_scrollbar_x (void) | |
750 { | |
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")); | |
757 #endif | |
758 } |