view lisp/mwheel.el @ 4967:0d4c9d0f6a8d

rewrite dynarr code -------------------- ChangeLog entries follow: -------------------- src/ChangeLog addition: 2010-02-03 Ben Wing <ben@xemacs.org> * device-x.c (x_get_resource_prefix): * device-x.c (Fx_get_resource): * device-x.c (Fx_get_resource_prefix): * device-x.c (Fx_put_resource): * dialog-msw.c: * dialog-msw.c (handle_question_dialog_box): * dired-msw.c (mswindows_sort_files): * dired-msw.c (mswindows_get_files): * extents.c (extent_fragment_sort_by_priority): * extents.c (Fset_extent_parent): * file-coding.c (coding_reader): * file-coding.c (coding_writer): * file-coding.c (gzip_convert): * frame.c (generate_title_string): * gutter.c (calculate_gutter_size_from_display_lines): * indent.c (vmotion_1): * lread.c (read_bit_vector): * mule-coding.c (iso2022_decode): * rangetab.c: * rangetab.c (Fcopy_range_table): * rangetab.c (Fget_range_table): * rangetab.c (unified_range_table_copy_data): * redisplay-msw.c (mswindows_output_string): * redisplay-output.c (output_display_line): * redisplay-output.c (redisplay_move_cursor): * redisplay-output.c (redisplay_clear_bottom_of_window): * redisplay-tty.c (tty_output_ichar_dynarr): * redisplay-tty.c (set_foreground_to): * redisplay-tty.c (set_background_to): * redisplay-xlike-inc.c (XLIKE_output_string): * redisplay.c (redisplay_window_text_width_string): * redisplay.c (redisplay_text_width_string): * redisplay.c (create_text_block): * redisplay.c (SET_CURRENT_MODE_CHARS_PIXSIZE): * redisplay.c (generate_fstring_runes): * redisplay.c (regenerate_modeline): * redisplay.c (ensure_modeline_generated): * redisplay.c (real_current_modeline_height): * redisplay.c (create_string_text_block): * redisplay.c (regenerate_window): * redisplay.c (REGEN_INC_FIND_START_END): * redisplay.c (point_visible): * redisplay.c (redisplay_window): * redisplay.c (mark_glyph_block_dynarr): * redisplay.c (line_start_cache_start): * redisplay.c (start_with_line_at_pixpos): * redisplay.c (update_line_start_cache): * redisplay.c (glyph_to_pixel_translation): * redisplay.c (pixel_to_glyph_translation): * sysdep.c (qxe_readdir): * text.c (dfc_convert_to_external_format): * text.c (dfc_convert_to_internal_format): * toolbar-common.c (common_output_toolbar_button): * window.c (window_modeline_height): * window.c (Fwindow_last_line_visible_height): * window.c (window_displayed_height): * window.c (window_scroll): * window.c (get_current_pixel_pos): Use Dynarr_begin() in place of Dynarr_atp (foo, 0). * dynarr.c (Dynarr_realloc): * dynarr.c (Dynarr_lisp_realloc): * dynarr.c (Dynarr_resize): * dynarr.c (Dynarr_insert_many): * dynarr.c (Dynarr_delete_many): * dynarr.c (Dynarr_memory_usage): * dynarr.c (stack_like_malloc): * dynarr.c (stack_like_free): * lisp.h: * lisp.h (DECLARE_DYNARR_LISP_IMP): * lisp.h (XD_DYNARR_DESC): * lisp.h (Dynarr_pop): * gutter.c (output_gutter): * redisplay-output.c (sync_rune_structs): * redisplay-output.c (redisplay_output_window): Redo the dynarr code, add greater checks. Rename the `len', `largest' and `max' members to `len_', `largest_' and `max_' to try and catch existing places that might directly modify these values. Make new accessors Dynarr_largest() and Dynarr_max() and make them and existing Dynarr_length() be non-lvalues by adding '+ 0' to them; fix a couple of places in the redisplay code that tried to modify the length directly by setting Dynarr_length(). Use the accessors whenever possible even in the dynarr code itself. The accessors also verify that 0 <= len <= largest <= max. Rename settor function Dynarr_set_size() to Dynarr_set_length() and use it more consistently; also create lower-level Dynarr_set_length_1(). This latter function should be the only function that directly modifies the `len_' member of a Dynarr, and in the process makes sure that the `largest' value is kept correct. Consistently use ERROR_CHECK_STRUCTURES instead of ERROR_CHECK_TYPES for error-checking code. Reintroduce the temporarily disabled verification code on the positions of Dynarr_at(), Dynarr_atp() and Dynarr_atp_past_end(). Also create Dynarr_resize_if() in place of a repeated code fragment. Clean up all the functions that modify Dynarrs to use the new macros and functions and verify the correctness of the Dynarr both before and after the change. Note that there are two kinds of verification -- one for accessing and one for modifying. The difference is that the modify verification additionally checks to make sure that the Dynarr isn't locked. (This is used in redisplay to check for problems with reentrancy.) * lrecord.h: Move XD_DYNARR_DESC to lisp.h, grouping with the dynarr code.
author Ben Wing <ben@xemacs.org>
date Wed, 03 Feb 2010 20:51:18 -0600
parents 5d1743698fb3
children 308d34e9f07d
line wrap: on
line source

;;; mwheel.el --- Mouse support for MS intelli-mouse type mice

;; Copyright (C) 1998, Free Software Foundation, Inc.
;; Maintainer: William M. Perry <wmperry@cs.indiana.edu>
;; Keywords: mouse

;; This file is part of XEmacs.

;; XEmacs is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

;; XEmacs is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;; General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with XEmacs; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.

;;; Synched up with: Not synched.

;;; Commentary:

;; This code will enable the use of the infamous 'wheel' on the new
;; crop of mice.  Under XFree86 and the XSuSE X Servers, the wheel
;; events are sent as button4/button5 events.

;; I for one would prefer some way of converting the button4/button5
;; events into different event types, like 'mwheel-up' or
;; 'mwheel-down', but I cannot find a way to do this very easily (or
;; portably), so for now I just live with it.

;; To enable this code, simply put this at the top of your .emacs
;; file:
;;
;; (autoload 'mwheel-install "mwheel" "Enable mouse wheel support.")
;; (mwheel-install)

;;; Code:

(require 'custom)
(require 'cl)

(globally-declare-fboundp
 '(event-basic-type
   posn-window event-start mwheel-event-window mwheel-event-button))

(defcustom mwheel-scroll-amount '(5 1 nil)
  "Amount to scroll windows by when spinning the mouse wheel.
A list with 3 elements specifying the amount to scroll on: a normal wheel
event, a wheel event with the shift key pressed, and a wheel event with the
control key pressed, in that order.

Each item should be the number of lines to scroll, or `nil' for near
full screen.
A near full screen is `next-screen-context-lines' less than a full screen."
  :group 'mouse
  :type '(list
	  (choice :tag "Normal"
		  (const :tag "Full screen" :value nil)
		  (integer :tag "Specific # of lines"))
	  (choice :tag "Shifted"
		  (const :tag "Full screen" :value nil)
		  (integer :tag "Specific # of lines"))
	  (choice :tag "Controlled"
		  (const :tag "Full screen" :value nil)
		  (integer :tag "Specific # of lines"))))

(defcustom mwheel-follow-mouse nil
  "Whether the mouse wheel should scroll the window that the mouse is over.
This can be slightly disconcerting, but some people may prefer it."
  :group 'mouse
  :type 'boolean)

(if (not (fboundp 'event-button))
    (defun mwheel-event-button (event)
      (let ((x (symbol-name (event-basic-type event))))
	(if (not (string-match "^mouse-\\([0-9]+\\)" x))
	    (error "Not a button event: %S" event))
	(string-to-int (substring x (match-beginning 1) (match-end 1)))))
  (fset 'mwheel-event-button 'event-button))

(if (not (fboundp 'event-window))
    (defun mwheel-event-window (event)
      (posn-window (event-start event)))
  (fset 'mwheel-event-window 'event-window))

(defun mwheel-scroll (event)
  (interactive "e")
  (let ((curwin (if mwheel-follow-mouse
		    (prog1
			(selected-window)
		      (select-window (mwheel-event-window event)))))
	(amt (if (memq 'shift (event-modifiers event))
		 (cadr mwheel-scroll-amount)
	       (if (memq 'control (event-modifiers event))
		   (caddr mwheel-scroll-amount)
		 (car mwheel-scroll-amount)))))
    (unwind-protect
	(case (mwheel-event-button event)
	  (4 (scroll-down amt))
	  (5 (scroll-up amt))
	  (otherwise (error "Bad binding in mwheel-scroll")))
      (if curwin (select-window curwin)))
    ))

;;;###autoload
(defun mwheel-install ()
  "Enable mouse wheel support."
  (interactive)
  (let ((keys '([(mouse-4)] [(shift mouse-4)] [(control mouse-4)]
		[(mouse-5)] [(shift mouse-5)] [(control mouse-5)])))

    ;; This condition-case is here because Emacs 19 will throw an error
    ;; if you try to define a key that it does not know about.  I for one
    ;; prefer to just unconditionally do a mwheel-install in my .emacs, so
    ;; that if the wheeled-mouse is there, it just works, and this way it
    ;; doesn't yell at me if I'm on my laptop or another machine, etc.
    (condition-case ()
	(while keys
	  (define-key global-map (car keys) 'mwheel-scroll)
	  (setq keys (cdr keys)))
      (error nil))))

;;;###autoload
(define-behavior 'mwheel
  "This code enables the use of the infamous 'wheel' on the new
crop of mice.  Under XFree86 and the XSuSE X Servers, the wheel
events are sent as button4/button5 events, which are automatically
set up to do scrolling in the expected way.  The actual way that the
scrolling works can be controlled by `mwheel-scroll-amount' and
`mwheel-follow-mouse'."
  :group 'mouse
  :short-doc "Mouse wheel support for X Windows"
  :enable 'mwheel-install)

(provide 'mwheel)

;;; mwheel.el ends here