changeset 107613:886b2b7fcdba

Merge from mainline.
author Eli Zaretskii <eliz@gnu.org>
date Fri, 08 Jan 2010 15:59:09 -0500
parents ac541db0e78b (current diff) 89ca5bbe8e71 (diff)
children 0dc1757dc6b9
files src/dispnew.c
diffstat 41 files changed, 826 insertions(+), 341 deletions(-) [+]
line wrap: on
line diff
--- a/doc/lispref/ChangeLog	Sun Jan 03 13:18:21 2010 -0500
+++ b/doc/lispref/ChangeLog	Fri Jan 08 15:59:09 2010 -0500
@@ -1,3 +1,27 @@
+2010-01-04  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	Avoid dubious uses of save-excursions.
+	* positions.texi (Excursions): Recommend the use of
+	save-current-buffer if applicable.
+	* text.texi (Clickable Text): Fix the example code which used
+	save-excursion in a naive way which sometimes preserves point and
+	sometimes not.
+	* variables.texi (Creating Buffer-Local):
+	* os.texi (Session Management):
+	* display.texi (GIF Images):
+	* control.texi (Cleanups): Use (save|with)-current-buffer.
+
+2010-01-02  Eli Zaretskii  <eliz@gnu.org>
+
+	* modes.texi (Example Major Modes): Fix indentation.  (Bug#5195)
+
+2010-01-02  Chong Yidong  <cyd@stupidchicken.com>
+
+	* nonascii.texi (Text Representations, Character Codes)
+	(Converting Representations, Explicit Encoding)
+	(Translation of Characters): Use hex notation consistently.
+	(Character Sets): Fix map-charset-chars doc (Bug#5197).
+
 2010-01-01  Chong Yidong  <cyd@stupidchicken.com>
 
 	* loading.texi (Where Defined): Make it clearer that these are
@@ -8364,7 +8388,7 @@
 ;; End:
 
     Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-      2007, 2008, 2009  Free Software Foundation, Inc.
+      2007, 2008, 2009, 2010  Free Software Foundation, Inc.
 
   This file is part of GNU Emacs.
 
--- a/doc/lispref/control.texi	Sun Jan 03 13:18:21 2010 -0500
+++ b/doc/lispref/control.texi	Fri Jan 08 15:59:09 2010 -0500
@@ -1255,9 +1255,8 @@
 
 @smallexample
 @group
-(save-excursion
-  (let ((buffer (get-buffer-create " *temp*")))
-    (set-buffer buffer)
+(let ((buffer (get-buffer-create " *temp*")))
+  (with-current-buffer buffer
     (unwind-protect
         @var{body-form}
       (kill-buffer buffer))))
@@ -1269,7 +1268,7 @@
 (current-buffer))} and dispense with the variable @code{buffer}.
 However, the way shown above is safer, if @var{body-form} happens to
 get an error after switching to a different buffer!  (Alternatively,
-you could write another @code{save-excursion} around @var{body-form},
+you could write a @code{save-current-buffer} around @var{body-form},
 to ensure that the temporary buffer becomes current again in time to
 kill it.)
 
--- a/doc/lispref/display.texi	Sun Jan 03 13:18:21 2010 -0500
+++ b/doc/lispref/display.texi	Fri Jan 08 15:59:09 2010 -0500
@@ -4394,8 +4394,7 @@
   (when (= idx max)
     (setq idx 0))
   (let ((img (create-image file nil :image idx)))
-    (save-excursion
-      (set-buffer buffer)
+    (with-current-buffer buffer
       (goto-char (point-min))
       (unless first-time (delete-char 1))
       (insert-image img))
--- a/doc/lispref/modes.texi	Sun Jan 03 13:18:21 2010 -0500
+++ b/doc/lispref/modes.texi	Fri Jan 08 15:59:09 2010 -0500
@@ -1062,8 +1062,8 @@
       ;;   @r{part of symbol names but not words.}
       ;;   @r{(The digit @samp{0} is @code{48} in the @acronym{ASCII} character set.)}
       (while (< i ?0)
-	(modify-syntax-entry i "_   " table)
-	(setq i (1+ i)))
+        (modify-syntax-entry i "_   " table)
+        (setq i (1+ i)))
       ;; @r{@dots{} similar code follows for other character ranges.}
 @end group
 @group
--- a/doc/lispref/nonascii.texi	Sun Jan 03 13:18:21 2010 -0500
+++ b/doc/lispref/nonascii.texi	Fri Jan 08 15:59:09 2010 -0500
@@ -46,12 +46,12 @@
 follows the @dfn{Unicode Standard}.  The Unicode Standard assigns a
 unique number, called a @dfn{codepoint}, to each and every character.
 The range of codepoints defined by Unicode, or the Unicode
-@dfn{codespace}, is @code{0..10FFFF} (in hex), inclusive.  Emacs
-extends this range with codepoints in the range @code{110000..3FFFFF},
-which it uses for representing characters that are not unified with
-Unicode and raw 8-bit bytes that cannot be interpreted as characters
-(the latter occupy the range @code{3FFF80..3FFFFF}).  Thus, a
-character codepoint in Emacs is a 22-bit integer number.
+@dfn{codespace}, is @code{0..#x10FFFF} (in hexadecimal notation),
+inclusive.  Emacs extends this range with codepoints in the range
+@code{#x110000..#x3FFFFF}, which it uses for representing characters
+that are not unified with Unicode and @dfn{raw 8-bit bytes} that
+cannot be interpreted as characters.  Thus, a character codepoint in
+Emacs is a 22-bit integer number.
 
 @cindex internal representation of characters
 @cindex characters, representation in buffers and strings
@@ -189,8 +189,8 @@
 it is returned unchanged.  The function assumes that @var{string}
 includes only @acronym{ASCII} characters and raw 8-bit bytes; the
 latter are converted to their multibyte representation corresponding
-to the codepoints in the @code{3FFF80..3FFFFF} area (@pxref{Text
-Representations, codepoints}).
+to the codepoints @code{#x3FFF80} through @code{#x3FFFFF}, inclusive
+(@pxref{Text Representations, codepoints}).
 @end defun
 
 @defun string-to-unibyte string
@@ -271,15 +271,19 @@
 
   The unibyte and multibyte text representations use different
 character codes.  The valid character codes for unibyte representation
-range from 0 to 255---the values that can fit in one byte.  The valid
-character codes for multibyte representation range from 0 to 4194303
-(#x3FFFFF).  In this code space, values 0 through 127 are for
-@acronym{ASCII} characters, and values 128 through 4194175 (#x3FFF7F)
-are for non-@acronym{ASCII} characters.  Values 0 through 1114111
-(#10FFFF) correspond to Unicode characters of the same codepoint;
-values 1114112 (#110000) through 4194175 (#x3FFF7F) represent
-characters that are not unified with Unicode; and values 4194176
-(#x3FFF80) through 4194303 (#x3FFFFF) represent eight-bit raw bytes.
+range from 0 to @code{#xFF} (255)---the values that can fit in one
+byte.  The valid character codes for multibyte representation range
+from 0 to @code{#x3FFFFF}.  In this code space, values 0 through
+@code{#x7F} (127) are for @acronym{ASCII} characters, and values
+@code{#x80} (128) through @code{#x3FFF7F} (4194175) are for
+non-@acronym{ASCII} characters.
+
+  Emacs character codes are a superset of the Unicode standard.
+Values 0 through @code{#x10FFFF} (1114111) correspond to Unicode
+characters of the same codepoint; values @code{#x110000} (1114112)
+through @code{#x3FFF7F} (4194175) represent characters that are not
+unified with Unicode; and values @code{#x3FFF80} (4194176) through
+@code{#x3FFFFF} (4194303) represent eight-bit raw bytes.
 
 @defun characterp charcode
 This returns @code{t} if @var{charcode} is a valid character, and
@@ -540,7 +544,7 @@
 @cindex @code{eight-bit}, a charset
   Emacs defines several special character sets.  The character set
 @code{unicode} includes all the characters whose Emacs code points are
-in the range @code{0..10FFFF}.  The character set @code{emacs}
+in the range @code{0..#x10FFFF}.  The character set @code{emacs}
 includes all @acronym{ASCII} and non-@acronym{ASCII} characters.
 Finally, the @code{eight-bit} charset includes the 8-bit raw bytes;
 Emacs uses it to represent raw bytes encountered in text.
@@ -628,12 +632,12 @@
   The following function comes in handy for applying a certain
 function to all or part of the characters in a charset:
 
-@defun map-charset-chars function charset &optional arg from to
+@defun map-charset-chars function charset &optional arg from-code to-code
 Call @var{function} for characters in @var{charset}.  @var{function}
 is called with two arguments.  The first one is a cons cell
 @code{(@var{from} .  @var{to})}, where @var{from} and @var{to}
 indicate a range of characters contained in charset.  The second
-argument is the optional argument @var{arg}.
+argument passed to @var{function} is @var{arg}.
 
 By default, the range of codepoints passed to @var{function} includes
 all the characters in @var{charset}, but optional arguments
@@ -751,7 +755,7 @@
 
 @defun make-translation-table-from-vector vec
 This function returns a translation table made from @var{vec} that is
-an array of 256 elements to map byte values 0 through 255 to
+an array of 256 elements to map bytes (values 0 through #xFF) to
 characters.  Elements may be @code{nil} for untranslated bytes.  The
 returned table has a translation table for reverse mapping in the
 first extra slot, and the value @code{1} in the second extra slot.
@@ -1562,10 +1566,10 @@
 text.  They logically consist of a series of byte values; that is, a
 series of @acronym{ASCII} and eight-bit characters.  In unibyte
 buffers and strings, these characters have codes in the range 0
-through 255.  In a multibyte buffer or string, eight-bit characters
-have character codes higher than 255 (@pxref{Text Representations}),
-but Emacs transparently converts them to their single-byte values when
-you encode or decode such text.
+through #xFF (255).  In a multibyte buffer or string, eight-bit
+characters have character codes higher than #xFF (@pxref{Text
+Representations}), but Emacs transparently converts them to their
+single-byte values when you encode or decode such text.
 
   The usual way to read a file into a buffer as a sequence of bytes, so
 you can decode the contents explicitly, is with
--- a/doc/lispref/os.texi	Sun Jan 03 13:18:21 2010 -0500
+++ b/doc/lispref/os.texi	Fri Jan 08 15:59:09 2010 -0500
@@ -2182,7 +2182,7 @@
 
 @group
 (defun save-yourself-test ()
-  (insert "(save-excursion
+  (insert "(save-current-buffer
   (switch-to-buffer \"*scratch*\")
   (insert \"I am restored\"))")
   nil)
--- a/doc/lispref/positions.texi	Sun Jan 03 13:18:21 2010 -0500
+++ b/doc/lispref/positions.texi	Fri Jan 08 15:59:09 2010 -0500
@@ -806,7 +806,9 @@
 
   The forms for saving and restoring the configuration of windows are
 described elsewhere (see @ref{Window Configurations}, and @pxref{Frame
-Configurations}).
+Configurations}).  When only the identity of the current buffer needs
+to be saved and restored, it is preferable to use
+@code{save-current-buffer} instead.
 
 @defspec save-excursion body@dots{}
 @cindex mark excursion
@@ -817,10 +819,10 @@
 point and the mark.  All three saved values are restored even in case of
 an abnormal exit via @code{throw} or error (@pxref{Nonlocal Exits}).
 
-The @code{save-excursion} special form is the standard way to switch
-buffers or move point within one part of a program and avoid affecting
-the rest of the program.  It is used more than 4000 times in the Lisp
-sources of Emacs.
+The @code{save-excursion} special form is the standard way to move
+point within one part of a program and avoid affecting the rest of the
+program.  It is used more than 4000 times in the Lisp sources
+of Emacs.
 
 @code{save-excursion} does not save the values of point and the mark for
 other buffers, so changes in other buffers remain in effect after
--- a/doc/lispref/text.texi	Sun Jan 03 13:18:21 2010 -0500
+++ b/doc/lispref/text.texi	Fri Jan 08 15:59:09 2010 -0500
@@ -3524,13 +3524,12 @@
 (defun dired-mouse-find-file-other-window (event)
   "In Dired, visit the file or directory name you click on."
   (interactive "e")
-  (let (window pos file)
-    (save-excursion
-      (setq window (posn-window (event-end event))
-            pos (posn-point (event-end event)))
-      (if (not (windowp window))
-          (error "No file chosen"))
-      (set-buffer (window-buffer window))
+  (let ((window (posn-window (event-end event)))
+        (pos (posn-point (event-end event)))
+        file)
+    (if (not (windowp window))
+        (error "No file chosen"))
+    (with-current-buffer (window-buffer window)
       (goto-char pos)
       (setq file (dired-get-file-for-visit)))
     (if (file-directory-p file)
--- a/doc/lispref/variables.texi	Sun Jan 03 13:18:21 2010 -0500
+++ b/doc/lispref/variables.texi	Fri Jan 08 15:59:09 2010 -0500
@@ -1240,8 +1240,7 @@
 
 @group
 ;; @r{In buffer @samp{b2}, the value hasn't changed.}
-(save-excursion
-  (set-buffer "b2")
+(with-current-buffer "b2"
   foo)
      @result{} 5
 @end group
--- a/doc/misc/ChangeLog	Sun Jan 03 13:18:21 2010 -0500
+++ b/doc/misc/ChangeLog	Fri Jan 08 15:59:09 2010 -0500
@@ -1,3 +1,13 @@
+2010-01-04  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	* gnus.texi (Posting Styles): Use with-current-buffer.
+	* calc.texi (Defining Simple Commands): Prefer save-current-buffer.
+
+2010-01-02  Kevin Ryde  <user42@zip.com.au>
+
+	* eieio.texi (Naming Conventions): Correction to xref on elisp
+	coding conventions, is "Tips" node not "Standards".
+
 2009-12-24  Chong Yidong  <cyd@stupidchicken.com>
 
 	* calc.texi (General Mode Commands): Calc file should be in .emacs.d.
@@ -6507,7 +6517,7 @@
 ;; End:
 
     Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2002,
-      2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation, Inc.
+      2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010  Free Software Foundation, Inc.
 
   This file is part of GNU Emacs.
 
--- a/doc/misc/calc.texi	Sun Jan 03 13:18:21 2010 -0500
+++ b/doc/misc/calc.texi	Fri Jan 08 15:59:09 2010 -0500
@@ -31968,7 +31968,7 @@
 @smallexample
 (let ((calc-command-flags nil))
   (unwind-protect
-      (save-excursion
+      (save-current-buffer
         (calc-select-buffer)
         @emph{body of function}
         @emph{renumber stack}
--- a/doc/misc/eieio.texi	Sun Jan 03 13:18:21 2010 -0500
+++ b/doc/misc/eieio.texi	Fri Jan 08 15:59:09 2010 -0500
@@ -11,7 +11,7 @@
 @copying
 This manual documents EIEIO, an object framework for Emacs Lisp.
 
-Copyright @copyright{} 2007, 2008, 2009 Free Software Foundation, Inc.
+Copyright @copyright{} 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
 @quotation
 Permission is granted to copy, distribute and/or modify this document
@@ -1776,11 +1776,11 @@
 @comment  node-name,  next,  previous,  up
 @chapter Naming Conventions
 
-@pxref{Standards,,,elisp,GNU Emacs Lisp Reference Manual}, for a
-description of Emacs Lisp programming conventions.  These conventions
-help ensure that Emacs packages work nicely one another, so an
-@eieio{}-based program should follow them.  Here are some conventions
-that apply specifically to @eieio{}-based programs:
+@xref{Tips,,Tips and Conventions,elisp,GNU Emacs Lisp Reference
+Manual}, for a description of Emacs Lisp programming conventions.
+These conventions help ensure that Emacs packages work nicely one
+another, so an @eieio{}-based program should follow them.  Here are
+some conventions that apply specifically to @eieio{}-based programs:
 
 @itemize
 
--- a/doc/misc/gnus.texi	Sun Jan 03 13:18:21 2010 -0500
+++ b/doc/misc/gnus.texi	Fri Jan 08 15:59:09 2010 -0500
@@ -10,7 +10,7 @@
 
 @copying
 Copyright @copyright{} 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
 @quotation
 Permission is granted to copy, distribute and/or modify this document
@@ -13449,8 +13449,7 @@
          (body "You are fired.\n\nSincerely, your boss.")
          (organization "Important Work, Inc"))
         ("nnml:.*"
-         (From (save-excursion
-                 (set-buffer gnus-article-buffer)
+         (From (with-current-buffer gnus-article-buffer
                  (message-fetch-field "to"))))
         ("^nn.+:"
          (signature-file "~/.mail-signature"))))
--- a/lisp/ChangeLog	Sun Jan 03 13:18:21 2010 -0500
+++ b/lisp/ChangeLog	Fri Jan 08 15:59:09 2010 -0500
@@ -1,3 +1,110 @@
+2010-01-08  Kenichi Handa  <handa@m17n.org>
+
+	* international/fontset.el (build-default-fontset-data): Exclude
+	characters in scripts kana, hangul, han, or cjk-misc.
+
+2010-01-07  Juanma Barranquero  <lekktu@gmail.com>
+
+	* vc-dir.el (vc-dir-prepare-status-buffer): Pass a (fake) filename
+	to `create-file-buffer' as it expects, not just a buffer name.
+	(vc-dir-mode): Include the buffer name in `list-buffers-directory',
+	to help uniquify.  (Bug#3224)
+
+2010-01-06  Jan Djärv  <jan.h.d@swipnet.se>
+
+	* font-setting.el (font-setting-change-default-font): Use user-spec
+	instead of name.
+
+2010-01-06  Dan Nicolaescu  <dann@ics.uci.edu>
+
+	* vc-bzr.el (vc-bzr-after-dir-status): Ignore pending merges.
+
+2010-01-05  Tom Tromey  <tromey@redhat.com>
+
+	* progmodes/python.el (python-font-lock-keywords): Handle
+	qualified decorators (Bug#881).
+
+2010-01-05  Dan Nicolaescu  <dann@ics.uci.edu>
+
+	* vc-bzr.el (vc-bzr-working-revision): Fix looking for a revision
+	in a lightweight checkout.
+
+2010-01-05  Kenichi Handa  <handa@m17n.org>
+
+	* language/indian.el (malayalam-composable-pattern): Fix ZWNJ and
+	ZWJ.
+
+2010-01-05  Dan Nicolaescu  <dann@ics.uci.edu>
+
+	* vc-bzr.el (vc-bzr-diff): Obey vc-disable-async-diff.
+
+2010-01-04  Dan Nicolaescu  <dann@ics.uci.edu>
+
+	* vc-bzr.el (vc-bzr-state-heuristic): Make it work for lightweight
+	checkouts.  (Bug#618)
+	(vc-bzr-log-view-mode): Also highlight the author.
+	(vc-bzr-shelve-map): Change binding for vc-bzr-shelve-apply-at-point.
+	(vc-bzr-shelve-menu-map):
+	(vc-bzr-dir-extra-headers): Improve menu and tooltip text.
+	(vc-bzr-shelve-apply): Make prompt more explicit.
+
+2010-01-02  Chong Yidong  <cyd@stupidchicken.com>
+
+	* net/browse-url.el (browse-url-encode-url): Don't escape commas.
+	They are valid characters in URL paths (rfc3986), and at least
+	Firefox does not understand the encoded version (Bug#3166).
+
+2010-01-02  Daniel Elliott  <danelliottster@gmail.com>  (tiny change)
+
+	* progmodes/octave-mod.el (octave-end-keywords)
+	(octave-block-begin-or-end-regexp, octave-block-match-alist): Add
+	"end" keyword (Bug#3061).
+	(octave-end-as-array-index-p): New function.
+	(calculate-octave-indent): Use it.
+
+2010-01-02  Karl Fogel  <kfogel@red-bean.com>
+
+	* bookmark.el: Consistently put the text property on the bookmark name.
+	(bookmark-bmenu-marks-width): Bump back to 2, to include
+	annotation marks.
+	(bookmark-bmenu-hide-filenames): Adjust for above, and put the text
+	property on the bookmark name, instead of not putting it at all.
+	(bookmark-bmenu-list): Fix where we put the text property.
+
+2010-01-02  Karl Fogel  <kfogel@red-bean.com>
+
+	* bookmark.el (bookmark-bmenu-save): Just depend on the new logic
+	for showing buffer modified state (as added in the previous change).
+
+2010-01-02  Karl Fogel  <kfogel@red-bean.com>
+
+	* bookmark.el: Show modified state of bookmark buffer more accurately.
+	(bookmark-bmenu-list): Initialize buffer-modified-p properly.
+	(bookmark-send-edited-annotation): Mark bookmark-alist as modified.
+	(with-buffer-modified-unmodified): New macro.
+	(bookmark-bmenu-show-filenames, bookmark-bmenu-hide-filenames)
+	(bookmark-bmenu-mark, bookmark-bmenu-unmark, bookmark-bmenu-delete):
+	Use new macro to preserve the buffer modified state.
+
+2010-01-02  Karl Fogel  <kfogel@red-bean.com>
+
+	* bookmark.el (bookmark-bmenu-select, bookmark-bmenu-1-window,
+	(bookmark-bmenu-2-window, bookmark-bmenu-this-window)
+	(bookmark-bmenu-other-window, bookmark-bmenu-switch-other-window)
+	(bookmark-bmenu-show-annotation, bookmark-bmenu-edit-annotation)
+	(bookmark-bmenu-rename, bookmark-bmenu-locate)
+	(bookmark-bmenu-relocate, bookmark-bmenu-goto-bookmark): Remove
+	unnecessary calls to `bookmark-bmenu-ensure-position'.
+
+2010-01-02  Eli Zaretskii  <eliz@gnu.org>
+
+	* emacs-lisp/easy-mmode.el (define-globalized-minor-mode): Make
+	the lines in the generated doc string shorter.  (Bug#4668)
+
+2010-01-02  Ryan Yeske  <rcyeske@gmail.com>
+
+	* net/rcirc.el: Add follow-link binding (Bug#4738).
+
 2010-01-02  Eli Zaretskii  <eliz@gnu.org>
 
 	* Makefile.in (bzr-update): Renamed from cvs-update.
--- a/lisp/bookmark.el	Sun Jan 03 13:18:21 2010 -0500
+++ b/lisp/bookmark.el	Fri Jan 08 15:59:09 2010 -0500
@@ -132,8 +132,9 @@
 (defconst bookmark-bmenu-header-height 2
   "Number of lines used for the *Bookmark List* header.")
 
-(defconst bookmark-bmenu-marks-width 1
-  "Number of columns (chars) used for the *Bookmark List* marks column.")
+(defconst bookmark-bmenu-marks-width 2
+  "Number of columns (chars) used for the *Bookmark List* marks column,
+including the annotations column.")
 
 (defcustom bookmark-bmenu-file-column 30
   "Column at which to display filenames in a buffer listing bookmarks.
@@ -289,13 +290,20 @@
 (defvar bookmark-quit-flag nil
   "Non nil make `bookmark-bmenu-search' quit immediately.")
 
-;; Helper functions.
+;; Helper functions and macros.
 
-;; Only functions on this page and the next one (file formats) need to
-;; know anything about the format of bookmark-alist entries.
+(defmacro with-buffer-modified-unmodified (&rest body)
+  "Run BODY while preserving the buffer's `buffer-modified-p' state."
+  (let ((was-modified (make-symbol "was-modified")))
+    `(let ((,was-modified (buffer-modified-p)))
+       (unwind-protect
+           (progn ,@body)
+         (set-buffer-modified-p ,was-modified)))))
+
+;; Only functions below, in this page and the next one (file formats),
+;; need to know anything about the format of bookmark-alist entries.
 ;; Everyone else should go through them.
 
-
 (defun bookmark-name-from-full-record (full-record)
   "Return name of FULL-RECORD (an alist element instead of a string)."
   (car full-record))
@@ -866,6 +874,8 @@
   (let ((annotation (buffer-substring-no-properties (point-min) (point-max)))
 	(bookmark bookmark-annotation-name))
     (bookmark-set-annotation bookmark annotation)
+    (setq bookmark-alist-modification-count
+          (1+ bookmark-alist-modification-count))
     (bookmark-bmenu-surreptitiously-rebuild-list))
   (kill-buffer (current-buffer)))
 
@@ -1547,16 +1557,16 @@
                     " *" "  ")
                 name)
         (setq end (point))
-        (put-text-property start
-                           (+ bookmark-bmenu-marks-width 1 start)
-                           'bookmark-name-prop name)
+        (put-text-property
+         (+ bookmark-bmenu-marks-width start) end 'bookmark-name-prop name)
         (when (display-mouse-p)
           (add-text-properties
-           (+ bookmark-bmenu-marks-width 1 start) end
+           (+ bookmark-bmenu-marks-width start) end
            '(mouse-face highlight
              follow-link t
              help-echo "mouse-2: go to this bookmark in other window")))
         (insert "\n")))
+    (set-buffer-modified-p (not (= bookmark-alist-modification-count 0)))
     (goto-char (point-min))
     (forward-line 2)
     (bookmark-bmenu-mode)
@@ -1635,26 +1645,27 @@
 mainly for debugging, and should not be necessary in normal use."
   (if (and (not force) bookmark-bmenu-toggle-filenames)
       nil ;already shown, so do nothing
-    (save-excursion
-      (save-window-excursion
-        (goto-char (point-min))
-        (forward-line 2)
-        (setq bookmark-bmenu-hidden-bookmarks ())
-        (let ((inhibit-read-only t))
-          (while (< (point) (point-max))
-            (let ((bmrk (bookmark-bmenu-bookmark)))
-              (push bmrk bookmark-bmenu-hidden-bookmarks)
-	      (let ((start (save-excursion (end-of-line) (point))))
-		(move-to-column bookmark-bmenu-file-column t)
-		;; Strip off `mouse-face' from the white spaces region.
-		(if (display-mouse-p)
-		    (remove-text-properties start (point)
-					    '(mouse-face nil help-echo nil))))
-	      (delete-region (point) (progn (end-of-line) (point)))
-              (insert "  ")
-              ;; Pass the NO-HISTORY arg:
-              (bookmark-insert-location bmrk t)
-              (forward-line 1))))))))
+    (with-buffer-modified-unmodified
+     (save-excursion
+       (save-window-excursion
+         (goto-char (point-min))
+         (forward-line 2)
+         (setq bookmark-bmenu-hidden-bookmarks ())
+         (let ((inhibit-read-only t))
+           (while (< (point) (point-max))
+             (let ((bmrk (bookmark-bmenu-bookmark)))
+               (push bmrk bookmark-bmenu-hidden-bookmarks)
+               (let ((start (save-excursion (end-of-line) (point))))
+                 (move-to-column bookmark-bmenu-file-column t)
+                 ;; Strip off `mouse-face' from the white spaces region.
+                 (if (display-mouse-p)
+                     (remove-text-properties start (point)
+                                             '(mouse-face nil help-echo nil))))
+               (delete-region (point) (progn (end-of-line) (point)))
+               (insert "  ")
+               ;; Pass the NO-HISTORY arg:
+               (bookmark-insert-location bmrk t)
+               (forward-line 1)))))))))
 
 
 (defun bookmark-bmenu-hide-filenames (&optional force)
@@ -1663,31 +1674,27 @@
 mainly for debugging, and should not be necessary in normal use."
   (when (and (not force) bookmark-bmenu-toggle-filenames)
     ;; nothing to hide if above is nil
-    (save-excursion
-      (goto-char (point-min))
-      (forward-line 2)
-      (setq bookmark-bmenu-hidden-bookmarks
-            (nreverse bookmark-bmenu-hidden-bookmarks))
-      (let ((inhibit-read-only t)
-            (column (save-excursion
-                      (goto-char (point-min))
-                      (search-forward "Bookmark")
-                      (backward-word 1)
-                      (current-column))))
-        (while bookmark-bmenu-hidden-bookmarks
-          (move-to-column column t)
-          (bookmark-kill-line)
-          (let ((name  (pop bookmark-bmenu-hidden-bookmarks))
-                (start (point)))
-            (insert name)
-            (if (display-mouse-p)
-                (add-text-properties
-                 start (point)
-                 '(mouse-face highlight
-                   follow-link t
-                   help-echo
-                   "mouse-2: go to this bookmark in other window"))))
-          (forward-line 1))))))
+    (with-buffer-modified-unmodified
+     (save-excursion
+       (goto-char (point-min))
+       (forward-line 2)
+       (setq bookmark-bmenu-hidden-bookmarks
+             (nreverse bookmark-bmenu-hidden-bookmarks))
+       (let ((inhibit-read-only t))
+         (while bookmark-bmenu-hidden-bookmarks
+           (move-to-column bookmark-bmenu-marks-width t)
+           (bookmark-kill-line)
+           (let ((name  (pop bookmark-bmenu-hidden-bookmarks))
+                 (start (point)))
+             (insert name)
+             (put-text-property start (point) 'bookmark-name-prop name)
+             (if (display-mouse-p)
+                 (add-text-properties
+                  start (point)
+                  '(mouse-face
+                    highlight follow-link t help-echo
+                    "mouse-2: go to this bookmark in other window"))))
+           (forward-line 1)))))))
 
 
 (defun bookmark-bmenu-ensure-position ()
@@ -1752,18 +1759,18 @@
   (interactive)
   (beginning-of-line)
   (bookmark-bmenu-ensure-position)
-  (let ((inhibit-read-only t))
-    (delete-char 1)
-    (insert ?>)
-    (forward-line 1)
-    (bookmark-bmenu-ensure-position)))
+  (with-buffer-modified-unmodified
+   (let ((inhibit-read-only t))
+     (delete-char 1)
+     (insert ?>)
+     (forward-line 1)
+     (bookmark-bmenu-ensure-position))))
 
 
 (defun bookmark-bmenu-select ()
   "Select this line's bookmark; also display bookmarks marked with `>'.
 You can mark bookmarks with the \\<bookmark-bmenu-mode-map>\\[bookmark-bmenu-mark] command."
   (interactive)
-  (bookmark-bmenu-ensure-position)
   (let ((bmrk (bookmark-bmenu-bookmark))
         (menu (current-buffer))
         (others ())
@@ -1811,20 +1818,8 @@
   (interactive "P")
   (save-excursion
     (save-window-excursion
-      (bookmark-save parg)))
-  ;; Show the buffer as unmodified after saving, but only if there are
-  ;; no marks: marks are not saved with the bookmarks, therefore from
-  ;; the user's point of view they are a "modification" in the buffer
-  ;;
-  ;; FIXME: Ideally, if the buffer were unmodified when there are no
-  ;; marks, and then some marks are made and removed without being
-  ;; executed, then the buffer would be restored to unmodified state.
-  ;; But that would require bookmark-specific logic to track buffer
-  ;; modification.  It might be worth it, but it's fine not to have it
-  ;; too -- the worst outcome is that the user might be tempted to
-  ;; save the bookmark list when it technically doesn't need saving.
-  (if (not (bookmark-bmenu-any-marks))
-      (set-buffer-modified-p nil)))
+      (bookmark-save parg)
+      (set-buffer-modified-p nil))))
 
 
 (defun bookmark-bmenu-load ()
@@ -1840,7 +1835,6 @@
 (defun bookmark-bmenu-1-window ()
   "Select this line's bookmark, alone, in full frame."
   (interactive)
-  (bookmark-bmenu-ensure-position)
   (bookmark-jump (bookmark-bmenu-bookmark))
   (bury-buffer (other-buffer))
   (delete-other-windows))
@@ -1849,7 +1843,6 @@
 (defun bookmark-bmenu-2-window ()
   "Select this line's bookmark, with previous buffer in second window."
   (interactive)
-  (bookmark-bmenu-ensure-position)
   (let ((bmrk (bookmark-bmenu-bookmark))
         (menu (current-buffer))
         (pop-up-windows t))
@@ -1863,7 +1856,6 @@
 (defun bookmark-bmenu-this-window ()
   "Select this line's bookmark in this window."
   (interactive)
-  (bookmark-bmenu-ensure-position)
   (bookmark-jump (bookmark-bmenu-bookmark)))
 
 
@@ -1871,7 +1863,6 @@
   "Select this line's bookmark in other window, leaving bookmark menu visible."
   (interactive)
   (let ((bookmark (bookmark-bmenu-bookmark)))
-    (bookmark-bmenu-ensure-position)
     (let ((bookmark-automatically-show-annotations t)) ;FIXME: needed?
       (bookmark--jump-via bookmark 'switch-to-buffer-other-window))))
 
@@ -1884,7 +1875,6 @@
         (pop-up-windows t)
         same-window-buffer-names
         same-window-regexps)
-    (bookmark-bmenu-ensure-position)
     (let ((bookmark-automatically-show-annotations t)) ;FIXME: needed?
       (bookmark--jump-via bookmark 'display-buffer))))
 
@@ -1901,7 +1891,6 @@
   "Show the annotation for the current bookmark in another window."
   (interactive)
   (let ((bookmark (bookmark-bmenu-bookmark)))
-    (bookmark-bmenu-ensure-position)
     (bookmark-show-annotation bookmark)))
 
 
@@ -1915,7 +1904,6 @@
   "Edit the annotation for the current bookmark in another window."
   (interactive)
   (let ((bookmark (bookmark-bmenu-bookmark)))
-    (bookmark-bmenu-ensure-position)
     (bookmark-edit-annotation bookmark)))
 
 
@@ -1925,14 +1913,15 @@
   (interactive "P")
   (beginning-of-line)
   (bookmark-bmenu-ensure-position)
-  (let ((inhibit-read-only t))
-    (delete-char 1)
-    ;; any flags to reset according to circumstances?  How about a
-    ;; flag indicating whether this bookmark is being visited?
-    ;; well, we don't have this now, so maybe later.
-    (insert " "))
-  (forward-line (if backup -1 1))
-  (bookmark-bmenu-ensure-position))
+  (with-buffer-modified-unmodified
+   (let ((inhibit-read-only t))
+     (delete-char 1)
+     ;; any flags to reset according to circumstances?  How about a
+     ;; flag indicating whether this bookmark is being visited?
+     ;; well, we don't have this now, so maybe later.
+     (insert " "))
+   (forward-line (if backup -1 1))
+   (bookmark-bmenu-ensure-position)))
 
 
 (defun bookmark-bmenu-backup-unmark ()
@@ -1951,11 +1940,12 @@
   (interactive)
   (beginning-of-line)
   (bookmark-bmenu-ensure-position)
-  (let ((inhibit-read-only t))
-    (delete-char 1)
-    (insert ?D)
-    (forward-line 1)
-    (bookmark-bmenu-ensure-position)))
+  (with-buffer-modified-unmodified
+   (let ((inhibit-read-only t))
+     (delete-char 1)
+     (insert ?D)
+     (forward-line 1)
+     (bookmark-bmenu-ensure-position))))
 
 
 (defun bookmark-bmenu-delete-backwards ()
@@ -2001,7 +1991,6 @@
 (defun bookmark-bmenu-rename ()
   "Rename bookmark on current line.  Prompts for a new name."
   (interactive)
-  (bookmark-bmenu-ensure-position)
   (let ((bmrk (bookmark-bmenu-bookmark))
         (thispoint (point)))
     (bookmark-rename bmrk)
@@ -2011,15 +2000,13 @@
 (defun bookmark-bmenu-locate ()
   "Display location of this bookmark.  Displays in the minibuffer."
   (interactive)
- (bookmark-bmenu-ensure-position)
- (let ((bmrk (bookmark-bmenu-bookmark)))
-   (message "%s" (bookmark-location bmrk))))
+  (let ((bmrk (bookmark-bmenu-bookmark)))
+    (message "%s" (bookmark-location bmrk))))
 
 (defun bookmark-bmenu-relocate ()
   "Change the file path of the bookmark on the current line,
   prompting with completion for the new path."
   (interactive)
-  (bookmark-bmenu-ensure-position)
   (let ((bmrk (bookmark-bmenu-bookmark))
         (thispoint (point)))
     (bookmark-relocate bmrk)
@@ -2084,7 +2071,6 @@
 (defun bookmark-bmenu-goto-bookmark (name)
   "Move point to bookmark with name NAME."
   (goto-char (point-min))
-  (bookmark-bmenu-ensure-position)
   (while (not (equal name (bookmark-bmenu-bookmark)))
     (forward-line 1))
   (forward-line 0))
--- a/lisp/emacs-lisp/easy-mmode.el	Sun Jan 03 13:18:21 2010 -0500
+++ b/lisp/emacs-lisp/easy-mmode.el	Fri Jan 08 15:59:09 2010 -0500
@@ -326,9 +326,13 @@
        (make-variable-buffer-local ',MODE-major-mode)
        ;; The actual global minor-mode
        (define-minor-mode ,global-mode
+	 ;; Very short lines to avoid too long lines in the generated
+	 ;; doc string.
 	 ,(format "Toggle %s in every possible buffer.
-With prefix ARG, turn %s on if and only if ARG is positive.
-%s is enabled in all buffers where `%s' would do it.
+With prefix ARG, turn %s on if and only if
+ARG is positive.
+%s is enabled in all buffers where
+\`%s' would do it.
 See `%s' for more information on %s."
 		  pretty-name pretty-global-name pretty-name turn-on
 		  mode pretty-name)
--- a/lisp/font-setting.el	Sun Jan 03 13:18:21 2010 -0500
+++ b/lisp/font-setting.el	Fri Jan 08 15:59:09 2010 -0500
@@ -57,7 +57,7 @@
 	(if (display-graphic-p f)
 	    (let* ((frame-font
 		    (or (font-get (face-attribute 'default :font f
-						  'default) :name)
+						  'default) :user-spec)
 			(frame-parameter f 'font-parameter)))
 		   (font-to-set
 		    (if set-font new-font
--- a/lisp/gnus/ChangeLog	Sun Jan 03 13:18:21 2010 -0500
+++ b/lisp/gnus/ChangeLog	Fri Jan 08 15:59:09 2010 -0500
@@ -1,3 +1,28 @@
+2010-01-06  Katsumi Yamaoka  <yamaoka@jpl.org>
+
+	* gnus-art.el (gnus-article-describe-bindings): Work for prefix keys.
+
+	* message.el (message-check-news-header-syntax): Protect against a
+	string that `rfc822-addresses' returns when parsing fails.
+
+2010-01-06  Katsumi Yamaoka  <yamaoka@jpl.org>
+
+	* gnus-util.el (gnus-invisible-p, gnus-next-char-property-change)
+	(gnus-previous-char-property-change): New functions.
+
+	* gnus-sum.el (gnus-forward-line-ignore-invisible): Use them.
+
+2010-01-05  Andreas Schwab  <schwab@linux-m68k.org>
+
+	* gnus-sum.el (gnus-forward-line-ignore-invisible): New function.
+	(gnus-summary-recenter): Use it instead of forward-line.  (Bug#5257)
+
+2010-01-02  Chong Yidong  <cyd@stupidchicken.com>
+
+	* message.el (message-exchange-point-and-mark): Rework last change to
+	avoid using optional arg of exchange-point-and-mark, for backward
+	compatibility.
+
 2010-01-01  Chong Yidong  <cyd@stupidchicken.com>
 
 	* message.el (message-exchange-point-and-mark): Call
@@ -13782,7 +13807,7 @@
 
 See ChangeLog.2 for earlier changes.
 
-    Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+    Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
   This file is part of GNU Emacs.
 
--- a/lisp/gnus/gnus-art.el	Sun Jan 03 13:18:21 2010 -0500
+++ b/lisp/gnus/gnus-art.el	Fri Jan 08 15:59:09 2010 -0500
@@ -6477,10 +6477,17 @@
   (let ((keymap (copy-keymap gnus-article-mode-map))
 	(map (copy-keymap gnus-article-send-map))
 	(sumkeys (where-is-internal 'gnus-article-read-summary-keys))
-	agent draft)
+	parent agent draft)
     (define-key keymap "S" map)
     (define-key map [t] nil)
     (with-current-buffer gnus-article-current-summary
+      (set-keymap-parent
+       keymap
+       (if (setq parent (keymap-parent gnus-article-mode-map))
+	   (prog1
+	       (setq parent (copy-keymap parent))
+	     (set-keymap-parent parent (current-local-map)))
+	 (current-local-map)))
       (set-keymap-parent map (key-binding "S"))
       (let (key def gnus-pick-mode)
 	(while sumkeys
--- a/lisp/gnus/gnus-sum.el	Sun Jan 03 13:18:21 2010 -0500
+++ b/lisp/gnus/gnus-sum.el	Fri Jan 08 15:59:09 2010 -0500
@@ -6727,6 +6727,26 @@
 
 (put 'gnus-recenter 'isearch-scroll t)
 
+(defun gnus-forward-line-ignore-invisible (n)
+  "Move N lines forward (backward if N is negative).
+Like forward-line, but skip over (and don't count) invisible lines."
+  (let (done)
+    (while (and (> n 0) (not done))
+      ;; If the following character is currently invisible,
+      ;; skip all characters with that same `invisible' property value.
+      (while (gnus-invisible-p (point))
+	(goto-char (gnus-next-char-property-change (point))))
+      (forward-line 1)
+      (if (eobp)
+	  (setq done t)
+	(setq n (1- n))))
+    (while (and (< n 0) (not done))
+      (forward-line -1)
+      (if (bobp) (setq done t)
+	(setq n (1+ n))
+	(while (and (not (bobp)) (gnus-invisible-p (1- (point))))
+	  (goto-char (gnus-previous-char-property-change (point))))))))
+
 (defun gnus-summary-recenter ()
   "Center point in the summary window.
 If `gnus-auto-center-summary' is nil, or the article buffer isn't
@@ -6742,16 +6762,19 @@
 			     gnus-auto-center-summary
                            (/ (1- (window-height)) 2)))))
 	   (height (1- (window-height)))
-	   (bottom (save-excursion (goto-char (point-max))
-				   (forward-line (- height))
-				   (point)))
+	   (bottom (save-excursion
+		     (goto-char (point-max))
+		     (gnus-forward-line-ignore-invisible (- height))
+		     (point)))
 	   (window (get-buffer-window (current-buffer))))
       (when (get-buffer-window gnus-article-buffer)
 	;; Only do recentering when the article buffer is displayed,
 	;; Set the window start to either `bottom', which is the biggest
 	;; possible valid number, or the second line from the top,
 	;; whichever is the least.
-	(let ((top-pos (save-excursion (forward-line (- top)) (point))))
+	(let ((top-pos (save-excursion
+			 (gnus-forward-line-ignore-invisible (- top))
+			 (point))))
 	  (if (> bottom top-pos)
 	      ;; Keep the second line from the top visible
 	      (set-window-start window top-pos)
@@ -6760,12 +6783,12 @@
 	    ;; visible, or revert to using TOP-POS.
 	    (save-excursion
 	      (goto-char (point-max))
-	      (forward-line -1)
+	      (gnus-forward-line-ignore-invisible -1)
 	      (let ((last-line-start (point)))
 		(goto-char bottom)
 		(set-window-start window (point) t)
 		(when (not (pos-visible-in-window-p last-line-start window))
-		  (forward-line 1)
+		  (gnus-forward-line-ignore-invisible 1)
 		  (set-window-start window (min (point) top-pos) t)))))))
       ;; Do horizontal recentering while we're at it.
       (when (and (get-buffer-window (current-buffer) t)
--- a/lisp/gnus/gnus-util.el	Sun Jan 03 13:18:21 2010 -0500
+++ b/lisp/gnus/gnus-util.el	Fri Jan 08 15:59:09 2010 -0500
@@ -969,6 +969,29 @@
 			  (overlay-get overlay 'face))
 			(overlays-at pos)))))))
 
+(if (fboundp 'invisible-p)
+    (defalias 'gnus-invisible-p 'invisible-p)
+  ;; for Emacs < 22.2, and XEmacs.
+  (defun gnus-invisible-p (pos)
+    "Return non-nil if the character after POS is currently invisible."
+    (let ((prop (get-char-property pos 'invisible)))
+      (if (eq buffer-invisibility-spec t)
+	  prop
+	(or (memq prop buffer-invisibility-spec)
+	    (assq prop buffer-invisibility-spec))))))
+
+;; Note: the optional 2nd argument has a different meaning between
+;; Emacs and XEmacs.
+;; (next-char-property-change POSITION &optional LIMIT)
+;; (next-extent-change        POS      &optional OBJECT)
+(defalias 'gnus-next-char-property-change
+  (if (fboundp 'next-extent-change)
+      'next-extent-change 'next-char-property-change))
+
+(defalias 'gnus-previous-char-property-change
+  (if (fboundp 'previous-extent-change)
+      'previous-extent-change 'previous-char-property-change))
+
 ;;; Protected and atomic operations.  dmoore@ucsd.edu 21.11.1996
 ;; The primary idea here is to try to protect internal datastructures
 ;; from becoming corrupted when the user hits C-g, or if a hook or
--- a/lisp/gnus/message.el	Sun Jan 03 13:18:21 2010 -0500
+++ b/lisp/gnus/message.el	Fri Jan 08 15:59:09 2010 -0500
@@ -5077,7 +5077,8 @@
 	  "Denied posting -- the From looks strange: \"%s\"." from)
 	 nil)
 	((let ((addresses (rfc822-addresses from)))
-	   (while (and addresses
+	   ;; `rfc822-addresses' returns a string if parsing fails.
+	   (while (and (consp addresses)
 		       (not (eq (string-to-char (car addresses)) ?\()))
 	     (setq addresses (cdr addresses)))
 	   addresses)
@@ -7505,7 +7506,8 @@
 
 (defun message-exchange-point-and-mark ()
   "Exchange point and mark, but don't activate region if it was inactive."
-  (exchange-point-and-mark transient-mark-mode))
+  (goto-char (prog1 (mark t)
+	       (set-marker (mark-marker) (point)))))
 
 (defalias 'message-make-overlay 'make-overlay)
 (defalias 'message-delete-overlay 'delete-overlay)
--- a/lisp/international/fontset.el	Sun Jan 03 13:18:21 2010 -0500
+++ b/lisp/international/fontset.el	Fri Jan 08 15:59:09 2010 -0500
@@ -361,8 +361,10 @@
 	     (let ((from (car range)) (to (cdr range)))
 	       (if (< to #x110000)
 		   (while (<= from to)
-		     (aset cjk-table from
-			   (logior (or (aref cjk-table from) 0) mask))
+		     (or (memq (aref char-script-table from)
+			       '(kana hangul han cjk-misc))
+			 (aset cjk-table from
+			       (logior (or (aref cjk-table from) 0) mask)))
 		     (setq from (1+ from))))))
 	 (nth 1 elt) nil (nth 2 elt) (nth 3 elt)))
       (setq i (1+ i)))
--- a/lisp/language/indian.el	Sun Jan 03 13:18:21 2010 -0500
+++ b/lisp/language/indian.el	Fri Jan 08 15:59:09 2010 -0500
@@ -153,8 +153,8 @@
 	   ("a" . "\u0903")			 ; vowel modifier (post) 
 	   ("S" . "\u0951")			 ; stress sign (above)
 	   ("s" . "\u0952")			 ; stress sign (below)
+	   ("N" . "\u200C")			 ; ZWNJ
 	   ("J" . "\u200D")			 ; ZWJ
-	   ("N" . "\u200C")			 ; ZWNJ
 	   ("X" . "[\u0900-\u097F]"))))		 ; all coverage
     (indian-compose-regexp
      (concat
@@ -195,8 +195,8 @@
 	   ("b" . "[\u0D62-\u0D63]")		  ; belowbase matra
 	   ("a" . "[\u0D02-\u0D03]")		  ; abovebase sign
 	   ("H" . "\u0D4D")			  ; virama sign 
-	   ("N" . "\u200D")			  ; ZWJ
-	   ("J" . "\u200C")			  ; ZWNJ
+	   ("N" . "\u200C")			  ; ZWNJ
+	   ("J" . "\u200D")			  ; ZWJ
 	   ("X" . "[\u0D00-\u0D7F]"))))		  ; all coverage
     (indian-compose-regexp
      (concat
--- a/lisp/net/browse-url.el	Sun Jan 03 13:18:21 2010 -0500
+++ b/lisp/net/browse-url.el	Fri Jan 08 15:59:09 2010 -0500
@@ -613,7 +613,7 @@
 
 (defun browse-url-url-encode-chars (text chars)
   "URL-encode the chars in TEXT that match CHARS.
-CHARS is a regexp-like character alternative (e.g., \"[,)$]\")."
+CHARS is a regexp-like character alternative (e.g., \"[)$]\")."
   (let ((encoded-text (copy-sequence text))
 	(s 0))
     (while (setq s (string-match chars encoded-text s))
@@ -626,10 +626,12 @@
 
 (defun browse-url-encode-url (url)
   "Escape annoying characters in URL.
-The annoying characters are those that can mislead a webbrowser
-regarding its parameter treatment.  For instance, `,' can
-be misleading because it could be used to separate URLs."
-  (browse-url-url-encode-chars url "[,)$]"))
+The annoying characters are those that can mislead a web browser
+regarding its parameter treatment."
+  ;; FIXME: Is there an actual example of a web browser getting
+  ;; confused?  (This used to encode commas, but at least Firefox
+  ;; handles commas correctly and doesn't accept encoded commas.)
+  (browse-url-url-encode-chars url "[)$]"))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; URL input
--- a/lisp/net/rcirc.el	Sun Jan 03 13:18:21 2010 -0500
+++ b/lisp/net/rcirc.el	Fri Jan 08 15:59:09 2010 -0500
@@ -836,6 +836,7 @@
 
 (define-key rcirc-browse-url-map (kbd "RET") 'rcirc-browse-url-at-point)
 (define-key rcirc-browse-url-map (kbd "<mouse-2>") 'rcirc-browse-url-at-mouse)
+(define-key rcirc-browse-url-map [follow-link] 'mouse-face)
 
 (defvar rcirc-short-buffer-name nil
   "Generated abbreviation to use to indicate buffer activity.")
--- a/lisp/progmodes/octave-mod.el	Sun Jan 03 13:18:21 2010 -0500
+++ b/lisp/progmodes/octave-mod.el	Fri Jan 08 15:59:09 2010 -0500
@@ -101,11 +101,9 @@
   '("do" "for" "function" "if" "switch" "try" "unwind_protect" "while"))
 (defvar octave-else-keywords
   '("case" "catch" "else" "elseif" "otherwise" "unwind_protect_cleanup"))
-;; FIXME: only use specific "end" tokens here to avoid confusion when "end"
-;; is used in indexing (the real fix is much more complex).
 (defvar octave-end-keywords
   '("endfor" "endfunction" "endif" "endswitch" "end_try_catch"
-    "end_unwind_protect" "endwhile" "until"))
+    "end_unwind_protect" "endwhile" "until" "end"))
 
 (defvar octave-reserved-words
   (append octave-begin-keywords
@@ -342,17 +340,15 @@
   (concat octave-block-begin-regexp "\\|" octave-block-end-regexp))
 (defvar octave-block-else-or-end-regexp
   (concat octave-block-else-regexp "\\|" octave-block-end-regexp))
-;; FIXME: only use specific "end" tokens here to avoid confusion when "end"
-;; is used in indexing (the real fix is much more complex).
 (defvar octave-block-match-alist
   '(("do" . ("until"))
-    ("for" . ("endfor"))
+    ("for" . ("endfor" "end"))
     ("function" . ("endfunction"))
-    ("if" . ("else" "elseif" "endif"))
-    ("switch" . ("case" "otherwise" "endswitch"))
+    ("if" . ("else" "elseif" "endif" "end"))
+    ("switch" . ("case" "otherwise" "endswitch" "end"))
     ("try" . ("catch" "end_try_catch"))
     ("unwind_protect" . ("unwind_protect_cleanup" "end_unwind_protect"))
-    ("while" . ("endwhile")))
+    ("while" . ("endwhile" "end")))
   "Alist with Octave's matching block keywords.
 Has Octave's begin keywords as keys and a list of the matching else or
 end keywords as associated values.")
@@ -680,7 +676,10 @@
 			(if (= bot (point))
 			    (setq icol (+ icol octave-block-offset))))
 		       ((octave-looking-at-kw octave-block-end-regexp)
-			(if (not (= bot (point)))
+			(if (and (not (= bot (point)))
+				 ;; special case for `end' keyword,
+				 ;; applied to all keywords
+				 (not (octave-end-as-array-index-p)))
 			    (setq icol (- icol
 					  (octave-block-end-offset)))))))
 		  (forward-char)))
@@ -702,6 +701,15 @@
 	(setq icol (list comment-column icol)))))
     icol))
 
+;; FIXME: this should probably also make sure we are actually looking
+;; at the "end" keyword.
+(defun octave-end-as-array-index-p ()
+  (save-excursion
+    (condition-case nil
+	;; Check if point is between parens
+	(progn (up-list 1) t)
+      (error nil))))
+
 (defun octave-block-end-offset ()
   (save-excursion
     (octave-backward-up-block 1)
--- a/lisp/progmodes/python.el	Sun Jan 03 13:18:21 2010 -0500
+++ b/lisp/progmodes/python.el	Fri Jan 08 15:59:09 2010 -0500
@@ -1,6 +1,6 @@
 ;;; python.el --- silly walks for Python  -*- coding: iso-8859-1 -*-
 
-;; Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
+;; Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
 ;;   Free Software Foundation, Inc.
 
 ;; Author: Dave Love <fx@gnu.org>
@@ -112,7 +112,9 @@
     ;; Top-level assignments are worth highlighting.
     (,(rx line-start (group (1+ (or word ?_))) (0+ space) "=")
      (1 font-lock-variable-name-face))
-    (,(rx line-start (* (any " \t")) (group "@" (1+ (or word ?_)))) ; decorators
+    ;; Decorators.
+    (,(rx line-start (* (any " \t")) (group "@" (1+ (or word ?_))
+					    (0+ "." (1+ (or word ?_)))))
      (1 font-lock-type-face))
     ;; Built-ins.  (The next three blocks are from
     ;; `__builtin__.__dict__.keys()' in Python 2.5.1.)  These patterns
--- a/lisp/vc-bzr.el	Sun Jan 03 13:18:21 2010 -0500
+++ b/lisp/vc-bzr.el	Fri Jan 08 15:59:09 2010 -0500
@@ -176,13 +176,13 @@
                                "\0"
                                "[^\0]*\0"     ;id?
                                "\\([^\0]*\\)\0" ;"a/f/d", a=removed?
-                               "[^\0]*\0" ;sha1 (empty if conflicted)?
-                               "\\([^\0]*\\)\0" ;size?
+                               "\\([^\0]*\\)\0" ;sha1 (empty if conflicted)?
+                               "\\([^\0]*\\)\0" ;size?p
                                "[^\0]*\0"       ;"y/n", executable?
                                "[^\0]*\0"       ;?
                                "\\([^\0]*\\)\0" ;"a/f/d" a=added?
                                "\\([^\0]*\\)\0" ;sha1 again?
-                               "[^\0]*\0"       ;size again?
+                               "\\([^\0]*\\)\0" ;size again?
                                "[^\0]*\0" ;"y/n", executable again?
                                "[^\0]*\0" ;last revid?
                                ;; There are more fields when merges are pending.
@@ -194,11 +194,20 @@
                       ;; conflict markers).
                       (cond
                        ((eq (char-after (match-beginning 1)) ?a) 'removed)
-                       ((eq (char-after (match-beginning 3)) ?a) 'added)
-                       ((and (eq (string-to-number (match-string 2))
+                       ((eq (char-after (match-beginning 4)) ?a) 'added)
+                       ((or (and (eq (string-to-number (match-string 3))
                                  (nth 7 (file-attributes file)))
-                             (equal (match-string 4)
+                             (equal (match-string 5)
                                     (vc-bzr-sha1 file)))
+			    (and
+			     ;; It looks like for lightweight
+			     ;; checkouts \2 is empty and we need to
+			     ;; look for size in \6.
+			     (eq (match-beginning 2) (match-end 2))
+			     (eq (string-to-number (match-string 6))
+				 (nth 7 (file-attributes file)))
+			     (equal (match-string 5)
+				    (vc-bzr-sha1 file))))
                         'up-to-date)
                        (t 'edited))
                     'unregistered))))
@@ -347,9 +356,19 @@
 	       (if (file-exists-p location-fname)
 		   (with-temp-buffer
 		     (insert-file-contents location-fname)
-		     (when (re-search-forward "file://\(.+\)" nil t)
-		       (setq branch-format-file (match-string 1))
-		       (file-exists-p branch-format-file)))
+		     ;; If the lightweight checkout points to a
+		     ;; location in the local file system, then we can
+		     ;; look there for the version information.
+		     (when (re-search-forward "file://\\(.+\\)" nil t)
+		       (let ((l-c-parent-dir (match-string 1)))
+			 (setq branch-format-file
+			       (expand-file-name vc-bzr-admin-branch-format-file
+						 l-c-parent-dir))
+			 (setq lastrev-file
+			       (expand-file-name vc-bzr-admin-lastrev l-c-parent-dir))
+			 ;; FIXME: maybe it's overkill to check if both these files exist.
+			 (and (file-exists-p branch-format-file)
+			      (file-exists-p lastrev-file)))))
 		 t)))
         (with-temp-buffer
           (insert-file-contents branch-format-file)
@@ -475,7 +494,7 @@
 		    (4 'change-log-list nil lax))))
 	 (append `((,log-view-message-re . 'log-view-message-face))
 		 ;; log-view-font-lock-keywords
-		 '(("^ *committer: \
+		 '(("^ *\\(?:committer\\|author\\): \
 \\([^<(]+?\\)[  ]*[(<]\\([[:alnum:]_.+-]+@[[:alnum:]_.-]+\\)[>)]"
 		    (1 'change-log-name)
 		    (2 'change-log-email))
@@ -523,7 +542,8 @@
 (defun vc-bzr-diff (files &optional rev1 rev2 buffer)
   "VC bzr backend for diff."
   ;; `bzr diff' exits with code 1 if diff is non-empty.
-  (apply #'vc-bzr-command "diff" (or buffer "*vc-diff*") 'async files
+  (apply #'vc-bzr-command "diff" (or buffer "*vc-diff*")
+	 (if vc-disable-async-diff 1 'async) files
          "--diff-options" (mapconcat 'identity
                                      (vc-switches 'bzr 'diff)
 				     " ")
@@ -651,7 +671,6 @@
                        ;; For conflicts, should we list the .THIS/.BASE/.OTHER?
 		       ("C  " . conflict)
 		       ("?  " . unregistered)
-		       ("?  " . unregistered)
 		       ;; No such state, but we need to distinguish this case.
 		       ("R  " . renamed)
 		       ;; For a non existent file FOO, the output is:
@@ -663,6 +682,8 @@
 		       ;; FIXME: maybe this warning can be put in the vc-dir header...
 		       ("wor" . not-found)
                        ;; Ignore "P " and "P." for pending patches.
+		       ("P  " . not-found)
+		       ("P. " . not-found)
                        ))
 	(translated nil)
 	(result nil))
@@ -732,7 +753,7 @@
     (define-key map "\C-k" 'vc-bzr-shelve-delete-at-point)
     ;; (define-key map "=" 'vc-bzr-shelve-show-at-point)
     ;; (define-key map "\C-m" 'vc-bzr-shelve-show-at-point)
-    (define-key map "A" 'vc-bzr-shelve-apply-at-point)
+    (define-key map "P" 'vc-bzr-shelve-apply-at-point)
     map))
 
 (defvar vc-bzr-shelve-menu-map
@@ -740,9 +761,9 @@
     (define-key map [de]
       '(menu-item "Delete shelf" vc-bzr-shelve-delete-at-point
 		  :help "Delete the current shelf"))
-    (define-key map [ap]
-      '(menu-item "Apply shelf" vc-bzr-shelve-apply-at-point
-		  :help "Apply the current shelf"))
+    (define-key map [po]
+      '(menu-item "Apply and remove shelf (pop)" vc-bzr-shelve-apply-at-point
+		  :help "Apply the current shelf and remove it"))
     ;; (define-key map [sh]
     ;;   '(menu-item "Show shelve" vc-bzr-shelve-show-at-point
     ;; 		  :help "Show the contents of the current shelve"))
@@ -800,7 +821,7 @@
 	     (propertize x
 			 'face 'font-lock-variable-name-face
 			 'mouse-face 'highlight
-			 'help-echo "mouse-3: Show shelve menu\nA: Apply shelf\nC-k: Delete shelf"
+			 'help-echo "mouse-3: Show shelve menu\nP: Apply and remove shelf (pop)\nC-k: Delete shelf"
 			 'keymap vc-bzr-shelve-map))
 	   shelve "\n"))
        (concat
@@ -830,8 +851,8 @@
 ;;   (pop-to-buffer (current-buffer)))
 
 (defun vc-bzr-shelve-apply (name)
-  "Apply shelve NAME."
-  (interactive "sApply shelf: ")
+  "Apply shelve NAME and remove it afterwards."
+  (interactive "sApply (and remove) shelf: ")
   (vc-bzr-command "unshelve" "*vc-bzr-shelve*" 0 nil "--apply" name)
   (vc-resynch-buffer (vc-bzr-root default-directory) t t))
 
--- a/lisp/vc-dir.el	Sun Jan 03 13:18:21 2010 -0500
+++ b/lisp/vc-dir.el	Fri Jan 08 15:59:09 2010 -0500
@@ -101,7 +101,9 @@
                       (return buffer))))))))
     (or buf
         ;; Create a new buffer named BNAME.
-        (with-current-buffer (create-file-buffer bname)
+	;; We pass a filename to create-file-buffer because it is what
+	;; the function expects, and also what uniquify needs (if active)
+        (with-current-buffer (create-file-buffer (expand-file-name bname dir))
           (cd dir)
           (vc-setup-buffer (current-buffer))
           ;; Reset the vc-parent-buffer-name so that it does not appear
@@ -928,7 +930,7 @@
     (set (make-local-variable 'vc-ewoc) (ewoc-create #'vc-dir-printer))
     (set (make-local-variable 'revert-buffer-function)
 	 'vc-dir-revert-buffer-function)
-    (setq list-buffers-directory default-directory)
+    (setq list-buffers-directory (expand-file-name "*vc-dir*" default-directory))
     (add-to-list 'vc-dir-buffers (current-buffer))
     ;; Make sure that if the directory buffer is killed, the update
     ;; process running in the background is also killed.
--- a/src/ChangeLog	Sun Jan 03 13:18:21 2010 -0500
+++ b/src/ChangeLog	Fri Jan 08 15:59:09 2010 -0500
@@ -1,3 +1,66 @@
+2010-01-08  Jan Djärv  <jan.h.d@swipnet.se>
+
+	* dispnew.c (change_frame_size_1): newwidth == FRAME_COLS  (f) must
+	also be true before we can return early (bug #5339).
+
+2010-01-06  David Reitter  <david.reitter@gmail.com>
+
+	* nsfns.m (ns_get_screen): Rewrite, returning NULL for non-NS.
+	(Fns_display_usable_bounds): Rewrite, computing bounds properly
+	(Bug#3233).
+
+2010-01-06  Jan Djärv  <jan.h.d@swipnet.se>
+
+	* font.c (font_open_entity): Enable chache and call cached_font_ok
+	for the driver if defined.
+	(QCuser_spec): New symbol.
+	(font_spec_from_name): Save name as user-spec.
+	(font_load_for_lface): Keep user-spec instead of name.
+	(font_open_by_name): Save name as user-spec.
+	(syms_of_font): Initialize QCuser_spec.
+	(font_clear_prop): Clear name if it exists in font (bug#5157).
+
+	* xftfont.c (xftfont_open): Call xftfont_add_rendering_parameters.
+	(xftfont_add_rendering_parameters, xftfont_cached_font_ok): New.
+	(syms_of_xftfont): Initialize xftfont_driver.cached_font_ok.
+
+	* font.h (struct font_driver): Add cached_font_ok.
+
+	* xterm.c (x_clear_frame): Queue draw for scroll bars.
+
+2010-01-05  Jan Djärv  <jan.h.d@swipnet.se>
+
+	* xterm.c (x_new_font): Move code for setting rows/cols before
+	resizing ...
+	(x_set_window_size): ... to here. bug #2568.
+
+	* gtkutil.c (xg_clear_under_internal_border): New function.
+	(xg_frame_resized, xg_frame_set_char_size): Call
+	xg_clear_under_internal_border.
+	(xg_update_scrollbar_pos): Clear under old scroll bar position.
+2010-01-05  Chong Yidong  <cyd@stupidchicken.com>
+
+	* keyboard.c (read_key_sequence): Catch keyboard switch after
+	making a new tty frame (Bug#5095).
+
+2010-01-05  Kenichi Handa  <handa@m17n.org>
+
+	* fontset.c (fontset_find_font): Fix getting the frame pointer.
+
+2010-01-04  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	* dbusbind.c (xd_remove_watch): Avoid trying to convert a void* to
+	Lisp_Object, preferring to convert a lisp_Object to a void* instead.
+	(Fdbus_init_bus): Use XHASH to get a scalar value from a Lisp_Object.
+
+2010-01-03  Michael Albinus  <michael.albinus@gmx.de>
+
+	* dbusbind.c (xd_add_watch): Improve debug message.
+	(xd_remove_watch): Improve debug message.  If DATA is the session
+	bus, unset D-Bus session environment.
+	(Fdbus_init_bus): Pass the bus as argument to
+	dbus_connection_set_watch_functions.  (Bug#5283)
+
 2010-01-01  Chong Yidong  <cyd@stupidchicken.com>
 
 	* nsterm.m (ns_get_color): Fix buffer overflow (Bug#4763).
@@ -144,7 +207,7 @@
 2009-12-15  Michael Albinus  <michael.albinus@gmx.de>
 
 	* dbusbind.c (xd_retrieve_arg): Reorder declarations in order to
-	avoid compiler warnings.  (Bug #5217).
+	avoid compiler warnings.  (Bug #5217)
 
 2009-12-14  Kenichi Handa  <handa@m17n.org>
 
@@ -5319,7 +5382,7 @@
 	(XD_SIGNAL1, XD_SIGNAL2, XD_SIGNAL3): New macros.  Throw Qdbus_error.
 	(xd_read_queued_messages): Catch Qdbus_error from the macros.
 	(all): Replace xsignal1, xsignal2, xsignal3 by the respective
-	macro.  (Bug#1186).
+	macro.  (Bug#1186)
 
 2008-10-23  Ali Bahrami  <ali_gnu@emvision.com>  (tiny change)
 
@@ -21213,7 +21276,7 @@
 ;; add-log-time-zone-rule: t
 ;; End:
 
-    Copyright (C) 2007, 2008, 2009  Free Software Foundation, Inc.
+    Copyright (C) 2007, 2008, 2009, 2010  Free Software Foundation, Inc.
 
   This file is part of GNU Emacs.
 
--- a/src/dbusbind.c	Sun Jan 03 13:18:21 2010 -0500
+++ b/src/dbusbind.c	Fri Jan 08 15:59:09 2010 -0500
@@ -761,14 +761,14 @@
   if (dbus_watch_get_flags (watch) & DBUS_WATCH_READABLE)
     {
 #if HAVE_DBUS_WATCH_GET_UNIX_FD
-      /* TODO: Reverse these on Win32, which prefers the opposite. */
+      /* TODO: Reverse these on Win32, which prefers the opposite.  */
       int fd = dbus_watch_get_unix_fd(watch);
       if (fd == -1)
 	fd = dbus_watch_get_socket(watch);
 #else
       int fd = dbus_watch_get_fd(watch);
 #endif
-      XD_DEBUG_MESSAGE ("%d", fd);
+      XD_DEBUG_MESSAGE ("fd %d", fd);
 
       if (fd == -1)
 	return FALSE;
@@ -781,7 +781,8 @@
   return TRUE;
 }
 
-/* Remove connection file descriptor from input_wait_mask.  */
+/* Remove connection file descriptor from input_wait_mask.  DATA is
+   the used bus, either QCdbus_system_bus or QCdbus_session_bus.  */
 void
 xd_remove_watch (watch, data)
      DBusWatch *watch;
@@ -791,18 +792,25 @@
   if (dbus_watch_get_flags (watch) & DBUS_WATCH_READABLE)
     {
 #if HAVE_DBUS_WATCH_GET_UNIX_FD
-      /* TODO: Reverse these on Win32, which prefers the opposite. */
+      /* TODO: Reverse these on Win32, which prefers the opposite.  */
       int fd = dbus_watch_get_unix_fd(watch);
       if (fd == -1)
 	fd = dbus_watch_get_socket(watch);
 #else
       int fd = dbus_watch_get_fd(watch);
 #endif
-      XD_DEBUG_MESSAGE ("%d", fd);
+      XD_DEBUG_MESSAGE ("fd %d", fd);
 
       if (fd == -1)
 	return;
 
+      /* Unset session environment.  */
+      if ((data != NULL) && (data == (void*) XHASH (QCdbus_session_bus)))
+	{
+	  XD_DEBUG_MESSAGE ("unsetenv DBUS_SESSION_BUS_ADDRESS");
+	  unsetenv ("DBUS_SESSION_BUS_ADDRESS");
+	}
+
       /* Remove the file descriptor from input_wait_mask.  */
       delete_keyboard_wait_descriptor (fd);
     }
@@ -825,11 +833,12 @@
   /* Open a connection to the bus.  */
   connection = xd_initialize (bus);
 
-  /* Add the watch functions.  */
+  /* Add the watch functions.  We pass also the bus as data, in order
+     to distinguish between the busses in xd_remove_watch.  */
   if (!dbus_connection_set_watch_functions (connection,
 					    xd_add_watch,
 					    xd_remove_watch,
-					    NULL, NULL, NULL))
+					    NULL, (void*) XHASH (bus), NULL))
     XD_SIGNAL1 (build_string ("Cannot add watch functions"));
 
   /* Return.  */
--- a/src/dispnew.c	Sun Jan 03 13:18:21 2010 -0500
+++ b/src/dispnew.c	Fri Jan 08 15:59:09 2010 -0500
@@ -6346,8 +6346,11 @@
   check_frame_size (f, &newheight, &newwidth);
 
   /* If we're not changing the frame size, quit now.  */
+  /* Frame width may be unchanged but the text portion may change, for example,
+     fullscreen and remove/add scroll bar.  */
   if (newheight == FRAME_LINES (f)
-      && new_frame_total_cols == FRAME_TOTAL_COLS (f))
+      && newwidth == FRAME_COLS  (f) // text portion unchanged
+      && new_frame_total_cols == FRAME_TOTAL_COLS (f)) // frame width unchanged
     return;
 
   BLOCK_INPUT;
--- a/src/font.c	Sun Jan 03 13:18:21 2010 -0500
+++ b/src/font.c	Fri Jan 08 15:59:09 2010 -0500
@@ -143,6 +143,8 @@
    characters; used in xfont.c and ftfont.c.  */
 Lisp_Object Qja, Qko;
 
+Lisp_Object QCuser_spec;
+
 Lisp_Object Vfont_encoding_alist;
 
 /* Alist of font registry symbol and the corresponding charsets
@@ -2989,16 +2991,6 @@
   else if (CONSP (Vface_font_rescale_alist))
     scaled_pixel_size = pixel_size * font_rescale_ratio (entity);
 
-#if 0
-  /* This doesn't work if you have changed hinting or any other parameter.
-     We need to make a new object in every case to be sure. */
-  for (objlist = AREF (entity, FONT_OBJLIST_INDEX); CONSP (objlist);
-       objlist = XCDR (objlist))
-    if (! NILP (AREF (XCAR (objlist), FONT_TYPE_INDEX))
-	&& XFONT_OBJECT (XCAR (objlist))->pixel_size == pixel_size)
-      return  XCAR (objlist);
-#endif
-
   val = AREF (entity, FONT_TYPE_INDEX);
   for (driver_list = f->font_driver_list;
        driver_list && ! EQ (driver_list->driver->type, val);
@@ -3006,6 +2998,19 @@
   if (! driver_list)
     return Qnil;
 
+  for (objlist = AREF (entity, FONT_OBJLIST_INDEX); CONSP (objlist);
+       objlist = XCDR (objlist))
+    {
+      Lisp_Object fn = XCAR (objlist);
+      if (! NILP (AREF (fn, FONT_TYPE_INDEX))
+          && XFONT_OBJECT (fn)->pixel_size == pixel_size)
+        {
+          if (driver_list->driver->cached_font_ok == NULL
+              || driver_list->driver->cached_font_ok (f, fn, entity))
+            return fn;
+        }
+    }
+
   font_object = driver_list->driver->open (f, entity, scaled_pixel_size);
   if (!NILP (font_object))
     ASET (font_object, FONT_SIZE_INDEX, make_number (pixel_size));
@@ -3161,6 +3166,7 @@
   if (font_parse_name ((char *) SDATA (font_name), spec) == -1)
     return Qnil;
   font_put_extra (spec, QCname, font_name);
+  font_put_extra (spec, QCuser_spec, font_name);
   return spec;
 }
 
@@ -3174,14 +3180,13 @@
 
   if (! FONTP (font))
     return;
-#if 0
+
   if (! NILP (Ffont_get (font, QCname)))
     {
       font = Fcopy_font_spec (font);
       font_put_extra (font, QCname, Qnil);
     }
 
-#endif
   if (NILP (AREF (font, prop))
       && prop != FONT_FAMILY_INDEX
       && prop != FONT_FOUNDRY_INDEX
@@ -3539,8 +3544,8 @@
   entity = font_open_for_lface (f, entity, attrs, spec);
   if (!NILP (entity))
     {
-      name = Ffont_get (spec, QCname);
-      if (STRINGP (name)) font_put_extra (entity, QCname, name);
+      name = Ffont_get (spec, QCuser_spec);
+      if (STRINGP (name)) font_put_extra (entity, QCuser_spec, name);
     }
   return entity;
 }
@@ -3614,7 +3619,7 @@
   ret = font_open_by_spec (f, spec);
   /* Do not loose name originally put in.  */
   if (!NILP (ret))
-    font_put_extra (ret, QCname, args[1]);
+    font_put_extra (ret, QCuser_spec, args[1]);
 
   return ret;
 }
@@ -5269,6 +5274,8 @@
   DEFSYM (Qja, "ja");
   DEFSYM (Qko, "ko");
 
+  DEFSYM (QCuser_spec, "user-spec");
+
   staticpro (&null_vector);
   null_vector = Fmake_vector (make_number (0), Qnil);
 
--- a/src/font.h	Sun Jan 03 13:18:21 2010 -0500
+++ b/src/font.h	Fri Jan 08 15:59:09 2010 -0500
@@ -689,6 +689,14 @@
 				   int c, unsigned variations[256]));
 
   void (*filter_properties) P_ ((Lisp_Object font, Lisp_Object properties));
+
+  /* Optional.
+
+     Return non-zero if FONT_OBJECT can be used as a (cached) font
+     for ENTITY on frame F.  */
+  int (*cached_font_ok) P_ ((struct frame *f,
+                             Lisp_Object font_object,
+                             Lisp_Object entity));
 };
 
 
--- a/src/fontset.c	Sun Jan 03 13:18:21 2010 -0500
+++ b/src/fontset.c	Fri Jan 08 15:59:09 2010 -0500
@@ -533,8 +533,8 @@
 {
   Lisp_Object vec, font_group;
   int i, charset_matched = 0, found_index;
-  FRAME_PTR f = (FRAMEP (FONTSET_FRAME (fontset)))
-    ? XFRAME (selected_frame) : XFRAME (FONTSET_FRAME (fontset));
+  FRAME_PTR f = (FRAMEP (FONTSET_FRAME (fontset))
+		 ? XFRAME (FONTSET_FRAME (fontset)) : XFRAME (selected_frame));
   Lisp_Object rfont_def;
 
   font_group = fontset_get_font_group (fontset, fallback ? -1 : c);
--- a/src/gtkutil.c	Sun Jan 03 13:18:21 2010 -0500
+++ b/src/gtkutil.c	Fri Jan 08 15:59:09 2010 -0500
@@ -568,6 +568,42 @@
                      f->left_pos, f->top_pos);
 }
 
+/* Clear under internal border if any.  As we use a mix of Gtk+ and X calls
+   and use a GtkFixed widget, this doesn't happen automatically.  */
+
+static void
+xg_clear_under_internal_border (f)
+     FRAME_PTR f;
+{
+  if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0)
+    {
+      GtkWidget *wfixed = f->output_data.x->edit_widget;
+      gtk_widget_queue_draw (wfixed);
+      gdk_window_process_all_updates ();
+      x_clear_area (FRAME_X_DISPLAY (f),
+                    FRAME_X_WINDOW (f),
+                    0, 0,
+                    FRAME_PIXEL_WIDTH (f),
+                    FRAME_INTERNAL_BORDER_WIDTH (f), 0);
+      x_clear_area (FRAME_X_DISPLAY (f),
+                    FRAME_X_WINDOW (f),
+                    0, 0,
+                    FRAME_INTERNAL_BORDER_WIDTH (f),
+                    FRAME_PIXEL_HEIGHT (f), 0);
+      x_clear_area (FRAME_X_DISPLAY (f),
+                    FRAME_X_WINDOW (f),
+                    0, FRAME_PIXEL_HEIGHT (f) - FRAME_INTERNAL_BORDER_WIDTH (f),
+                    FRAME_PIXEL_WIDTH (f),
+                    FRAME_INTERNAL_BORDER_WIDTH (f), 0);
+      x_clear_area (FRAME_X_DISPLAY (f),
+                    FRAME_X_WINDOW (f),
+                    FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f),
+                    0,
+                    FRAME_INTERNAL_BORDER_WIDTH (f),
+                    FRAME_PIXEL_HEIGHT (f), 0);
+    }
+}
+
 /* Function to handle resize of our frame.  As we have a Gtk+ tool bar
    and a Gtk+ menu bar, we get resize events for the edit part of the
    frame only.  We let Gtk+ deal with the Gtk+ parts.
@@ -584,8 +620,8 @@
   if (pixelwidth == -1 && pixelheight == -1)
     {
       if (FRAME_GTK_WIDGET (f) && GTK_WIDGET_MAPPED (FRAME_GTK_WIDGET (f)))
-          gdk_window_get_geometry(FRAME_GTK_WIDGET (f)->window, 0, 0,
-                                  &pixelwidth, &pixelheight, 0);
+          gdk_window_get_geometry (FRAME_GTK_WIDGET (f)->window, 0, 0,
+                                   &pixelwidth, &pixelheight, 0);
       else return;
     }
   
@@ -601,6 +637,7 @@
       FRAME_PIXEL_WIDTH (f) = pixelwidth;
       FRAME_PIXEL_HEIGHT (f) = pixelheight;
 
+      xg_clear_under_internal_border (f);
       change_frame_size (f, rows, columns, 0, 1, 0);
       SET_FRAME_GARBAGED (f);
       cancel_mouse_face (f);
@@ -637,6 +674,10 @@
      after calculating that value.  */
   pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols);
 
+
+  /* Do this before resize, as we don't know yet if we will be resized.  */
+  xg_clear_under_internal_border (f);
+
   /* Must resize our top level widget.  Font size may have changed,
      but not rows/cols.  */
   gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
@@ -3201,15 +3242,43 @@
     {
       GtkWidget *wfixed = f->output_data.x->edit_widget;
       GtkWidget *wparent = gtk_widget_get_parent (wscroll);
+      GtkFixed *wf = GTK_FIXED (wfixed);
+
+      /* Clear out old position.  */
+      GList *iter;
+      int oldx = -1, oldy = -1, oldw, oldh;
+      for (iter = wf->children; iter; iter = iter->next)
+        if (((GtkFixedChild *)iter->data)->widget == wparent)
+          {
+            GtkFixedChild *ch = (GtkFixedChild *)iter->data;
+            if (ch->x != left || ch->y != top)
+              {
+                oldx = ch->x;
+                oldy = ch->y;
+                gtk_widget_get_size_request (wscroll, &oldw, &oldh);
+              }
+            break;
+          }
 
       /* Move and resize to new values.  */
       gtk_fixed_move (GTK_FIXED (wfixed), wparent, left, top);
       gtk_widget_set_size_request (wscroll, width, height);
-      gtk_widget_queue_draw (wparent);
+      gtk_widget_queue_draw (wfixed);
       gdk_window_process_all_updates ();
+      if (oldx != -1) 
+        {
+          /* Clear under old scroll bar position.  This must be done after
+             the gtk_widget_queue_draw and gdk_window_process_all_updates
+             above.  */
+          x_clear_area (FRAME_X_DISPLAY (f),
+                        FRAME_X_WINDOW (f),
+                        oldx, oldy, oldw, oldh, 0);
+        }
+      
       /* GTK does not redraw until the main loop is entered again, but
          if there are no X events pending we will not enter it.  So we sync
          here to get some events.  */
+            
       x_sync (f);
       SET_FRAME_GARBAGED (f);
       cancel_mouse_face (f);
--- a/src/keyboard.c	Sun Jan 03 13:18:21 2010 -0500
+++ b/src/keyboard.c	Fri Jan 08 15:59:09 2010 -0500
@@ -9502,7 +9502,13 @@
 	    key = read_char (NILP (prompt), nmaps,
 			     (Lisp_Object *) submaps, last_nonmenu_event,
 			     &used_mouse_menu, NULL);
-	    if (INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */
+	    if ((INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */
+		/* When switching to a new tty (with a new keyboard),
+		   read_char returns the new buffer, rather than -2
+		   (Bug#5095).  This is because `terminal-init-xterm'
+		   calls read-char, which eats the wrong_kboard_jmpbuf
+		   return.  Any better way to fix this? -- cyd  */
+		|| (interrupted_kboard != current_kboard))
 	      {
 		int found = 0;
 		struct kboard *k;
--- a/src/nsfns.m	Sun Jan 03 13:18:21 2010 -0500
+++ b/src/nsfns.m	Fri Jan 08 15:59:09 2010 -0500
@@ -206,30 +206,28 @@
 static NSScreen *
 ns_get_screen (Lisp_Object screen)
 {
-  struct terminal *terminal = get_terminal (screen, 1);
+  struct frame *f;
+  struct terminal *terminal;
+
+  if (EQ (Qt, screen)) /* not documented */
+    return [NSScreen mainScreen];
+
+  terminal = get_terminal (screen, 1);
   if (terminal->type != output_ns)
-    // Not sure if this special case for nil is needed.  It does seem to be
-    // important in xfns.c for the make-frame call in frame-initialize,
-    // so let's keep it here for now.
-    return (NILP (screen) ? [NSScreen mainScreen] : NULL);
+    return NULL;
+
+  if (NILP (screen))
+    f = SELECTED_FRAME ();
+  else if (FRAMEP (screen))
+    f = XFRAME (screen);
   else
     {
       struct ns_display_info *dpyinfo = terminal->display_info.ns;
-      struct frame *f = dpyinfo->x_focus_frame;
-      if (!f)
-	f = dpyinfo->x_highlight_frame;
-      if (!f)
-	return NULL;
-      else
-	{
-	  id window = nil;
-	  Lisp_Object frame;
-	  eassert (FRAME_NS_P (f));
-	  XSETFRAME (frame, f);
-	  window = ns_get_window (frame);
-	  return window ? [window screen] : NULL;
-	}
+      f = (dpyinfo->x_focus_frame || dpyinfo->x_highlight_frame);
     }
+
+  return ((f && FRAME_NS_P (f)) ? [[FRAME_NS_VIEW (f) window] screen]
+	  : NULL);
 }
 
 
@@ -2325,15 +2323,21 @@
      Lisp_Object display;
 {
   int top;
+  NSScreen *screen;
   NSRect vScreen;
 
   check_ns ();
-  vScreen = [ns_get_screen (display) visibleFrame];
-  top = vScreen.origin.y == 0.0 ?
-    (int) [ns_get_screen (display) frame].size.height - vScreen.size.height : 0;
-
+  screen = ns_get_screen (display);
+  if (!screen)
+    return Qnil;
+
+  vScreen = [screen visibleFrame];
+
+  /* NS coordinate system is upside-down.
+     Transform to screen-specific coordinates. */
   return list4 (make_number ((int) vScreen.origin.x),
-                make_number (top),
+		make_number ((int) [screen frame].size.height
+			     - vScreen.size.height - vScreen.origin.y),
                 make_number ((int) vScreen.size.width),
                 make_number ((int) vScreen.size.height));
 }
--- a/src/xftfont.c	Sun Jan 03 13:18:21 2010 -0500
+++ b/src/xftfont.c	Fri Jan 08 15:59:09 2010 -0500
@@ -237,6 +237,56 @@
     }
 }
 
+static void
+xftfont_add_rendering_parameters (pat, entity)
+     FcPattern *pat;
+     Lisp_Object entity;
+{
+  Lisp_Object tail;
+  int ival;
+
+  for (tail = AREF (entity, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail))
+    {
+      Lisp_Object key = XCAR (XCAR (tail));
+      Lisp_Object val = XCDR (XCAR (tail));
+
+      if (EQ (key, QCantialias))
+          FcPatternAddBool (pat, FC_ANTIALIAS, NILP (val) ? FcFalse : FcTrue);
+      else if (EQ (key, QChinting))
+	FcPatternAddBool (pat, FC_HINTING, NILP (val) ? FcFalse : FcTrue);
+      else if (EQ (key, QCautohint))
+	FcPatternAddBool (pat, FC_AUTOHINT, NILP (val) ? FcFalse : FcTrue);
+      else if (EQ (key, QChintstyle))
+	{
+	  if (INTEGERP (val))
+	    FcPatternAddInteger (pat, FC_HINT_STYLE, XINT (val));
+          else if (SYMBOLP (val)
+                   && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival))
+	    FcPatternAddInteger (pat, FC_HINT_STYLE, ival);
+	}
+      else if (EQ (key, QCrgba))
+	{
+	  if (INTEGERP (val))
+	    FcPatternAddInteger (pat, FC_RGBA, XINT (val));
+          else if (SYMBOLP (val)
+                   && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival))
+	    FcPatternAddInteger (pat, FC_RGBA, ival);
+	}
+      else if (EQ (key, QClcdfilter))
+	{
+	  if (INTEGERP (val))
+	    FcPatternAddInteger (pat, FC_LCD_FILTER, ival = XINT (val));
+          else if (SYMBOLP (val)
+                   && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival))
+	    FcPatternAddInteger (pat, FC_LCD_FILTER, ival);
+	}
+#ifdef FC_EMBOLDEN
+      else if (EQ (key, QCembolden))
+	FcPatternAddBool (pat, FC_EMBOLDEN, NILP (val) ? FcFalse : FcTrue);
+#endif
+    }
+}
+
 static Lisp_Object
 xftfont_open (f, entity, pixel_size)
      FRAME_PTR f;
@@ -245,7 +295,7 @@
 {
   FcResult result;
   Display *display = FRAME_X_DISPLAY (f);
-  Lisp_Object val, filename, index, tail, font_object;
+  Lisp_Object val, filename, index, font_object;
   FcPattern *pat = NULL, *match;
   struct xftfont_info *xftfont_info = NULL;
   struct font *font;
@@ -253,7 +303,7 @@
   XftFont *xftfont = NULL;
   int spacing;
   char name[256];
-  int len, i, ival;
+  int len, i;
   XGlyphInfo extents;
   FT_Face ft_face;
   FcMatrix *matrix;
@@ -297,46 +347,7 @@
      over 10x20-ISO8859-1.pcf.gz).  */
   FcPatternAddCharSet (pat, FC_CHARSET, ftfont_get_fc_charset (entity));
 
-  for (tail = AREF (entity, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail))
-    {
-      Lisp_Object key, val;
-
-      key = XCAR (XCAR (tail)), val = XCDR (XCAR (tail));
-      if (EQ (key, QCantialias))
-          FcPatternAddBool (pat, FC_ANTIALIAS, NILP (val) ? FcFalse : FcTrue);
-      else if (EQ (key, QChinting))
-	FcPatternAddBool (pat, FC_HINTING, NILP (val) ? FcFalse : FcTrue);
-      else if (EQ (key, QCautohint))
-	FcPatternAddBool (pat, FC_AUTOHINT, NILP (val) ? FcFalse : FcTrue);
-      else if (EQ (key, QChintstyle))
-	{
-	  if (INTEGERP (val))
-	    FcPatternAddInteger (pat, FC_HINT_STYLE, XINT (val));
-          else if (SYMBOLP (val)
-                   && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival))
-	    FcPatternAddInteger (pat, FC_HINT_STYLE, ival);
-	}
-      else if (EQ (key, QCrgba))
-	{
-	  if (INTEGERP (val))
-	    FcPatternAddInteger (pat, FC_RGBA, XINT (val));
-          else if (SYMBOLP (val)
-                   && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival))
-	    FcPatternAddInteger (pat, FC_RGBA, ival);
-	}
-      else if (EQ (key, QClcdfilter))
-	{
-	  if (INTEGERP (val))
-	    FcPatternAddInteger (pat, FC_LCD_FILTER, ival = XINT (val));
-          else if (SYMBOLP (val)
-                   && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival))
-	    FcPatternAddInteger (pat, FC_LCD_FILTER, ival);
-	}
-#ifdef FC_EMBOLDEN
-      else if (EQ (key, QCembolden))
-	FcPatternAddBool (pat, FC_EMBOLDEN, NILP (val) ? FcFalse : FcTrue);
-#endif
-    }
+  xftfont_add_rendering_parameters (pat, entity);
 
   FcPatternAddString (pat, FC_FILE, (FcChar8 *) SDATA (filename));
   FcPatternAddInteger (pat, FC_INDEX, XINT (index));
@@ -712,6 +723,53 @@
   return 0;
 }
 
+static int
+xftfont_cached_font_ok (f, font_object, entity)
+     struct frame *f;
+     Lisp_Object font_object;
+     Lisp_Object entity;
+
+{
+  struct xftfont_info *info = (struct xftfont_info *) XFONT_OBJECT (font_object);
+  FcPattern *oldpat = info->xftfont->pattern;
+  Display *display = FRAME_X_DISPLAY (f);
+  FcPattern *pat = FcPatternCreate ();
+  FcBool b1, b2;
+  int ok = 0, i1, i2, r1, r2;
+
+  xftfont_add_rendering_parameters (pat, entity);
+  XftDefaultSubstitute (display, FRAME_X_SCREEN_NUMBER (f), pat);
+
+  r1 = FcPatternGetBool (pat, FC_ANTIALIAS, 0, &b1);
+  r2 = FcPatternGetBool (oldpat, FC_ANTIALIAS, 0, &b2);
+  if (r1 != r2 || b1 != b2) goto out;
+  r1 = FcPatternGetBool (pat, FC_HINTING, 0, &b1);
+  r2 = FcPatternGetBool (oldpat, FC_HINTING, 0, &b2);
+  if (r1 != r2 || b1 != b2) goto out;
+  r1 = FcPatternGetBool (pat, FC_AUTOHINT, 0, &b1);
+  r2 = FcPatternGetBool (oldpat, FC_AUTOHINT, 0, &b2);
+  if (r1 != r2 || b1 != b2) goto out;
+#ifdef FC_EMBOLDEN
+  r1 = FcPatternGetBool (pat, FC_EMBOLDEN, 0, &b1);
+  r2 = FcPatternGetBool (oldpat, FC_EMBOLDEN, 0, &b2);
+  if (r1 != r2 || b1 != b2) goto out;
+#endif
+  r1 = FcPatternGetInteger (pat, FC_HINT_STYLE, 0, &i1);
+  r2 = FcPatternGetInteger (oldpat, FC_HINT_STYLE, 0, &i2);
+  if (r1 != r2 || i1 != i2) goto out;
+  r1 = FcPatternGetInteger (pat, FC_LCD_FILTER, 0, &i1);
+  r2 = FcPatternGetInteger (oldpat, FC_LCD_FILTER, 0, &i2);
+  if (r1 != r2 || i1 != i2) goto out;
+  r1 = FcPatternGetInteger (pat, FC_RGBA, 0, &i1);
+  r2 = FcPatternGetInteger (oldpat, FC_RGBA, 0, &i2);
+  if (r1 != r2 || i1 != i2) goto out;
+
+  ok = 1;
+ out:
+  FcPatternDestroy (pat);
+  return ok;
+}
+
 void
 syms_of_xftfont ()
 {
@@ -737,6 +795,7 @@
   xftfont_driver.text_extents = xftfont_text_extents;
   xftfont_driver.draw = xftfont_draw;
   xftfont_driver.end_for_frame = xftfont_end_for_frame;
+  xftfont_driver.cached_font_ok = xftfont_cached_font_ok;
 
   register_font_driver (&xftfont_driver, NULL);
 }
--- a/src/xterm.c	Sun Jan 03 13:18:21 2010 -0500
+++ b/src/xterm.c	Fri Jan 08 15:59:09 2010 -0500
@@ -2951,6 +2951,12 @@
      colors or something like that, then they should be notified.  */
   x_scroll_bar_clear (f);
 
+#if defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS)
+  /* Make sure scroll bars are redrawn.  As they aren't redrawn by
+     redisplay, do it here.  */
+  gtk_widget_queue_draw (FRAME_GTK_WIDGET (f));
+#endif
+  
   XFlush (FRAME_X_DISPLAY (f));
 
   UNBLOCK_INPUT;
@@ -8064,32 +8070,7 @@
 	 doing it because it's done in Fx_show_tip, and it leads to
 	 problems because the tip frame has no widget.  */
       if (NILP (tip_frame) || XFRAME (tip_frame) != f)
-        {
-	  int rows, cols;
-	  
-	  /* When the frame is maximized/fullscreen or running under for
-             example Xmonad, x_set_window_size will be a no-op.
-             In that case, the right thing to do is extend rows/cols to
-             the current frame size.  We do that first if x_set_window_size
-             turns out to not be a no-op (there is no way to know).
-             The size will be adjusted again if the frame gets a
-             ConfigureNotify event as a result of x_set_window_size.  */
-          int pixelh = FRAME_PIXEL_HEIGHT (f);
-#ifdef USE_X_TOOLKIT
-          /* The menu bar is not part of text lines.  The tool bar
-             is however.  */
-          pixelh -= FRAME_MENUBAR_HEIGHT (f);
-#endif
-          rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixelh);
-	  /* Update f->scroll_bar_actual_width because it is used in
-	     FRAME_PIXEL_WIDTH_TO_TEXT_COLS.  */
-	  f->scroll_bar_actual_width
-	    = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
-          cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, FRAME_PIXEL_WIDTH (f));
-          
-          change_frame_size (f, rows, cols, 0, 1, 0);
-          x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
-        }
+        x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
     }
 
 #ifdef HAVE_X_I18N
@@ -8977,6 +8958,32 @@
 {
   BLOCK_INPUT;
 
+  if (NILP (tip_frame) || XFRAME (tip_frame) != f)
+    {
+      int r, c;
+	  
+      /* When the frame is maximized/fullscreen or running under for
+         example Xmonad, x_set_window_size_1 will be a no-op.
+         In that case, the right thing to do is extend rows/cols to
+         the current frame size.  We do that first if x_set_window_size_1
+         turns out to not be a no-op (there is no way to know).
+         The size will be adjusted again if the frame gets a
+         ConfigureNotify event as a result of x_set_window_size.  */
+      int pixelh = FRAME_PIXEL_HEIGHT (f);
+#ifdef USE_X_TOOLKIT
+      /* The menu bar is not part of text lines.  The tool bar
+         is however.  */
+      pixelh -= FRAME_MENUBAR_HEIGHT (f);
+#endif
+      r = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixelh);
+      /* Update f->scroll_bar_actual_width because it is used in
+         FRAME_PIXEL_WIDTH_TO_TEXT_COLS.  */
+      f->scroll_bar_actual_width
+        = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
+      c = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, FRAME_PIXEL_WIDTH (f));
+      change_frame_size (f, r, c, 0, 1, 0);
+    }
+
 #ifdef USE_GTK
   if (FRAME_GTK_WIDGET (f))
     xg_frame_set_char_size (f, cols, rows);