+(defun scroll-bar-columns (side)
+ "Return the width, measured in columns, of the vertical scrollbar on SIDE.
+SIDE must be the symbol `left' or `right'."
+ (let* ((wsb (window-scroll-bars))
+ (vtype (nth 2 wsb))
+ (cols (nth 1 wsb)))
+ (cond
+ ((not (memq side '(left right)))
+ (error "`left' or `right' expected instead of %S" side))
+ ((and (eq vtype side) cols))
+ ((eq (frame-parameter nil 'vertical-scroll-bars) side)
+ ;; nil means it's a non-toolkit scroll bar, and its width in
+ ;; columns is 14 pixels rounded up.
+ (ceiling (or (frame-parameter nil 'scroll-bar-width) 14)
+ (frame-char-width)))
+ (0))))
+
+\f
+;;;; Helpful functions for enabling and disabling scroll bars.
+
+(defvar scroll-bar-mode)
+
+(defvar scroll-bar-mode-explicit nil
+ "Non-nil means `set-scroll-bar-mode' should really do something.
+This is nil while loading `scroll-bar.el', and t afterward.")
+
+(defun set-scroll-bar-mode-1 (ignore value)
+ (set-scroll-bar-mode value))
+
+(defun set-scroll-bar-mode (value)
+ "Set `scroll-bar-mode' to VALUE and put the new value into effect."
+ (setq scroll-bar-mode value)
+
+ (when scroll-bar-mode-explicit
+ ;; Apply it to default-frame-alist.
+ (let ((parameter (assq 'vertical-scroll-bars default-frame-alist)))
+ (if (consp parameter)
+ (setcdr parameter scroll-bar-mode)
+ (setq default-frame-alist
+ (cons (cons 'vertical-scroll-bars scroll-bar-mode)
+ default-frame-alist))))
+
+ ;; Apply it to existing frames.
+ (let ((frames (frame-list)))
+ (while frames
+ (modify-frame-parameters
+ (car frames)
+ (list (cons 'vertical-scroll-bars scroll-bar-mode)))
+ (setq frames (cdr frames))))))
+
+(defcustom scroll-bar-mode default-frame-scroll-bars
+ "*Specify whether to have vertical scroll bars, and on which side.
+Possible values are nil (no scroll bars), `left' (scroll bars on left)
+and `right' (scroll bars on right).
+To set this variable in a Lisp program, use `set-scroll-bar-mode'
+to make it take real effect.
+Setting the variable with a customization buffer also takes effect."
+ :type '(choice (const :tag "none (nil)" nil)
+ (const left)
+ (const right))
+ :group 'frames
+ ;; The default value for :initialize would try to use :set
+ ;; when processing the file in cus-dep.el.
+ :initialize 'custom-initialize-default
+ :set 'set-scroll-bar-mode-1)
+
+;; We just set scroll-bar-mode, but that was the default.
+;; If it is set again, that is for real.
+(setq scroll-bar-mode-explicit t)
+
+(defun scroll-bar-mode (&optional flag)
+ "Toggle display of vertical scroll bars on all frames.
+This command applies to all frames that exist and frames to be
+created in the future.
+With a numeric argument, if the argument is negative,
+turn off scroll bars; otherwise, turn on scroll bars."
+ (interactive "P")
+
+ ;; Tweedle the variable according to the argument.
+ (set-scroll-bar-mode (if (if (null flag)
+ (not scroll-bar-mode)
+ (setq flag (prefix-numeric-value flag))
+ (or (not (numberp flag)) (>= flag 0)))
+ default-frame-scroll-bars)))
+
+(defun toggle-scroll-bar (arg)
+ "Toggle whether or not the selected frame has vertical scroll bars.
+With arg, turn vertical scroll bars on if and only if arg is positive.
+The variable `scroll-bar-mode' controls which side the scroll bars are on
+when they are turned on; if it is nil, they go on the left."
+ (interactive "P")
+ (if (null arg)
+ (setq arg
+ (if (cdr (assq 'vertical-scroll-bars
+ (frame-parameters (selected-frame))))
+ -1 1))
+ (setq arg (prefix-numeric-value arg)))
+ (modify-frame-parameters
+ (selected-frame)
+ (list (cons 'vertical-scroll-bars
+ (if (> arg 0)
+ (or scroll-bar-mode default-frame-scroll-bars))))))
+
+(defun toggle-horizontal-scroll-bar (arg)
+ "Toggle whether or not the selected frame has horizontal scroll bars.
+With arg, turn horizontal scroll bars on if and only if arg is positive.
+Horizontal scroll bars aren't implemented yet."
+ (interactive "P")
+ (error "Horizontal scroll bars aren't implemented yet"))