changeset 108024:4d8277a44bb4

Gtk tool bars can be text, icons with text or just icons. * xsettings.c: Qmonospace_font_name, Qtool_bar_style and current_tool_bar_style are new. (store_config_changed_event): Rename from store_font_changed_event. (XSETTINGS_TOOL_BAR_STYLE): New define. (SEEN_FONT, SEEN_TB_STYLE): New enum values. (struct xsettings): Add font and tb_style, set xft stuff inside #ifdef HAVE_XFT. (something_changedCB): store_font_changed_event is now store_config_changed_event (parse_settings): Rename from parse_xft_settings. Read non-xft xsettings outside #ifdef HAVE_XFT. (read_settings): Renamed from read_xft_settings. (apply_xft_settings): Take current settings as parameter. Do not call read_(xft)_settings. (read_and_apply_settings): New function. (xft_settings_event): Do non-xft stuff out of HAVE_XFT. Call read_and_apply_settings if there are settings to be read. (init_xsettings): Renamed from init_xfd_settings. Call read_and_apply_settings unconditionally. (xsettings_initialize): Call init_xsettings. (Ftool_bar_get_system_style): New function. (syms_of_xsettings): Define Qmonospace_font_name and Qtool_bar_style. Initialize current_tool_bar_style to nil. defsubr Stool_bar_get_system_style. Fprovide on dynamic-setting. * xsettings.h (Ftool_bar_get_system_style): Declare. * xdisp.c: Vtool_bar_style, tool_bar_max_label_size, Qtext, Qboth, Qboth_horiz are new. (syms_of_xdisp): Intern Qtext, Qboth, Qboth_horiz, DEFVAR Vtool_bar_style, tool_bar_max_label_size. * lisp.h: Extern declare Qtext, Qboth, Qboth_horiz. * keyboard.c: QClabel is new. (parse_tool_bar_item): Take out QClabel from tool bar items. Try to construct a label if ther is no QClabel. (syms_of_keyboard): Intern :label as QClabel. * dispextern.h (tool_bar_item_idx): TOOL_BAR_ITEM_LABEL is new. (Vtool_bar_style, tool_bar_max_label_size, DEFAULT_TOOL_BAR_LABEL_SIZE): New. * Makefile.in (SOME_MACHINE_LISP): font-setting.el renamed to dynamic-setting.el. * gtkutil.c (xg_tool_bar_menu_proxy): Handle label in tool bar item. (xg_make_tool_item, xg_show_toolbar_item): New function. (update_frame_tool_bar): Take label from TOOL_BAR_ITEM_LABEL. Call xg_make_tool_item to make a tool bar item. Call xg_show_toolbar_item. Use wtoolbar instead of x->toolbar_widget. * xterm.c (x_draw_image_relief): Take Vtool_bar_button_margin into account for toolbars. * vc-dir.el (vc-dir-tool-bar-map): Add :label on some tool bar items. * tool-bar.el (tool-bar-setup): Add :label on some tool bar items. * loadup.el: Load dynamic-setting.el if feature dynamic-setting is present. * info.el (info-tool-bar-map): Add labels. * cus-start.el (all): Add tool-bar-style and tool-bar-max-label-size. * cus-edit.el (custom-commands): Add labels for tool bar. (custom-buffer-create-internal, Custom-mode): Adjust for labels in custom-commands. * dynamic-setting.el: Renamed from font-setting.el.
author Jan D. <jan.h.d@swipnet.se>
date Tue, 20 Apr 2010 20:52:07 +0200
parents 150fd3d78f5a
children 7b45a10725ef
files lisp/ChangeLog lisp/cus-edit.el lisp/cus-start.el lisp/dynamic-setting.el lisp/font-setting.el lisp/info.el lisp/loadup.el lisp/tool-bar.el lisp/vc-dir.el src/ChangeLog src/Makefile.in src/dispextern.h src/gtkutil.c src/keyboard.c src/lisp.h src/xdisp.c src/xsettings.c src/xsettings.h src/xterm.c
diffstat 19 files changed, 683 insertions(+), 304 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Wed Apr 21 18:13:55 2010 +0200
+++ b/lisp/ChangeLog	Tue Apr 20 20:52:07 2010 +0200
@@ -1,3 +1,22 @@
+2010-04-21  Jan Djärv  <jan.h.d@swipnet.se>
+
+	* vc-dir.el (vc-dir-tool-bar-map): Add :label on some tool bar items.
+
+	* tool-bar.el (tool-bar-setup): Add :label on some tool bar items.
+
+	* loadup.el: Load dynamic-setting.el if feature dynamic-setting
+	is present.
+
+	* info.el (info-tool-bar-map): Add labels.
+
+	* cus-start.el (all): Add tool-bar-style and tool-bar-max-label-size.
+
+	* cus-edit.el (custom-commands): Add labels for tool bar.
+	(custom-buffer-create-internal, Custom-mode): Adjust for
+	labels in custom-commands.
+
+	* dynamic-setting.el: Renamed from font-setting.el.
+
 2010-04-21  John Wiegley  <jwiegley@gmail.com>
 
 	* ido.el (ido-init-completion-maps): For ido-switch-buffer, C-o
--- a/lisp/cus-edit.el	Wed Apr 21 18:13:55 2010 +0200
+++ b/lisp/cus-edit.el	Tue Apr 20 20:52:07 2010 +0200
@@ -739,25 +739,31 @@
 (defvar custom-commands
   '(("Set for current session" Custom-set t
      "Apply all settings in this buffer to the current session"
-     "index")
+     "index"
+     "Apply")
     ("Save for future sessions" Custom-save
      (or custom-file user-init-file)
      "Apply all settings in this buffer and save them for future Emacs sessions."
-     "save")
+     "save"
+     "Save")
     ("Undo edits" Custom-reset-current t
      "Restore all settings in this buffer to reflect their current values."
-     "refresh")
+     "refresh"
+     "Undo")
     ("Reset to saved" Custom-reset-saved t
      "Restore all settings in this buffer to their saved values (if any)."
-     "undo")
+     "undo"
+     "Reset")
     ("Erase customizations" Custom-reset-standard
      (or custom-file user-init-file)
      "Un-customize all settings in this buffer and save them with standard values."
-     "delete")
+     "delete"
+     "Uncustomize")
     ("Help for Customize" Custom-help t
      "Get help for using Customize."
-     "help")
-    ("Exit" Custom-buffer-done t "Exit Customize." "exit")))
+     "help"
+     "Help")
+    ("Exit" Custom-buffer-done t "Exit Customize." "exit" "Exit")))
 
 (defun Custom-help ()
   "Read the node on Easy Customization in the Emacs manual."
@@ -1616,7 +1622,7 @@
     (if custom-buffer-verbose-help
 	(widget-insert "
  Operate on all settings in this buffer:\n"))
-    (let ((button (lambda (tag action active help icon)
+    (let ((button (lambda (tag action active help icon label)
 		    (widget-insert " ")
 		    (if (eval active)
 			(widget-create 'push-button :tag tag
@@ -4680,7 +4686,8 @@
 	     (mapc
 	      (lambda (arg)
 		(tool-bar-local-item-from-menu
-		 (nth 1 arg) (nth 4 arg) map custom-mode-map))
+		 (nth 1 arg) (nth 4 arg) map custom-mode-map
+		 :label (nth 5 arg)))
 	      custom-commands)
 	     (setq custom-tool-bar-map map))))
   (make-local-variable 'custom-options)
--- a/lisp/cus-start.el	Wed Apr 21 18:13:55 2010 +0200
+++ b/lisp/cus-start.el	Tue Apr 20 20:52:07 2010 +0200
@@ -339,6 +339,15 @@
 		       (const :tag "Off (nil)" :value nil)
 		       (const :tag "Immediate" :value t)
 		       (number :tag "Delay by secs" :value 0.5)) "22.1")
+             (tool-bar-style
+	      frames (choice
+		      (const :tag "Images" :value image)
+		      (const :tag "Text" :value text)
+		      (const :tag "Both" :value both)
+		      (const :tag "Both-horiz" :value both-horiz)
+		      (const :tag "System default" :value nil)) "23.3")
+             (tool-bar-max-label-size frames integer "23.3")
+
 	     ;; xfaces.c
 	     (scalable-fonts-allowed display boolean "22.1")
 	     ;; xfns.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/dynamic-setting.el	Tue Apr 20 20:52:07 2010 +0200
@@ -0,0 +1,105 @@
+;;; dynamic-setting.el --- Support dynamic changes
+
+;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+;; Author: Jan Djärv <jan.h.d@swipnet.se>
+;; Maintainer: FSF
+;; Keywords: font, system-font, tool-bar-style
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This file provides the lisp part of the GConf and XSetting code in
+;; xsetting.c.  But it is nothing that prevents it from being used by
+;; other configuration schemes.
+
+;;; Code:
+
+;;; Customizable variables
+
+(declare-function font-get-system-font "xsettings.c" ())
+
+(defvar font-use-system-font)
+
+(defun font-setting-change-default-font (display-or-frame set-font)
+  "Change font and/or font settings for frames on display DISPLAY-OR-FRAME.
+If DISPLAY-OR-FRAME is a frame, the display is the one for that frame.
+
+If SET-FONT is non-nil, change the font for frames.  Otherwise re-apply the
+current form for the frame (i.e. hinting or somesuch changed)."
+
+  (let ((new-font (and (fboundp 'font-get-system-font)
+		       (font-get-system-font))))
+    (when new-font
+      ;; Be careful here: when set-face-attribute is called for the
+      ;; :font attribute, Emacs tries to guess the best matching font
+      ;; by examining the other face attributes (Bug#2476).
+
+      (clear-font-cache)
+      ;; Set for current frames. Only change font for those that have
+      ;; the old font now. If they don't have the old font, the user
+      ;; probably changed it.
+      (dolist (f (frames-on-display-list display-or-frame))
+	(if (display-graphic-p f)
+	    (let* ((frame-font
+		    (or (font-get (face-attribute 'default :font f
+						  'default) :user-spec)
+			(frame-parameter f 'font-parameter)))
+		   (font-to-set
+		    (if set-font new-font
+		      ;; else set font again, hinting etc. may have changed.
+		      frame-font)))
+	      (if font-to-set
+		  (progn
+		    (message "setting %s" font-to-set)
+		    (set-frame-parameter f 'font-parameter font-to-set)
+		    (set-face-attribute 'default f
+					:width 'normal
+					:weight 'normal
+					:slant 'normal
+					:font font-to-set))))))
+
+      ;; Set for future frames.
+      (set-face-attribute 'default t :font new-font)
+      (let ((spec (list (list t (face-attr-construct 'default)))))
+	(progn
+	  (put 'default 'customized-face spec)
+	  (custom-push-theme 'theme-face 'default 'user 'set spec)
+	  (put 'default 'face-modified nil))))))
+
+(defun dynamic-setting-handle-config-changed-event (event)
+  "Handle config-changed-event on the display in EVENT.
+Changes can be
+  The monospace font. If `font-use-system-font' is nil, the font
+    is not changed.
+  Xft parameters, like DPI and hinting.
+  The tool bar style."
+  (interactive "e")
+  (let ((type (nth 1 event))
+	(display-name (nth 2 event)))
+    (cond ((and (eq type 'monospace-font-name) font-use-system-font)
+	   (font-setting-change-default-font display-name t))
+
+	  ((eq type 'font-render)
+	   (font-setting-change-default-font display-name nil))
+
+	  ((eq type 'tool-bar-style) (force-mode-line-update t)))))
+
+(define-key special-event-map [config-changed-event]
+  'dynamic-setting-handle-config-changed-event)
+
+;; arch-tag: 3a57e78f-1cd6-48b6-ab75-98f160dcc017
--- a/lisp/font-setting.el	Wed Apr 21 18:13:55 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-;;; font-setting.el --- Support dynamic font changes
-
-;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
-
-;; Author: Jan Djärv <jan.h.d@swipnet.se>
-;; Maintainer: FSF
-;; Keywords: font, system-font
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file provides the lisp part of the GConf and XSetting code in
-;; xsetting.c.  But it is nothing that prevents it from being used by
-;; other configuration schemes.
-
-;;; Code:
-
-;;; Customizable variables
-
-(declare-function font-get-system-font "xsettings.c" ())
-
-(defvar font-use-system-font)
-
-(defun font-setting-change-default-font (display-or-frame set-font)
-  "Change font and/or font settings for frames on display DISPLAY-OR-FRAME.
-If DISPLAY-OR-FRAME is a frame, the display is the one for that frame.
-
-If SET-FONT is non-nil, change the font for frames.  Otherwise re-apply the
-current form for the frame (i.e. hinting or somesuch changed)."
-
-  (let ((new-font (and (fboundp 'font-get-system-font)
-		       (font-get-system-font))))
-    (when new-font
-      ;; Be careful here: when set-face-attribute is called for the
-      ;; :font attribute, Emacs tries to guess the best matching font
-      ;; by examining the other face attributes (Bug#2476).
-
-      (clear-font-cache)
-      ;; Set for current frames. Only change font for those that have
-      ;; the old font now. If they don't have the old font, the user
-      ;; probably changed it.
-      (dolist (f (frames-on-display-list display-or-frame))
-	(if (display-graphic-p f)
-	    (let* ((frame-font
-		    (or (font-get (face-attribute 'default :font f
-						  'default) :user-spec)
-			(frame-parameter f 'font-parameter)))
-		   (font-to-set
-		    (if set-font new-font
-		      ;; else set font again, hinting etc. may have changed.
-		      frame-font)))
-	      (if font-to-set
-		  (progn
-		    (message "setting %s" font-to-set)
-		    (set-frame-parameter f 'font-parameter font-to-set)
-		    (set-face-attribute 'default f
-					:width 'normal
-					:weight 'normal
-					:slant 'normal
-					:font font-to-set))))))
-
-      ;; Set for future frames.
-      (set-face-attribute 'default t :font new-font)
-      (let ((spec (list (list t (face-attr-construct 'default)))))
-	(progn
-	  (put 'default 'customized-face spec)
-	  (custom-push-theme 'theme-face 'default 'user 'set spec)
-	  (put 'default 'face-modified nil))))))
-
-(defun font-setting-handle-config-changed-event (event)
-  "Handle config-changed-event to change fonts on the display in EVENT.
-If `font-use-system-font' is nil, the font is not changed."
-  (interactive "e")
-  (let ((type (nth 1 event)) ;; font-name or font-render
-	(display-name (nth 2 event)))
-    (if (or (not (eq type 'font-name))
-	    font-use-system-font)
-	(font-setting-change-default-font display-name
-					  (eq type 'font-name)))))
-
-(if (or (featurep 'system-font-setting) (featurep 'font-render-setting))
-  (define-key special-event-map [config-changed-event]
-    'font-setting-handle-config-changed-event))
-
-(provide 'font-setting)
-
-;; arch-tag: 3a57e78f-1cd6-48b6-ab75-98f160dcc017
--- a/lisp/info.el	Wed Apr 21 18:13:55 2010 +0200
+++ b/lisp/info.el	Tue Apr 20 20:52:07 2010 +0200
@@ -3736,9 +3736,11 @@
 (defvar info-tool-bar-map
   (let ((map (make-sparse-keymap)))
     (tool-bar-local-item-from-menu 'Info-history-back "left-arrow" map Info-mode-map
-				   :rtl "right-arrow")
+				   :rtl "right-arrow"
+				   :label "Back")
     (tool-bar-local-item-from-menu 'Info-history-forward "right-arrow" map Info-mode-map
-				   :rtl "left-arrow")
+				   :rtl "left-arrow"
+				   :label "Forward")
     (tool-bar-local-item-from-menu 'Info-prev "prev-node" map Info-mode-map
 				   :rtl "next-node")
     (tool-bar-local-item-from-menu 'Info-next "next-node" map Info-mode-map
@@ -3746,7 +3748,8 @@
     (tool-bar-local-item-from-menu 'Info-up "up-node" map Info-mode-map)
     (tool-bar-local-item-from-menu 'Info-top-node "home" map Info-mode-map)
     (tool-bar-local-item-from-menu 'Info-goto-node "jump-to" map Info-mode-map)
-    (tool-bar-local-item-from-menu 'Info-index "index" map Info-mode-map)
+    (tool-bar-local-item-from-menu 'Info-index "index" map Info-mode-map
+				   :label "Index Search")
     (tool-bar-local-item-from-menu 'Info-search "search" map Info-mode-map)
     (tool-bar-local-item-from-menu 'Info-exit "exit" map Info-mode-map)
     map))
--- a/lisp/loadup.el	Wed Apr 21 18:13:55 2010 +0200
+++ b/lisp/loadup.el	Tue Apr 20 20:52:07 2010 +0200
@@ -203,8 +203,8 @@
       (load "dnd")
       (load "tool-bar")))
 
-(if (or (featurep 'system-font-setting) (featurep 'font-render-setting))
-    (load "font-setting"))
+(if (featurep 'dynamic-setting)
+    (load "dynamic-setting"))
 
 (if (featurep 'x)
     (progn
--- a/lisp/tool-bar.el	Wed Apr 21 18:13:55 2010 +0200
+++ b/lisp/tool-bar.el	Tue Apr 20 20:52:07 2010 +0200
@@ -267,7 +267,7 @@
   ;; People say it's bad to have EXIT on the tool bar, since users
   ;; might inadvertently click that button.
   ;;(tool-bar-add-item-from-menu 'save-buffers-kill-emacs "exit")
-  (tool-bar-add-item-from-menu 'find-file "new")
+  (tool-bar-add-item-from-menu 'find-file "new" nil :label "New File")
   (tool-bar-add-item-from-menu 'menu-find-file-existing "open")
   (tool-bar-add-item-from-menu 'dired "diropen")
   (tool-bar-add-item-from-menu 'kill-this-buffer "close")
@@ -294,14 +294,15 @@
 			       "paste" nil
 			       :visible '(not (eq 'special (get major-mode
 								'mode-class))))
-  (tool-bar-add-item-from-menu 'nonincremental-search-forward "search")
+  (tool-bar-add-item-from-menu 'nonincremental-search-forward "search"
+			       nil :label "Search")
   ;;(tool-bar-add-item-from-menu 'ispell-buffer "spell")
 
   ;; There's no icon appropriate for News and we need a command rather
   ;; than a lambda for Read Mail.
   ;;(tool-bar-add-item-from-menu 'compose-mail "mail/compose")
 
-  (tool-bar-add-item-from-menu 'print-buffer "print")
+  (tool-bar-add-item-from-menu 'print-buffer "print" nil :label "Print")
 
   ;; tool-bar-add-item-from-menu itself operates on
   ;; (default-value 'tool-bar-map), but when we don't use that function,
--- a/lisp/vc-dir.el	Wed Apr 21 18:13:55 2010 +0200
+++ b/lisp/vc-dir.el	Tue Apr 20 20:52:07 2010 +0200
@@ -301,7 +301,8 @@
 				   map vc-dir-mode-map)
     (tool-bar-local-item "bookmark_add"
 			 'vc-dir-toggle-mark 'vc-dir-toggle-mark map
-			 :help "Toggle mark on current item")
+			 :help "Toggle mark on current item"
+			 :label "Toggle Mark")
     (tool-bar-local-item-from-menu 'vc-dir-previous-line "left-arrow"
 				   map vc-dir-mode-map
 				   :rtl "right-arrow")
@@ -313,11 +314,14 @@
     (tool-bar-local-item-from-menu 'revert-buffer "refresh"
 				   map vc-dir-mode-map)
     (tool-bar-local-item-from-menu 'nonincremental-search-forward
-				   "search" map)
+				   "search" map nil
+				   :label "Search")
     (tool-bar-local-item-from-menu 'vc-dir-query-replace-regexp
-				   "search-replace" map vc-dir-mode-map)
+				   "search-replace" map vc-dir-mode-map
+				   :label "Replace")
     (tool-bar-local-item-from-menu 'vc-dir-kill-dir-status-process "cancel"
-				   map vc-dir-mode-map)
+				   map vc-dir-mode-map
+				   :label "Cancel")
     (tool-bar-local-item-from-menu 'quit-window "exit"
 				   map vc-dir-mode-map)
     map))
--- a/src/ChangeLog	Wed Apr 21 18:13:55 2010 +0200
+++ b/src/ChangeLog	Tue Apr 20 20:52:07 2010 +0200
@@ -1,3 +1,61 @@
+2010-04-21  Jan Djärv  <jan.h.d@swipnet.se>
+
+	* xsettings.c: Qmonospace_font_name, Qtool_bar_style and
+	current_tool_bar_style are new.
+	(store_config_changed_event): Rename from store_font_changed_event.
+	(XSETTINGS_TOOL_BAR_STYLE): New define.
+	(SEEN_FONT, SEEN_TB_STYLE): New enum values.
+	(struct xsettings): Add font and tb_style, set xft stuff inside #ifdef
+	HAVE_XFT.
+	(something_changedCB): store_font_changed_event is now
+	store_config_changed_event
+	(parse_settings): Rename from parse_xft_settings.  Read
+	non-xft xsettings outside #ifdef HAVE_XFT.
+	(read_settings): Renamed from read_xft_settings.
+	(apply_xft_settings): Take current settings as parameter.  Do not
+	call read_(xft)_settings.
+	(read_and_apply_settings): New function.
+	(xft_settings_event): Do non-xft stuff out of HAVE_XFT.  Call
+	read_and_apply_settings if there are settings to be read.
+	(init_xsettings): Renamed from init_xfd_settings.
+	Call read_and_apply_settings unconditionally.
+	(xsettings_initialize): Call init_xsettings.
+	(Ftool_bar_get_system_style): New function.
+	(syms_of_xsettings): Define Qmonospace_font_name and
+	Qtool_bar_style.  Initialize current_tool_bar_style to nil.
+	defsubr Stool_bar_get_system_style. Fprovide on
+	dynamic-setting.
+
+	* xsettings.h (Ftool_bar_get_system_style): Declare.
+
+	* xdisp.c: Vtool_bar_style, tool_bar_max_label_size,
+	Qtext, Qboth, Qboth_horiz are new.
+	(syms_of_xdisp): Intern Qtext, Qboth, Qboth_horiz, DEFVAR
+	Vtool_bar_style, tool_bar_max_label_size.
+
+	* lisp.h: Extern declare Qtext, Qboth, Qboth_horiz.
+
+	* keyboard.c: QClabel is new.
+	(parse_tool_bar_item): Take out QClabel from tool bar items.
+	Try to construct a label if ther is no QClabel.
+	(syms_of_keyboard): Intern :label as QClabel.
+
+	* dispextern.h (tool_bar_item_idx): TOOL_BAR_ITEM_LABEL is new.
+	(Vtool_bar_style, tool_bar_max_label_size, DEFAULT_TOOL_BAR_LABEL_SIZE):
+	New.
+
+	* Makefile.in (SOME_MACHINE_LISP): font-setting.el renamed to
+	dynamic-setting.el.
+
+	* gtkutil.c (xg_tool_bar_menu_proxy): Handle label in tool bar item.
+	(xg_make_tool_item, xg_show_toolbar_item): New function.
+	(update_frame_tool_bar): Take label from TOOL_BAR_ITEM_LABEL.
+	Call xg_make_tool_item to make a tool bar item.
+	Call xg_show_toolbar_item.  Use wtoolbar instead of x->toolbar_widget.
+
+	* xterm.c (x_draw_image_relief): Take Vtool_bar_button_margin
+	into account for toolbars.
+
 2010-04-21  Jan Djärv  <jan.h.d@swipnet.se>
 
 	* data.c (make_blv): Declarations before code (Bug#5993).
--- a/src/Makefile.in	Wed Apr 21 18:13:55 2010 +0200
+++ b/src/Makefile.in	Tue Apr 20 20:52:07 2010 +0200
@@ -566,7 +566,7 @@
  ${lispsource}international/fontset.elc ${lispsource}dnd.elc \
  ${lispsource}tool-bar.elc ${lispsource}mwheel.elc ${lispsource}x-dnd.elc \
  ${lispsource}term/common-win.elc ${lispsource}term/x-win.elc \
- ${lispsource}font-setting.elc
+ ${lispsource}dynamic-setting.elc
 #else
 #define WINDOW_SUPPORT ${lispsource}fringe.elc ${lispsource}image.elc \
  ${lispsource}international/fontset.elc ${lispsource}dnd.elc \
@@ -801,7 +801,7 @@
   ../lisp/tooltip.elc ../lisp/image.elc \
   ../lisp/fringe.elc ../lisp/dnd.elc \
   ../lisp/mwheel.elc ../lisp/tool-bar.elc \
-  ../lisp/x-dnd.elc ../lisp/font-setting.elc \
+  ../lisp/x-dnd.elc ../lisp/dynamic-setting.elc \
   ../lisp/international/ccl.elc \
   ../lisp/international/fontset.elc \
   ../lisp/mouse.elc \
--- a/src/dispextern.h	Wed Apr 21 18:13:55 2010 +0200
+++ b/src/dispextern.h	Tue Apr 20 20:52:07 2010 +0200
@@ -2793,6 +2793,9 @@
   /* Icon file name of right to left image when an RTL locale is used.  */
   TOOL_BAR_ITEM_RTL_IMAGE,
 
+  /* Label to show when text labels are enabled.  */
+  TOOL_BAR_ITEM_LABEL,
+
   /* Sentinel = number of slots in tool_bar_items occupied by one
      tool-bar item.  */
   TOOL_BAR_ITEM_NSLOTS
@@ -2814,6 +2817,15 @@
 
 extern Lisp_Object Vtool_bar_button_margin;
 
+/* Tool bar style */
+
+extern Lisp_Object Vtool_bar_style;
+
+/* Maximum number of characters a label can have to be shown.  */
+
+extern EMACS_INT tool_bar_max_label_size;
+#define DEFAULT_TOOL_BAR_LABEL_SIZE 14
+
 /* Thickness of relief to draw around tool-bar buttons.  */
 
 extern EMACS_INT tool_bar_button_relief;
--- a/src/gtkutil.c	Wed Apr 21 18:13:55 2010 +0200
+++ b/src/gtkutil.c	Tue Apr 20 20:52:07 2010 +0200
@@ -3522,7 +3522,16 @@
 {
   GtkWidget *weventbox = gtk_bin_get_child (GTK_BIN (toolitem));
   GtkButton *wbutton = GTK_BUTTON (gtk_bin_get_child (GTK_BIN (weventbox)));
-  GtkWidget *wmenuitem = gtk_image_menu_item_new_with_label ("");
+  GtkBox *vb = GTK_BOX (gtk_bin_get_child (GTK_BIN (wbutton)));
+  GtkBoxChild *c1 = (GtkBoxChild *) vb->children->data;
+  GtkBoxChild *c2 = (GtkBoxChild *) vb->children->next->data;
+  GtkImage *wimage = GTK_IS_IMAGE (c1->widget)
+    ? GTK_IMAGE (c1->widget) : GTK_IMAGE (c2->widget);
+  GtkLabel *wlbl = GTK_IS_LABEL (c1->widget)
+    ? GTK_LABEL (c1->widget) : GTK_LABEL (c2->widget);
+  GtkWidget *wmenuitem = gtk_image_menu_item_new_with_label
+    (gtk_label_get_text (wlbl));
+
   GtkWidget *wmenuimage;
 
   if (gtk_button_get_use_stock (wbutton))
@@ -3530,7 +3539,6 @@
                                            GTK_ICON_SIZE_MENU);
   else
     {
-      GtkImage *wimage = GTK_IMAGE (gtk_bin_get_child (GTK_BIN (wbutton)));
       GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (wbutton));
       GtkImageType store_type = gtk_image_get_storage_type (wimage);
 
@@ -3834,6 +3842,132 @@
   return image;
 }
 
+static GtkToolItem *
+xg_make_tool_item (FRAME_PTR f,
+                   GtkWidget *wimage,
+                   GtkWidget **wbutton,
+                   char *label,
+                   int i)
+{
+  GtkToolItem *ti = gtk_tool_item_new ();
+  GtkWidget *vb = EQ (Vtool_bar_style, Qboth_horiz)
+    ? gtk_hbox_new (FALSE, 0) : gtk_vbox_new (FALSE, 0);
+  GtkWidget *wb = gtk_button_new ();
+  GtkWidget *weventbox = gtk_event_box_new ();
+
+  if (wimage)
+    gtk_box_pack_start_defaults (GTK_BOX (vb), wimage);
+
+  gtk_box_pack_start_defaults (GTK_BOX (vb), gtk_label_new (label));
+  gtk_button_set_focus_on_click (GTK_BUTTON (wb), FALSE);
+  gtk_button_set_relief (GTK_BUTTON (wb), GTK_RELIEF_NONE);
+  gtk_container_add (GTK_CONTAINER (wb), vb);
+  gtk_container_add (GTK_CONTAINER (weventbox), wb);
+  gtk_container_add (GTK_CONTAINER (ti), weventbox);
+
+  if (wimage)
+    {
+      /* The EMACS_INT cast avoids a warning. */
+      g_signal_connect (G_OBJECT (ti), "create-menu-proxy",
+                        G_CALLBACK (xg_tool_bar_menu_proxy),
+                        (gpointer) (EMACS_INT) i);
+
+      g_signal_connect (G_OBJECT (wb), "clicked",
+                        G_CALLBACK (xg_tool_bar_callback),
+                        (gpointer) (EMACS_INT) i);
+
+      gtk_widget_show_all (GTK_WIDGET (ti));
+
+      g_object_set_data (G_OBJECT (weventbox), XG_FRAME_DATA, (gpointer)f);
+
+      /* Catch expose events to overcome an annoying redraw bug, see
+         comment for xg_tool_bar_item_expose_callback.  */
+      g_signal_connect (G_OBJECT (ti),
+                        "expose-event",
+                        G_CALLBACK (xg_tool_bar_item_expose_callback),
+                        0);
+
+      gtk_tool_item_set_homogeneous (ti, FALSE);
+
+      /* Callback to save modifyer mask (Shift/Control, etc).  GTK makes
+         no distinction based on modifiers in the activate callback,
+         so we have to do it ourselves.  */
+      g_signal_connect (wb, "button-release-event",
+                        G_CALLBACK (xg_tool_bar_button_cb),
+                        NULL);
+
+      g_object_set_data (G_OBJECT (wb), XG_FRAME_DATA, (gpointer)f);
+          
+      /* Use enter/leave notify to show help.  We use the events
+         rather than the GtkButton specific signals "enter" and
+         "leave", so we can have only one callback.  The event
+         will tell us what kind of event it is.  */
+      /* The EMACS_INT cast avoids a warning. */
+      g_signal_connect (G_OBJECT (weventbox),
+                        "enter-notify-event",
+                        G_CALLBACK (xg_tool_bar_help_callback),
+                        (gpointer) (EMACS_INT) i);
+      g_signal_connect (G_OBJECT (weventbox),
+                        "leave-notify-event",
+                        G_CALLBACK (xg_tool_bar_help_callback),
+                        (gpointer) (EMACS_INT) i);
+    }
+  
+  if (wbutton) *wbutton = wb;
+
+  return ti;
+}
+
+static void
+xg_show_toolbar_item (GtkToolItem *ti)
+{
+  Lisp_Object style = Ftool_bar_get_system_style ();
+
+  int show_label = EQ (style, Qboth)
+    || EQ (style, Qboth_horiz) || EQ (style, Qtext);
+  int show_image = ! EQ (style, Qtext);
+  int horiz = EQ (style, Qboth_horiz);
+
+  GtkWidget *weventbox = gtk_bin_get_child (GTK_BIN (ti));
+  GtkWidget *wbutton = gtk_bin_get_child (GTK_BIN (weventbox));
+  GtkBox *vb = GTK_BOX (gtk_bin_get_child (GTK_BIN (wbutton)));
+  GtkBoxChild *c1 = (GtkBoxChild *) vb->children->data;
+  GtkBoxChild *c2 = (GtkBoxChild *) vb->children->next->data;
+  GtkWidget *wimage = GTK_IS_IMAGE (c1->widget)
+    ? c1->widget : c2->widget;
+  GtkWidget *wlbl = GTK_IS_LABEL (c1->widget)
+    ? c1->widget : c2->widget;
+  GtkWidget *new_box = NULL;
+
+  if (GTK_IS_VBOX (vb) && horiz)
+    new_box = gtk_hbox_new (FALSE, 0);
+  else if (GTK_IS_HBOX (vb) && !horiz && show_label && show_image)
+    new_box = gtk_vbox_new (FALSE, 0);
+  if (new_box)
+    {
+      gtk_widget_ref (wimage);
+      gtk_widget_ref (wlbl);
+      gtk_container_remove (GTK_CONTAINER (vb), wimage);
+      gtk_container_remove (GTK_CONTAINER (vb), wlbl);
+      gtk_widget_destroy (GTK_WIDGET (vb));
+      gtk_box_pack_start_defaults (GTK_BOX (new_box), wimage);
+      gtk_box_pack_start_defaults (GTK_BOX (new_box), wlbl);
+      gtk_container_add (GTK_CONTAINER (wbutton), new_box);
+      gtk_widget_unref (wimage);
+      gtk_widget_unref (wlbl);
+      vb = GTK_BOX (new_box);
+    }
+
+  if (show_label) gtk_widget_show (wlbl);
+  else gtk_widget_hide (wlbl);
+  if (show_image) gtk_widget_show (wimage);
+  else gtk_widget_hide (wimage);
+  gtk_widget_show (GTK_WIDGET (vb));
+  gtk_widget_show (GTK_WIDGET (wbutton));
+  gtk_widget_show (GTK_WIDGET (ti));
+}
+
+
 /* Update the tool bar for frame F.  Add new buttons and remove old.  */
 
 extern Lisp_Object Qx_gtk_map_stock;
@@ -3885,8 +4019,8 @@
 
   wtoolbar = GTK_TOOLBAR (x->toolbar_widget);
   gtk_widget_size_request (GTK_WIDGET (wtoolbar), &old_req);
-  dir = gtk_widget_get_direction (x->toolbar_widget);
-
+  dir = gtk_widget_get_direction (GTK_WIDGET (wtoolbar));
+  
   for (i = 0; i < f->n_tool_bar_items; ++i)
     {
       int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
@@ -3904,8 +4038,10 @@
       GtkWidget *wbutton = NULL;
       GtkWidget *weventbox;
       Lisp_Object specified_file;
-
-      ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (x->toolbar_widget), i);
+      Lisp_Object lbl = PROP (TOOL_BAR_ITEM_LABEL);
+      char *label = SSDATA (PROP (TOOL_BAR_ITEM_LABEL));
+      
+      ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (wtoolbar), i);
 
       if (ti)
         {
@@ -3913,6 +4049,7 @@
           wbutton = gtk_bin_get_child (GTK_BIN (weventbox));
         }
 
+
       image = PROP (TOOL_BAR_ITEM_IMAGES);
 
       /* Ignore invalid image specifications.  */
@@ -3944,7 +4081,7 @@
                 icon_size = gtk_toolbar_get_icon_size (wtoolbar);
             }
           else if (gtk_stock_lookup (SSDATA (stock), &stock_item))
-              icon_size = gtk_toolbar_get_icon_size (wtoolbar);
+            icon_size = gtk_toolbar_get_icon_size (wtoolbar);
           else
             {
               stock = Qnil;
@@ -3988,22 +4125,15 @@
 
           if (img->load_failed_p || img->pixmap == None)
             {
-                if (ti)
-                    gtk_widget_hide_all (GTK_WIDGET (ti));
-                else
+              if (ti)
+                gtk_widget_hide_all (GTK_WIDGET (ti));
+              else
                 {
-                    /* Insert an empty (non-image) button */
-                    weventbox = gtk_event_box_new ();
-                    wbutton = gtk_button_new ();
-                    gtk_button_set_focus_on_click (GTK_BUTTON (wbutton), FALSE);
-                    gtk_button_set_relief (GTK_BUTTON (wbutton),
-                                           GTK_RELIEF_NONE);
-                    gtk_container_add (GTK_CONTAINER (weventbox), wbutton);
-                    ti = gtk_tool_item_new ();
-                    gtk_container_add (GTK_CONTAINER (ti), weventbox);
-                    gtk_toolbar_insert (GTK_TOOLBAR (x->toolbar_widget), ti, -1);
+                  /* Insert an empty (non-image) button */
+                  ti = xg_make_tool_item (f, NULL, NULL, "", i);
+                  gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, -1);
                 }
-                continue;
+              continue;
             }
         }
 
@@ -4034,73 +4164,27 @@
             }
 
           gtk_misc_set_padding (GTK_MISC (w), hmargin, vmargin);
-          wbutton = gtk_button_new ();
-          gtk_button_set_focus_on_click (GTK_BUTTON (wbutton), FALSE);
-          gtk_button_set_relief (GTK_BUTTON (wbutton), GTK_RELIEF_NONE);
-          gtk_container_add (GTK_CONTAINER (wbutton), w);
-          weventbox = gtk_event_box_new ();
-          gtk_container_add (GTK_CONTAINER (weventbox), wbutton);
-          ti = gtk_tool_item_new ();
-          gtk_container_add (GTK_CONTAINER (ti), weventbox);
-          gtk_toolbar_insert (GTK_TOOLBAR (x->toolbar_widget), ti, -1);
-
-
-          /* The EMACS_INT cast avoids a warning. */
-          g_signal_connect (G_OBJECT (ti), "create-menu-proxy",
-                            G_CALLBACK (xg_tool_bar_menu_proxy),
-                            (gpointer) (EMACS_INT) i);
-
-          g_signal_connect (G_OBJECT (wbutton), "clicked",
-                            G_CALLBACK (xg_tool_bar_callback),
-                            (gpointer) (EMACS_INT) i);
-
-          gtk_widget_show_all (GTK_WIDGET (ti));
-
-
-          g_object_set_data (G_OBJECT (weventbox), XG_FRAME_DATA, (gpointer)f);
-
-          /* Catch expose events to overcome an annoying redraw bug, see
-             comment for xg_tool_bar_item_expose_callback.  */
-          g_signal_connect (G_OBJECT (ti),
-                            "expose-event",
-                            G_CALLBACK (xg_tool_bar_item_expose_callback),
-                            0);
-
+          ti = xg_make_tool_item (f, w, &wbutton, label, i);
+          gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, -1);
           gtk_widget_set_sensitive (wbutton, enabled_p);
-          gtk_tool_item_set_homogeneous (ti, FALSE);
-
-          /* Callback to save modifyer mask (Shift/Control, etc).  GTK makes
-             no distinction based on modifiers in the activate callback,
-             so we have to do it ourselves.  */
-          g_signal_connect (wbutton, "button-release-event",
-                            G_CALLBACK (xg_tool_bar_button_cb),
-                            NULL);
-
-          g_object_set_data (G_OBJECT (wbutton), XG_FRAME_DATA, (gpointer)f);
-          
-          /* Use enter/leave notify to show help.  We use the events
-             rather than the GtkButton specific signals "enter" and
-             "leave", so we can have only one callback.  The event
-             will tell us what kind of event it is.  */
-          /* The EMACS_INT cast avoids a warning. */
-          g_signal_connect (G_OBJECT (weventbox),
-                            "enter-notify-event",
-                            G_CALLBACK (xg_tool_bar_help_callback),
-                            (gpointer) (EMACS_INT) i);
-          g_signal_connect (G_OBJECT (weventbox),
-                            "leave-notify-event",
-                            G_CALLBACK (xg_tool_bar_help_callback),
-                            (gpointer) (EMACS_INT) i);
         }
       else
         {
-          GtkWidget *wimage = gtk_bin_get_child (GTK_BIN (wbutton));
+          GtkBox *vb = GTK_BOX (gtk_bin_get_child (GTK_BIN (wbutton)));
+          GtkBoxChild *c1 = (GtkBoxChild *) vb->children->data;
+          GtkBoxChild *c2 = (GtkBoxChild *) vb->children->next->data;
+          GtkWidget *wimage = GTK_IS_IMAGE (c1->widget)
+            ? c1->widget : c2->widget;
+          GtkWidget *wlbl = GTK_IS_LABEL (c1->widget)
+            ? c1->widget : c2->widget;
+
           Pixmap old_img = (Pixmap)g_object_get_data (G_OBJECT (wimage),
                                                       XG_TOOL_BAR_IMAGE_DATA);
           gpointer old_stock_name = g_object_get_data (G_OBJECT (wimage),
                                                        XG_TOOL_BAR_STOCK_NAME);
           gpointer old_icon_name = g_object_get_data (G_OBJECT (wimage),
                                                       XG_TOOL_BAR_ICON_NAME);
+          gtk_label_set_text (GTK_LABEL (wlbl), label);
           if (stock_name &&
               (! old_stock_name || strcmp (old_stock_name, stock_name) != 0))
             {
@@ -4111,7 +4195,8 @@
                                       (GDestroyNotify) xfree);
               g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_IMAGE_DATA,
                                  NULL);
-              g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_ICON_NAME, NULL);
+              g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_ICON_NAME,
+                                 NULL);
             }
           else if (icon_name &&
                    (! old_icon_name || strcmp (old_icon_name, icon_name) != 0))
@@ -4134,14 +4219,15 @@
 
               g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_STOCK_NAME,
                                  NULL);
-              g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_ICON_NAME, NULL);
+              g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_ICON_NAME,
+                                 NULL);
             }
 
           gtk_misc_set_padding (GTK_MISC (wimage), hmargin, vmargin);
 
           gtk_widget_set_sensitive (wbutton, enabled_p);
-          gtk_widget_show_all (GTK_WIDGET (ti));
-       }
+        }
+      xg_show_toolbar_item (ti);
 
 #undef PROP
     }
@@ -4150,16 +4236,16 @@
      can be reused later on.  */
   do
     {
-      ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (x->toolbar_widget), i++);
+      ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (wtoolbar), i++);
       if (ti) gtk_widget_hide_all (GTK_WIDGET (ti));
     } while (ti != NULL);
 
   new_req.height = 0;
   if (pack_tool_bar && f->n_tool_bar_items != 0)
-      xg_pack_tool_bar (f);
+    xg_pack_tool_bar (f);
   
 
-  gtk_widget_size_request (GTK_WIDGET (x->toolbar_widget), &new_req);
+  gtk_widget_size_request (GTK_WIDGET (wtoolbar), &new_req);
   if (old_req.height != new_req.height
       && ! FRAME_X_OUTPUT (f)->toolbar_detached)
     {
@@ -4203,7 +4289,7 @@
 
 /***********************************************************************
                       Initializing
- ***********************************************************************/
+***********************************************************************/
 void
 xg_initialize ()
 {
--- a/src/keyboard.c	Wed Apr 21 18:13:55 2010 +0200
+++ b/src/keyboard.c	Tue Apr 20 20:52:07 2010 +0200
@@ -496,7 +496,7 @@
 /* menu item parts */
 Lisp_Object Qmenu_enable;
 Lisp_Object QCenable, QCvisible, QChelp, QCfilter, QCkeys, QCkey_sequence;
-Lisp_Object QCbutton, QCtoggle, QCradio;
+Lisp_Object QCbutton, QCtoggle, QCradio, QClabel;
 extern Lisp_Object Qmenu_item;
 
 /* An event header symbol HEAD may have a property named
@@ -8248,7 +8248,11 @@
 
    - `:help HELP-STRING'.
 
-   Gives a help string to display for the tool bar item.  */
+   Gives a help string to display for the tool bar item.
+
+   - `:label LABEL-STRING'.
+
+   A text label to show with the tool bar button if labels are enabled.  */
 
 static int
 parse_tool_bar_item (key, item)
@@ -8259,7 +8263,7 @@
 
   Lisp_Object filter = Qnil;
   Lisp_Object caption;
-  int i;
+  int i, have_label = 0;
 
   /* Defininition looks like `(menu-item CAPTION BINDING PROPS...)'.
      Rule out items that aren't lists, don't start with
@@ -8337,6 +8341,12 @@
       else if (EQ (key, QChelp))
 	/* `:help HELP-STRING'.  */
 	PROP (TOOL_BAR_ITEM_HELP) = value;
+      else if (EQ (key, QClabel))
+        {
+          /* `:label LABEL-STRING'.  */
+          PROP (TOOL_BAR_ITEM_LABEL) = value;
+          have_label = 1;
+        }
       else if (EQ (key, QCfilter))
 	/* ':filter FORM'.  */
 	filter = value;
@@ -8364,6 +8374,49 @@
 	PROP (TOOL_BAR_ITEM_RTL_IMAGE) = value;
     }
 
+
+  if (!have_label)
+    {
+      /* Try to make one from caption and key.  */
+      Lisp_Object key = PROP (TOOL_BAR_ITEM_KEY);
+      Lisp_Object capt = PROP (TOOL_BAR_ITEM_CAPTION);
+      char *label = SYMBOLP (key) ? (char *) SDATA (SYMBOL_NAME (key)) : "";
+      char *caption = STRINGP (capt) ? (char *) SDATA (capt) : "";
+      char buf[64];
+      EMACS_INT max_lbl = 2*tool_bar_max_label_size;
+      Lisp_Object new_lbl;
+
+      if (strlen (caption) < max_lbl && caption[0] != '\0') 
+        {
+          strcpy (buf, caption);
+          while (buf[0] != '\0' &&  buf[strlen (buf) -1] == '.')
+            buf[strlen (buf)-1] = '\0';
+          if (strlen (buf) <= max_lbl)
+            caption = buf;
+        }
+
+      if (strlen (caption) <= max_lbl)
+        label = caption;
+
+      if (strlen (label) <= max_lbl && label[0] != '\0') 
+        {
+          int i;
+          if (label != buf) strcpy (buf, label);
+
+          for (i = 0; i < strlen (buf); ++i) 
+            {
+              if (buf[i] == '-') buf[i] = ' ';
+            }
+          label = buf;
+      
+        }
+      else label = "";
+
+      new_lbl = Fupcase_initials (make_string (label, strlen (label)));
+      if (SCHARS (new_lbl) <= tool_bar_max_label_size)
+        PROP (TOOL_BAR_ITEM_LABEL) = new_lbl;
+    }
+
   /* If got a filter apply it on binding.  */
   if (!NILP (filter))
     PROP (TOOL_BAR_ITEM_BINDING)
@@ -11699,6 +11752,8 @@
   staticpro (&QCtoggle);
   QCradio = intern_c_string (":radio");
   staticpro (&QCradio);
+  QClabel = intern_c_string (":label");
+  staticpro (&QClabel);
 
   Qmode_line = intern_c_string ("mode-line");
   staticpro (&Qmode_line);
--- a/src/lisp.h	Wed Apr 21 18:13:55 2010 +0200
+++ b/src/lisp.h	Tue Apr 20 20:52:07 2010 +0200
@@ -2635,7 +2635,7 @@
 extern Lisp_Object Qinhibit_redisplay, Qdisplay;
 extern Lisp_Object Qinhibit_eval_during_redisplay;
 extern Lisp_Object Qmessage_truncate_lines;
-extern Lisp_Object Qimage;
+extern Lisp_Object Qimage, Qtext, Qboth, Qboth_horiz;
 extern Lisp_Object Vmessage_log_max;
 extern int message_enable_multibyte;
 extern Lisp_Object echo_area_buffer[2];
--- a/src/xdisp.c	Wed Apr 21 18:13:55 2010 +0200
+++ b/src/xdisp.c	Tue Apr 20 20:52:07 2010 +0200
@@ -357,6 +357,14 @@
 
 Lisp_Object Vauto_resize_tool_bars;
 
+/* Type of tool bar.  Can be symbols image, text, both or both-hroiz.  */
+
+Lisp_Object Vtool_bar_style;
+
+/* Maximum number of characters a label can have to be shown.  */
+
+EMACS_INT tool_bar_max_label_size;
+
 /* Non-zero means draw block and hollow cursor as wide as the glyph
    under it.  For example, if a block cursor is over a tab, it will be
    drawn as wide as that tab on the display.  */
@@ -442,7 +450,7 @@
 Lisp_Object Qnobreak_space;
 
 /* The symbol `image' which is the car of the lists used to represent
-   images in Lisp.  */
+   images in Lisp.  Also a tool bar style.  */
 
 Lisp_Object Qimage;
 
@@ -450,6 +458,9 @@
 Lisp_Object QCmap, QCpointer;
 Lisp_Object Qrect, Qcircle, Qpoly;
 
+/* Tool bar styles */
+Lisp_Object Qtext, Qboth, Qboth_horiz;
+
 /* Non-zero means print newline to stdout before next mini-buffer
    message.  */
 
@@ -25781,6 +25792,12 @@
   staticpro (&Qnobreak_space);
   Qimage = intern_c_string ("image");
   staticpro (&Qimage);
+  Qtext = intern_c_string ("text");
+  staticpro (&Qtext);
+  Qboth = intern_c_string ("both");
+  staticpro (&Qboth);
+  Qboth_horiz = intern_c_string ("both-horiz");
+  staticpro (&Qboth_horiz);
   QCmap = intern_c_string (":map");
   staticpro (&QCmap);
   QCpointer = intern_c_string (":pointer");
@@ -26121,6 +26138,22 @@
     doc: /* *Relief thickness of tool-bar buttons.  */);
   tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
 
+  DEFVAR_LISP ("tool-bar-style", &Vtool_bar_style,
+    doc: /* *Tool bar style to use.
+It can be one of
+ image      - show images only
+ text       - show text only
+ both       - show both, text under image
+ both-horiz - show text to the right of the image
+ any other  - use system default or image if no system default.  */);
+  Vtool_bar_style = Qnil;
+
+  DEFVAR_INT ("tool-bar-max-label-size", &tool_bar_max_label_size,
+    doc: /* *Maximum number of characters a label can have to be shown.
+The tool bar style must also show labels for this to have any effect, see
+`tool-bar-style'.  */);
+  tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
+
   DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
     doc: /* List of functions to call to fontify regions of text.
 Each function is called with one argument POS.  Functions must
--- a/src/xsettings.c	Wed Apr 21 18:13:55 2010 +0200
+++ b/src/xsettings.c	Tue Apr 20 20:52:07 2010 +0200
@@ -41,10 +41,11 @@
 static char *current_mono_font;
 static char *current_font;
 static struct x_display_info *first_dpyinfo;
-static Lisp_Object Qfont_name, Qfont_render;
+static Lisp_Object Qmonospace_font_name, Qfont_name, Qfont_render,
+  Qtool_bar_style;
 static int use_system_font;
 static Lisp_Object Vxft_settings;
-
+static Lisp_Object current_tool_bar_style;
 
 #ifdef HAVE_GCONF
 static GConfClient *gconf_client;
@@ -52,7 +53,7 @@
 
 
 static void
-store_font_changed_event (arg, display_name)
+store_config_changed_event (arg, display_name)
      Lisp_Object arg;
      Lisp_Object display_name;
 {
@@ -64,13 +65,38 @@
   kbd_buffer_store_event (&event);
 }
 
-#define XSETTINGS_FONT_NAME  "Gtk/FontName"
+#define XSETTINGS_FONT_NAME       "Gtk/FontName"
+#define XSETTINGS_TOOL_BAR_STYLE  "Gtk/ToolbarStyle"
 
 #ifdef HAVE_GCONF
 
 #define SYSTEM_MONO_FONT     "/desktop/gnome/interface/monospace_font_name"
 #define SYSTEM_FONT          "/desktop/gnome/interface/font_name"
 
+enum {
+  SEEN_AA         = 0x01,
+  SEEN_HINTING    = 0x02,
+  SEEN_RGBA       = 0x04,
+  SEEN_LCDFILTER  = 0x08,
+  SEEN_HINTSTYLE  = 0x10,
+  SEEN_DPI        = 0x20,
+  SEEN_FONT       = 0x40,
+  SEEN_TB_STYLE   = 0x80,
+};
+struct xsettings 
+{
+#ifdef HAVE_XFT
+  FcBool aa, hinting;
+  int rgba, lcdfilter, hintstyle;
+  double dpi;
+#endif
+
+  char *font;
+  char *tb_style;
+
+  unsigned seen;
+};
+
 /* Callback called when something changed in GConf that we care about,
    that is SYSTEM_MONO_FONT.  */
 
@@ -105,8 +131,8 @@
         found = dpyinfo == first_dpyinfo;
 
       if (found && use_system_font)
-        store_font_changed_event (Qfont_name,
-                                  XCAR (first_dpyinfo->name_list_element));
+        store_config_changed_event (Qmonospace_font_name,
+                                    XCAR (first_dpyinfo->name_list_element));
     }
 }
 #endif /* HAVE_GCONF */
@@ -124,6 +150,8 @@
 #define FC_LCD_FILTER "lcdfilter"
 #endif
 
+#endif /* HAVE_XFT */
+
 /* Find the window that contains the XSETTINGS property values.  */
 
 static void
@@ -144,23 +172,6 @@
   XUngrabServer (dpy);
 }
 
-enum {
-  SEEN_AA         = 0x01,
-  SEEN_HINTING    = 0x02,
-  SEEN_RGBA       = 0x04,
-  SEEN_LCDFILTER  = 0x08,
-  SEEN_HINTSTYLE  = 0x10,
-  SEEN_DPI        = 0x20,
-};
-struct xsettings 
-{
-  FcBool aa, hinting;
-  int rgba, lcdfilter, hintstyle;
-  double dpi;
-
-  unsigned seen;
-};
-
 #define SWAP32(nr) (((nr) << 24) | (((nr) << 8) & 0xff0000)     \
                     | (((nr) >> 8) & 0xff00) | ((nr) >> 24))
 #define SWAP16(nr) (((nr) << 8) | ((nr) >> 8))
@@ -217,7 +228,7 @@
 */
 
 static int
-parse_xft_settings (prop, bytes, settings)
+parse_settings (prop, bytes, settings)
      unsigned char *prop;
      unsigned long bytes;
      struct xsettings *settings;
@@ -268,8 +279,13 @@
       bytes_parsed += 4; /* Skip serial for this value */
       if (bytes_parsed > bytes) return BadLength;
 
-      want_this = (nlen > 6 && strncmp (name, "Xft/", 4) == 0)
-        || (strcmp (XSETTINGS_FONT_NAME, name) == 0);
+      want_this =
+#ifdef HAVE_XFT
+        (nlen > 6 && strncmp (name, "Xft/", 4) == 0)
+        ||
+#endif
+        (strcmp (XSETTINGS_FONT_NAME, name) == 0)
+        || (strcmp (XSETTINGS_TOOL_BAR_STYLE, name) == 0);
 
       switch (type) 
         {
@@ -311,7 +327,18 @@
       if (want_this) 
         {
           ++settings_seen;
-          if (strcmp (name, "Xft/Antialias") == 0)
+          if (strcmp (name, XSETTINGS_FONT_NAME) == 0)
+            {
+              settings->font = xstrdup (sval);
+              settings->seen |= SEEN_FONT;
+            }
+          else if (strcmp (name, XSETTINGS_TOOL_BAR_STYLE) == 0)
+            {
+              settings->tb_style = xstrdup (sval);
+              settings->seen |= SEEN_TB_STYLE;
+            }
+#ifdef HAVE_XFT
+          else if (strcmp (name, "Xft/Antialias") == 0)
             {
               settings->seen |= SEEN_AA;
               settings->aa = ival != 0;
@@ -366,11 +393,7 @@
               else
                 settings->seen &= ~SEEN_LCDFILTER;
             }
-          else if (strcmp (name, XSETTINGS_FONT_NAME) == 0)
-            {
-              free (current_font);
-              current_font = xstrdup (sval);
-            }
+#endif /* HAVE_XFT */
         }
     }
 
@@ -378,7 +401,7 @@
 }
 
 static int
-read_xft_settings (dpyinfo, settings)
+read_settings (dpyinfo, settings)
      struct x_display_info *dpyinfo;
      struct xsettings *settings;
 {
@@ -400,7 +423,7 @@
 
   if (rc == Success && prop != NULL && act_form == 8 && nitems > 0
       && act_type == dpyinfo->Xatom_xsettings_prop)
-    rc = parse_xft_settings (prop, nitems, settings);
+    rc = parse_settings (prop, nitems, settings);
 
   XFree (prop);
 
@@ -411,18 +434,17 @@
 
 
 static void
-apply_xft_settings (dpyinfo, send_event_p)
+apply_xft_settings (dpyinfo, send_event_p, settings)
      struct x_display_info *dpyinfo;
      int send_event_p;
+     struct xsettings *settings;
 {
+#ifdef HAVE_XFT
   FcPattern *pat;
-  struct xsettings settings, oldsettings;
+  struct xsettings oldsettings;
   int changed = 0;
   char buf[256];
 
-  if (!read_xft_settings (dpyinfo, &settings))
-    return;
-
   memset (&oldsettings, 0, sizeof (oldsettings));
   buf[0] = '\0';
   pat = FcPatternCreate ();
@@ -436,74 +458,74 @@
   FcPatternGetInteger (pat, FC_RGBA, 0, &oldsettings.rgba);
   FcPatternGetDouble (pat, FC_DPI, 0, &oldsettings.dpi);
 
-  if ((settings.seen & SEEN_AA) != 0 && oldsettings.aa != settings.aa)
+  if ((settings->seen & SEEN_AA) != 0 && oldsettings.aa != settings->aa)
     {
       FcPatternDel (pat, FC_ANTIALIAS);
-      FcPatternAddBool (pat, FC_ANTIALIAS, settings.aa);
+      FcPatternAddBool (pat, FC_ANTIALIAS, settings->aa);
       ++changed;
-      oldsettings.aa = settings.aa;
+      oldsettings.aa = settings->aa;
     }
   sprintf (buf, "Antialias: %d", oldsettings.aa);
 
-  if ((settings.seen & SEEN_HINTING) != 0
-      && oldsettings.hinting != settings.hinting)
+  if ((settings->seen & SEEN_HINTING) != 0
+      && oldsettings.hinting != settings->hinting)
     {
       FcPatternDel (pat, FC_HINTING);
-      FcPatternAddBool (pat, FC_HINTING, settings.hinting);
+      FcPatternAddBool (pat, FC_HINTING, settings->hinting);
       ++changed;
-      oldsettings.hinting = settings.hinting;
+      oldsettings.hinting = settings->hinting;
     }
   if (strlen (buf) > 0) strcat (buf, ", ");
   sprintf (buf+strlen (buf), "Hinting: %d", oldsettings.hinting);
-  if ((settings.seen & SEEN_RGBA) != 0 && oldsettings.rgba != settings.rgba)
+  if ((settings->seen & SEEN_RGBA) != 0 && oldsettings.rgba != settings->rgba)
     {
       FcPatternDel (pat, FC_RGBA);
-      FcPatternAddInteger (pat, FC_RGBA, settings.rgba);
-      oldsettings.rgba = settings.rgba;
+      FcPatternAddInteger (pat, FC_RGBA, settings->rgba);
+      oldsettings.rgba = settings->rgba;
       ++changed;
     }
   if (strlen (buf) > 0) strcat (buf, ", ");
   sprintf (buf+strlen (buf), "RGBA: %d", oldsettings.rgba);
 
   /* Older fontconfig versions don't have FC_LCD_FILTER. */
-  if ((settings.seen & SEEN_LCDFILTER) != 0
-      && oldsettings.lcdfilter != settings.lcdfilter)
+  if ((settings->seen & SEEN_LCDFILTER) != 0
+      && oldsettings.lcdfilter != settings->lcdfilter)
     {
       FcPatternDel (pat, FC_LCD_FILTER);
-      FcPatternAddInteger (pat, FC_LCD_FILTER, settings.lcdfilter);
+      FcPatternAddInteger (pat, FC_LCD_FILTER, settings->lcdfilter);
       ++changed;
-      oldsettings.lcdfilter = settings.lcdfilter;
+      oldsettings.lcdfilter = settings->lcdfilter;
     }
   if (strlen (buf) > 0) strcat (buf, ", ");
   sprintf (buf+strlen (buf), "LCDFilter: %d", oldsettings.lcdfilter);
 
-  if ((settings.seen & SEEN_HINTSTYLE) != 0
-      && oldsettings.hintstyle != settings.hintstyle)
+  if ((settings->seen & SEEN_HINTSTYLE) != 0
+      && oldsettings.hintstyle != settings->hintstyle)
     {
       FcPatternDel (pat, FC_HINT_STYLE);
-      FcPatternAddInteger (pat, FC_HINT_STYLE, settings.hintstyle);
+      FcPatternAddInteger (pat, FC_HINT_STYLE, settings->hintstyle);
       ++changed;
-      oldsettings.hintstyle = settings.hintstyle;
+      oldsettings.hintstyle = settings->hintstyle;
     }
   if (strlen (buf) > 0) strcat (buf, ", ");
   sprintf (buf+strlen (buf), "Hintstyle: %d", oldsettings.hintstyle);
 
-  if ((settings.seen & SEEN_DPI) != 0 && oldsettings.dpi != settings.dpi
-      && settings.dpi > 0)
+  if ((settings->seen & SEEN_DPI) != 0 && oldsettings.dpi != settings->dpi
+      && settings->dpi > 0)
     {
       Lisp_Object frame, tail;
 
       FcPatternDel (pat, FC_DPI);
-      FcPatternAddDouble (pat, FC_DPI, settings.dpi);
+      FcPatternAddDouble (pat, FC_DPI, settings->dpi);
       ++changed;
-      oldsettings.dpi = settings.dpi;
+      oldsettings.dpi = settings->dpi;
       
       /* Change the DPI on this display and all frames on the display.  */
-      dpyinfo->resy = dpyinfo->resx = settings.dpi;
+      dpyinfo->resy = dpyinfo->resx = settings->dpi;
       FOR_EACH_FRAME (tail, frame)
         if (FRAME_X_P (XFRAME (frame))
             && FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
-          XFRAME (frame)->resy = XFRAME (frame)->resx = settings.dpi;
+          XFRAME (frame)->resy = XFRAME (frame)->resx = settings->dpi;
     }
 
   if (strlen (buf) > 0) strcat (buf, ", ");
@@ -513,23 +535,68 @@
     {
       XftDefaultSet (dpyinfo->display, pat);
       if (send_event_p)
-        store_font_changed_event (Qfont_render,
-                                  XCAR (dpyinfo->name_list_element));
+        store_config_changed_event (Qfont_render,
+                                    XCAR (dpyinfo->name_list_element));
       Vxft_settings = make_string (buf, strlen (buf));
     }
   else
     FcPatternDestroy (pat);
+#endif /* HAVE_XFT */
 }
 
-#endif /* HAVE_XFT */
+static void
+read_and_apply_settings (dpyinfo, send_event_p)
+     struct x_display_info *dpyinfo;
+     int send_event_p;
+{
+  struct xsettings settings;
+  Lisp_Object dpyname = XCAR (dpyinfo->name_list_element);
+
+  if (!read_settings (dpyinfo, &settings))
+    return;
+
+  apply_xft_settings (dpyinfo, True, &settings);
+  if (settings.seen & SEEN_TB_STYLE)
+    {
+      Lisp_Object style = Qnil;
+      if (strcmp (settings.tb_style, "both") == 0)
+        style = Qboth;
+      else if (strcmp (settings.tb_style, "both-horiz") == 0)
+        style = Qboth_horiz;
+      else if (strcmp (settings.tb_style, "icons") == 0)
+        style = Qimage;
+      else if (strcmp (settings.tb_style, "text") == 0)
+        style = Qtext;
+      if (!NILP (style) && !EQ (style, current_tool_bar_style))
+        {
+          current_tool_bar_style = style;
+          if (send_event_p)
+            store_config_changed_event (Qtool_bar_style, dpyname);
+        }
+      free (settings.tb_style);
+    }
+
+  if (settings.seen & SEEN_FONT)
+    {
+      if (strcmp (current_font, settings.font) != 0) 
+        {
+          free (current_font);
+          current_font = settings.font;
+          if (send_event_p)
+            store_config_changed_event (Qfont_name, dpyname);
+        }
+      else
+        free (settings.font);
+    }
+}
 
 void
 xft_settings_event (dpyinfo, event)
      struct x_display_info *dpyinfo;
      XEvent *event;
 {
-#ifdef HAVE_XFT
   int check_window_p = 0;
+  int apply_settings = 0;
 
   switch (event->type)
     {
@@ -549,20 +616,21 @@
       if (event->xproperty.window == dpyinfo->xsettings_window
           && event->xproperty.state == PropertyNewValue
           && event->xproperty.atom == dpyinfo->Xatom_xsettings_prop)
-        {
-          apply_xft_settings (dpyinfo, True);
-        }
+        apply_settings = 1;
       break;
     }
 
+
   if (check_window_p)
     {
       dpyinfo->xsettings_window = None;
       get_prop_window (dpyinfo);
       if (dpyinfo->xsettings_window != None)
-        apply_xft_settings (dpyinfo, True);
+        apply_settings = 1;
     }
-#endif /* HAVE_XFT */
+
+  if (apply_settings)
+    read_and_apply_settings (dpyinfo, True);
 }
 
 
@@ -600,10 +668,9 @@
 }
 
 static void
-init_xfd_settings (dpyinfo)
+init_xsettings (dpyinfo)
      struct x_display_info *dpyinfo;
 {
-#ifdef HAVE_XFT
   char sel[64];
   Display *dpy = dpyinfo->display;
 
@@ -622,18 +689,9 @@
 
   get_prop_window (dpyinfo);
   if (dpyinfo->xsettings_window != None)
-    apply_xft_settings (dpyinfo, False);
+    read_and_apply_settings (dpyinfo, False);
 
   UNBLOCK_INPUT;
-
-#else /* ! HAVE_XFT */
-
-  dpyinfo->Xatom_xsettings_sel = None;
-  dpyinfo->Xatom_xsettings_prop = None;
-  dpyinfo->Xatom_xsettings_mgr = None;
-  dpyinfo->xsettings_window = None;
-
-#endif /* ! HAVE_XFT */
 }
 
 void
@@ -642,7 +700,7 @@
 {
   if (first_dpyinfo == NULL) first_dpyinfo = dpyinfo;
   init_gconf ();
-  init_xfd_settings (dpyinfo);
+  init_xsettings (dpyinfo);
 }
 
 const char *
@@ -678,6 +736,23 @@
     : Qnil;
 }
 
+DEFUN ("tool-bar-get-system-style", Ftool_bar_get_system_style, Stool_bar_get_system_style,
+       0, 0, 0,
+       doc: /* Get the system tool bar style.
+If no system tool bar style is known, return `tool-bar-style' is set to a
+known style.  Otherwise return image.  */)
+  ()
+{
+  if (EQ (Vtool_bar_style, Qimage)
+      || EQ (Vtool_bar_style, Qtext)
+      || EQ (Vtool_bar_style, Qboth)
+      || EQ (Vtool_bar_style, Qboth_horiz))
+    return Vtool_bar_style;
+  if (!NILP (current_tool_bar_style))
+    return current_tool_bar_style;
+  return Qimage;
+}
+
 void
 syms_of_xsettings ()
 {
@@ -688,6 +763,8 @@
   gconf_client = NULL;
 #endif
 
+  Qmonospace_font_name = intern_c_string ("monospace-font-name");
+  staticpro (&Qmonospace_font_name);
   Qfont_name = intern_c_string ("font-name");
   staticpro (&Qfont_name);
   Qfont_render = intern_c_string ("font-render");
@@ -709,6 +786,13 @@
   Fprovide (intern_c_string ("system-font-setting"), Qnil);
 #endif
 #endif
+
+  current_tool_bar_style = Qnil;
+  Qtool_bar_style = intern_c_string ("tool-bar-style");
+  staticpro (&Qtool_bar_style);
+  defsubr (&Stool_bar_get_system_style);
+
+  Fprovide (intern_c_string ("dynamic-setting"), Qnil);
 }
 
 /* arch-tag: 541716ed-2e6b-42e1-8212-3197e01ea61d
--- a/src/xsettings.h	Wed Apr 21 18:13:55 2010 +0200
+++ b/src/xsettings.h	Tue Apr 20 20:52:07 2010 +0200
@@ -22,6 +22,7 @@
 
 EXFUN (Ffont_get_system_font, 0);
 EXFUN (Ffont_get_system_normal_font, 0);
+EXFUN (Ftool_bar_get_system_style, 0);
 
 extern void xsettings_initialize P_ ((struct x_display_info *dpyinfo));
 extern void xft_settings_event P_ ((struct x_display_info *dpyinfo,
--- a/src/xterm.c	Wed Apr 21 18:13:55 2010 +0200
+++ b/src/xterm.c	Tue Apr 20 20:52:07 2010 +0200
@@ -2322,10 +2322,13 @@
       raised_p = s->img->relief > 0;
     }
 
-  x0 = x - thick;
-  y0 = y - thick;
-  x1 = x + s->slice.width + thick - 1;
-  y1 = y + s->slice.height + thick - 1;
+  int extra = s->face->id == TOOL_BAR_FACE_ID
+    ? XINT (Vtool_bar_button_margin) : 0;
+  
+  x0 = x - thick - extra;
+  y0 = y - thick - extra;
+  x1 = x + s->slice.width + thick - 1 + extra;
+  y1 = y + s->slice.height + thick - 1 + extra;
 
   x_setup_relief_colors (s);
   get_glyph_string_clip_rect (s, &r);