changeset 106760:a9df81470f83

from trunk
author Kenichi Handa <handa@m17n.org>
date Fri, 08 Jan 2010 09:46:18 +0900
parents 8d23ea9e4ab1 (current diff) 0865d6c0506d (diff)
children 8e1704b5a4b3
files
diffstat 17 files changed, 432 insertions(+), 127 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Tue Jan 05 20:59:03 2010 +0900
+++ b/lisp/ChangeLog	Fri Jan 08 09:46:18 2010 +0900
@@ -1,3 +1,22 @@
+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
--- a/lisp/font-setting.el	Tue Jan 05 20:59:03 2010 +0900
+++ b/lisp/font-setting.el	Fri Jan 08 09:46:18 2010 +0900
@@ -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	Tue Jan 05 20:59:03 2010 +0900
+++ b/lisp/gnus/ChangeLog	Fri Jan 08 09:46:18 2010 +0900
@@ -1,3 +1,22 @@
+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
@@ -13788,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	Tue Jan 05 20:59:03 2010 +0900
+++ b/lisp/gnus/gnus-art.el	Fri Jan 08 09:46:18 2010 +0900
@@ -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	Tue Jan 05 20:59:03 2010 +0900
+++ b/lisp/gnus/gnus-sum.el	Fri Jan 08 09:46:18 2010 +0900
@@ -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	Tue Jan 05 20:59:03 2010 +0900
+++ b/lisp/gnus/gnus-util.el	Fri Jan 08 09:46:18 2010 +0900
@@ -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	Tue Jan 05 20:59:03 2010 +0900
+++ b/lisp/gnus/message.el	Fri Jan 08 09:46:18 2010 +0900
@@ -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)
--- a/lisp/progmodes/python.el	Tue Jan 05 20:59:03 2010 +0900
+++ b/lisp/progmodes/python.el	Fri Jan 08 09:46:18 2010 +0900
@@ -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	Tue Jan 05 20:59:03 2010 +0900
+++ b/lisp/vc-bzr.el	Fri Jan 08 09:46:18 2010 +0900
@@ -356,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)
@@ -661,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:
@@ -673,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))
--- a/src/ChangeLog	Tue Jan 05 20:59:03 2010 +0900
+++ b/src/ChangeLog	Fri Jan 08 09:46:18 2010 +0900
@@ -1,3 +1,43 @@
+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.
--- a/src/font.c	Tue Jan 05 20:59:03 2010 +0900
+++ b/src/font.c	Fri Jan 08 09:46:18 2010 +0900
@@ -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	Tue Jan 05 20:59:03 2010 +0900
+++ b/src/font.h	Fri Jan 08 09:46:18 2010 +0900
@@ -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/gtkutil.c	Tue Jan 05 20:59:03 2010 +0900
+++ b/src/gtkutil.c	Fri Jan 08 09:46:18 2010 +0900
@@ -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	Tue Jan 05 20:59:03 2010 +0900
+++ b/src/keyboard.c	Fri Jan 08 09:46:18 2010 +0900
@@ -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	Tue Jan 05 20:59:03 2010 +0900
+++ b/src/nsfns.m	Fri Jan 08 09:46:18 2010 +0900
@@ -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	Tue Jan 05 20:59:03 2010 +0900
+++ b/src/xftfont.c	Fri Jan 08 09:46:18 2010 +0900
@@ -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	Tue Jan 05 20:59:03 2010 +0900
+++ b/src/xterm.c	Fri Jan 08 09:46:18 2010 +0900
@@ -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);