# HG changeset patch # User Kenichi Handa # Date 1262911578 -32400 # Node ID a9df81470f833a7674dcbcab93e76b4f9d641078 # Parent 8d23ea9e4ab1c8b427897a0a5ad286683ebd15b9# Parent 0865d6c0506d156e05abafe5401b3b2b4965562e from trunk diff -r 8d23ea9e4ab1 -r a9df81470f83 lisp/ChangeLog --- 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 + + * font-setting.el (font-setting-change-default-font): Use user-spec + instead of name. + +2010-01-06 Dan Nicolaescu + + * vc-bzr.el (vc-bzr-after-dir-status): Ignore pending merges. + +2010-01-05 Tom Tromey + + * progmodes/python.el (python-font-lock-keywords): Handle + qualified decorators (Bug#881). + +2010-01-05 Dan Nicolaescu + + * vc-bzr.el (vc-bzr-working-revision): Fix looking for a revision + in a lightweight checkout. + 2010-01-05 Kenichi Handa * language/indian.el (malayalam-composable-pattern): Fix ZWNJ and diff -r 8d23ea9e4ab1 -r a9df81470f83 lisp/font-setting.el --- 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 diff -r 8d23ea9e4ab1 -r a9df81470f83 lisp/gnus/ChangeLog --- 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 + + * 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 + + * 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 + + * 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 * 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. diff -r 8d23ea9e4ab1 -r a9df81470f83 lisp/gnus/gnus-art.el --- 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 diff -r 8d23ea9e4ab1 -r a9df81470f83 lisp/gnus/gnus-sum.el --- 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) diff -r 8d23ea9e4ab1 -r a9df81470f83 lisp/gnus/gnus-util.el --- 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 diff -r 8d23ea9e4ab1 -r a9df81470f83 lisp/gnus/message.el --- 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) diff -r 8d23ea9e4ab1 -r a9df81470f83 lisp/progmodes/python.el --- 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 @@ -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 diff -r 8d23ea9e4ab1 -r a9df81470f83 lisp/vc-bzr.el --- 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)) diff -r 8d23ea9e4ab1 -r a9df81470f83 src/ChangeLog --- 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 + + * 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 + + * 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 + + * 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 + + * keyboard.c (read_key_sequence): Catch keyboard switch after + making a new tty frame (Bug#5095). + 2010-01-05 Kenichi Handa * fontset.c (fontset_find_font): Fix getting the frame pointer. diff -r 8d23ea9e4ab1 -r a9df81470f83 src/font.c --- 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); diff -r 8d23ea9e4ab1 -r a9df81470f83 src/font.h --- 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)); }; diff -r 8d23ea9e4ab1 -r a9df81470f83 src/gtkutil.c --- 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); diff -r 8d23ea9e4ab1 -r a9df81470f83 src/keyboard.c --- 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; diff -r 8d23ea9e4ab1 -r a9df81470f83 src/nsfns.m --- 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)); } diff -r 8d23ea9e4ab1 -r a9df81470f83 src/xftfont.c --- 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); } diff -r 8d23ea9e4ab1 -r a9df81470f83 src/xterm.c --- 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);