aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJan Djärv2010-04-20 20:52:07 +0200
committerJan Djärv2010-04-20 20:52:07 +0200
commitf904c0f93825fb434f802ced019c378a20ec491d (patch)
tree8c3423c4680c054cd4ede1c2d01438d64f328a67 /src
parentc632dfda11b0ad6a144704dc473e4ff6bbac0990 (diff)
downloademacs-f904c0f93825fb434f802ced019c378a20ec491d.tar.gz
emacs-f904c0f93825fb434f802ced019c378a20ec491d.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog58
-rw-r--r--src/Makefile.in4
-rw-r--r--src/dispextern.h12
-rw-r--r--src/gtkutil.c258
-rw-r--r--src/keyboard.c61
-rw-r--r--src/lisp.h2
-rw-r--r--src/xdisp.c35
-rw-r--r--src/xsettings.c254
-rw-r--r--src/xsettings.h1
-rw-r--r--src/xterm.c11
10 files changed, 514 insertions, 182 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 14790309a11..8125fce330b 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,63 @@
12010-04-21 Jan Djärv <jan.h.d@swipnet.se> 12010-04-21 Jan Djärv <jan.h.d@swipnet.se>
2 2
3 * xsettings.c: Qmonospace_font_name, Qtool_bar_style and
4 current_tool_bar_style are new.
5 (store_config_changed_event): Rename from store_font_changed_event.
6 (XSETTINGS_TOOL_BAR_STYLE): New define.
7 (SEEN_FONT, SEEN_TB_STYLE): New enum values.
8 (struct xsettings): Add font and tb_style, set xft stuff inside #ifdef
9 HAVE_XFT.
10 (something_changedCB): store_font_changed_event is now
11 store_config_changed_event
12 (parse_settings): Rename from parse_xft_settings. Read
13 non-xft xsettings outside #ifdef HAVE_XFT.
14 (read_settings): Renamed from read_xft_settings.
15 (apply_xft_settings): Take current settings as parameter. Do not
16 call read_(xft)_settings.
17 (read_and_apply_settings): New function.
18 (xft_settings_event): Do non-xft stuff out of HAVE_XFT. Call
19 read_and_apply_settings if there are settings to be read.
20 (init_xsettings): Renamed from init_xfd_settings.
21 Call read_and_apply_settings unconditionally.
22 (xsettings_initialize): Call init_xsettings.
23 (Ftool_bar_get_system_style): New function.
24 (syms_of_xsettings): Define Qmonospace_font_name and
25 Qtool_bar_style. Initialize current_tool_bar_style to nil.
26 defsubr Stool_bar_get_system_style. Fprovide on
27 dynamic-setting.
28
29 * xsettings.h (Ftool_bar_get_system_style): Declare.
30
31 * xdisp.c: Vtool_bar_style, tool_bar_max_label_size,
32 Qtext, Qboth, Qboth_horiz are new.
33 (syms_of_xdisp): Intern Qtext, Qboth, Qboth_horiz, DEFVAR
34 Vtool_bar_style, tool_bar_max_label_size.
35
36 * lisp.h: Extern declare Qtext, Qboth, Qboth_horiz.
37
38 * keyboard.c: QClabel is new.
39 (parse_tool_bar_item): Take out QClabel from tool bar items.
40 Try to construct a label if ther is no QClabel.
41 (syms_of_keyboard): Intern :label as QClabel.
42
43 * dispextern.h (tool_bar_item_idx): TOOL_BAR_ITEM_LABEL is new.
44 (Vtool_bar_style, tool_bar_max_label_size, DEFAULT_TOOL_BAR_LABEL_SIZE):
45 New.
46
47 * Makefile.in (SOME_MACHINE_LISP): font-setting.el renamed to
48 dynamic-setting.el.
49
50 * gtkutil.c (xg_tool_bar_menu_proxy): Handle label in tool bar item.
51 (xg_make_tool_item, xg_show_toolbar_item): New function.
52 (update_frame_tool_bar): Take label from TOOL_BAR_ITEM_LABEL.
53 Call xg_make_tool_item to make a tool bar item.
54 Call xg_show_toolbar_item. Use wtoolbar instead of x->toolbar_widget.
55
56 * xterm.c (x_draw_image_relief): Take Vtool_bar_button_margin
57 into account for toolbars.
58
592010-04-21 Jan Djärv <jan.h.d@swipnet.se>
60
3 * data.c (make_blv): Declarations before code (Bug#5993). 61 * data.c (make_blv): Declarations before code (Bug#5993).
4 62
52010-04-21 Glenn Morris <rgm@gnu.org> 632010-04-21 Glenn Morris <rgm@gnu.org>
diff --git a/src/Makefile.in b/src/Makefile.in
index 61b6cef6827..ab9272f5285 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -566,7 +566,7 @@ otherobj= $(termcapobj) lastfile.o $(mallocobj) $(widgetobj) $(LIBOBJS)
566 ${lispsource}international/fontset.elc ${lispsource}dnd.elc \ 566 ${lispsource}international/fontset.elc ${lispsource}dnd.elc \
567 ${lispsource}tool-bar.elc ${lispsource}mwheel.elc ${lispsource}x-dnd.elc \ 567 ${lispsource}tool-bar.elc ${lispsource}mwheel.elc ${lispsource}x-dnd.elc \
568 ${lispsource}term/common-win.elc ${lispsource}term/x-win.elc \ 568 ${lispsource}term/common-win.elc ${lispsource}term/x-win.elc \
569 ${lispsource}font-setting.elc 569 ${lispsource}dynamic-setting.elc
570#else 570#else
571#define WINDOW_SUPPORT ${lispsource}fringe.elc ${lispsource}image.elc \ 571#define WINDOW_SUPPORT ${lispsource}fringe.elc ${lispsource}image.elc \
572 ${lispsource}international/fontset.elc ${lispsource}dnd.elc \ 572 ${lispsource}international/fontset.elc ${lispsource}dnd.elc \
@@ -801,7 +801,7 @@ SOME_MACHINE_LISP = ../lisp/mouse.elc \
801 ../lisp/tooltip.elc ../lisp/image.elc \ 801 ../lisp/tooltip.elc ../lisp/image.elc \
802 ../lisp/fringe.elc ../lisp/dnd.elc \ 802 ../lisp/fringe.elc ../lisp/dnd.elc \
803 ../lisp/mwheel.elc ../lisp/tool-bar.elc \ 803 ../lisp/mwheel.elc ../lisp/tool-bar.elc \
804 ../lisp/x-dnd.elc ../lisp/font-setting.elc \ 804 ../lisp/x-dnd.elc ../lisp/dynamic-setting.elc \
805 ../lisp/international/ccl.elc \ 805 ../lisp/international/ccl.elc \
806 ../lisp/international/fontset.elc \ 806 ../lisp/international/fontset.elc \
807 ../lisp/mouse.elc \ 807 ../lisp/mouse.elc \
diff --git a/src/dispextern.h b/src/dispextern.h
index d60616a9088..afbe6f5343d 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2793,6 +2793,9 @@ enum tool_bar_item_idx
2793 /* Icon file name of right to left image when an RTL locale is used. */ 2793 /* Icon file name of right to left image when an RTL locale is used. */
2794 TOOL_BAR_ITEM_RTL_IMAGE, 2794 TOOL_BAR_ITEM_RTL_IMAGE,
2795 2795
2796 /* Label to show when text labels are enabled. */
2797 TOOL_BAR_ITEM_LABEL,
2798
2796 /* Sentinel = number of slots in tool_bar_items occupied by one 2799 /* Sentinel = number of slots in tool_bar_items occupied by one
2797 tool-bar item. */ 2800 tool-bar item. */
2798 TOOL_BAR_ITEM_NSLOTS 2801 TOOL_BAR_ITEM_NSLOTS
@@ -2814,6 +2817,15 @@ enum tool_bar_item_image
2814 2817
2815extern Lisp_Object Vtool_bar_button_margin; 2818extern Lisp_Object Vtool_bar_button_margin;
2816 2819
2820/* Tool bar style */
2821
2822extern Lisp_Object Vtool_bar_style;
2823
2824/* Maximum number of characters a label can have to be shown. */
2825
2826extern EMACS_INT tool_bar_max_label_size;
2827#define DEFAULT_TOOL_BAR_LABEL_SIZE 14
2828
2817/* Thickness of relief to draw around tool-bar buttons. */ 2829/* Thickness of relief to draw around tool-bar buttons. */
2818 2830
2819extern EMACS_INT tool_bar_button_relief; 2831extern EMACS_INT tool_bar_button_relief;
diff --git a/src/gtkutil.c b/src/gtkutil.c
index b3805511bc9..d9312909bf3 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -3522,7 +3522,16 @@ xg_tool_bar_menu_proxy (toolitem, user_data)
3522{ 3522{
3523 GtkWidget *weventbox = gtk_bin_get_child (GTK_BIN (toolitem)); 3523 GtkWidget *weventbox = gtk_bin_get_child (GTK_BIN (toolitem));
3524 GtkButton *wbutton = GTK_BUTTON (gtk_bin_get_child (GTK_BIN (weventbox))); 3524 GtkButton *wbutton = GTK_BUTTON (gtk_bin_get_child (GTK_BIN (weventbox)));
3525 GtkWidget *wmenuitem = gtk_image_menu_item_new_with_label (""); 3525 GtkBox *vb = GTK_BOX (gtk_bin_get_child (GTK_BIN (wbutton)));
3526 GtkBoxChild *c1 = (GtkBoxChild *) vb->children->data;
3527 GtkBoxChild *c2 = (GtkBoxChild *) vb->children->next->data;
3528 GtkImage *wimage = GTK_IS_IMAGE (c1->widget)
3529 ? GTK_IMAGE (c1->widget) : GTK_IMAGE (c2->widget);
3530 GtkLabel *wlbl = GTK_IS_LABEL (c1->widget)
3531 ? GTK_LABEL (c1->widget) : GTK_LABEL (c2->widget);
3532 GtkWidget *wmenuitem = gtk_image_menu_item_new_with_label
3533 (gtk_label_get_text (wlbl));
3534
3526 GtkWidget *wmenuimage; 3535 GtkWidget *wmenuimage;
3527 3536
3528 if (gtk_button_get_use_stock (wbutton)) 3537 if (gtk_button_get_use_stock (wbutton))
@@ -3530,7 +3539,6 @@ xg_tool_bar_menu_proxy (toolitem, user_data)
3530 GTK_ICON_SIZE_MENU); 3539 GTK_ICON_SIZE_MENU);
3531 else 3540 else
3532 { 3541 {
3533 GtkImage *wimage = GTK_IMAGE (gtk_bin_get_child (GTK_BIN (wbutton)));
3534 GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (wbutton)); 3542 GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (wbutton));
3535 GtkImageType store_type = gtk_image_get_storage_type (wimage); 3543 GtkImageType store_type = gtk_image_get_storage_type (wimage);
3536 3544
@@ -3834,6 +3842,132 @@ find_rtl_image (f, image, rtl)
3834 return image; 3842 return image;
3835} 3843}
3836 3844
3845static GtkToolItem *
3846xg_make_tool_item (FRAME_PTR f,
3847 GtkWidget *wimage,
3848 GtkWidget **wbutton,
3849 char *label,
3850 int i)
3851{
3852 GtkToolItem *ti = gtk_tool_item_new ();
3853 GtkWidget *vb = EQ (Vtool_bar_style, Qboth_horiz)
3854 ? gtk_hbox_new (FALSE, 0) : gtk_vbox_new (FALSE, 0);
3855 GtkWidget *wb = gtk_button_new ();
3856 GtkWidget *weventbox = gtk_event_box_new ();
3857
3858 if (wimage)
3859 gtk_box_pack_start_defaults (GTK_BOX (vb), wimage);
3860
3861 gtk_box_pack_start_defaults (GTK_BOX (vb), gtk_label_new (label));
3862 gtk_button_set_focus_on_click (GTK_BUTTON (wb), FALSE);
3863 gtk_button_set_relief (GTK_BUTTON (wb), GTK_RELIEF_NONE);
3864 gtk_container_add (GTK_CONTAINER (wb), vb);
3865 gtk_container_add (GTK_CONTAINER (weventbox), wb);
3866 gtk_container_add (GTK_CONTAINER (ti), weventbox);
3867
3868 if (wimage)
3869 {
3870 /* The EMACS_INT cast avoids a warning. */
3871 g_signal_connect (G_OBJECT (ti), "create-menu-proxy",
3872 G_CALLBACK (xg_tool_bar_menu_proxy),
3873 (gpointer) (EMACS_INT) i);
3874
3875 g_signal_connect (G_OBJECT (wb), "clicked",
3876 G_CALLBACK (xg_tool_bar_callback),
3877 (gpointer) (EMACS_INT) i);
3878
3879 gtk_widget_show_all (GTK_WIDGET (ti));
3880
3881 g_object_set_data (G_OBJECT (weventbox), XG_FRAME_DATA, (gpointer)f);
3882
3883 /* Catch expose events to overcome an annoying redraw bug, see
3884 comment for xg_tool_bar_item_expose_callback. */
3885 g_signal_connect (G_OBJECT (ti),
3886 "expose-event",
3887 G_CALLBACK (xg_tool_bar_item_expose_callback),
3888 0);
3889
3890 gtk_tool_item_set_homogeneous (ti, FALSE);
3891
3892 /* Callback to save modifyer mask (Shift/Control, etc). GTK makes
3893 no distinction based on modifiers in the activate callback,
3894 so we have to do it ourselves. */
3895 g_signal_connect (wb, "button-release-event",
3896 G_CALLBACK (xg_tool_bar_button_cb),
3897 NULL);
3898
3899 g_object_set_data (G_OBJECT (wb), XG_FRAME_DATA, (gpointer)f);
3900
3901 /* Use enter/leave notify to show help. We use the events
3902 rather than the GtkButton specific signals "enter" and
3903 "leave", so we can have only one callback. The event
3904 will tell us what kind of event it is. */
3905 /* The EMACS_INT cast avoids a warning. */
3906 g_signal_connect (G_OBJECT (weventbox),
3907 "enter-notify-event",
3908 G_CALLBACK (xg_tool_bar_help_callback),
3909 (gpointer) (EMACS_INT) i);
3910 g_signal_connect (G_OBJECT (weventbox),
3911 "leave-notify-event",
3912 G_CALLBACK (xg_tool_bar_help_callback),
3913 (gpointer) (EMACS_INT) i);
3914 }
3915
3916 if (wbutton) *wbutton = wb;
3917
3918 return ti;
3919}
3920
3921static void
3922xg_show_toolbar_item (GtkToolItem *ti)
3923{
3924 Lisp_Object style = Ftool_bar_get_system_style ();
3925
3926 int show_label = EQ (style, Qboth)
3927 || EQ (style, Qboth_horiz) || EQ (style, Qtext);
3928 int show_image = ! EQ (style, Qtext);
3929 int horiz = EQ (style, Qboth_horiz);
3930
3931 GtkWidget *weventbox = gtk_bin_get_child (GTK_BIN (ti));
3932 GtkWidget *wbutton = gtk_bin_get_child (GTK_BIN (weventbox));
3933 GtkBox *vb = GTK_BOX (gtk_bin_get_child (GTK_BIN (wbutton)));
3934 GtkBoxChild *c1 = (GtkBoxChild *) vb->children->data;
3935 GtkBoxChild *c2 = (GtkBoxChild *) vb->children->next->data;
3936 GtkWidget *wimage = GTK_IS_IMAGE (c1->widget)
3937 ? c1->widget : c2->widget;
3938 GtkWidget *wlbl = GTK_IS_LABEL (c1->widget)
3939 ? c1->widget : c2->widget;
3940 GtkWidget *new_box = NULL;
3941
3942 if (GTK_IS_VBOX (vb) && horiz)
3943 new_box = gtk_hbox_new (FALSE, 0);
3944 else if (GTK_IS_HBOX (vb) && !horiz && show_label && show_image)
3945 new_box = gtk_vbox_new (FALSE, 0);
3946 if (new_box)
3947 {
3948 gtk_widget_ref (wimage);
3949 gtk_widget_ref (wlbl);
3950 gtk_container_remove (GTK_CONTAINER (vb), wimage);
3951 gtk_container_remove (GTK_CONTAINER (vb), wlbl);
3952 gtk_widget_destroy (GTK_WIDGET (vb));
3953 gtk_box_pack_start_defaults (GTK_BOX (new_box), wimage);
3954 gtk_box_pack_start_defaults (GTK_BOX (new_box), wlbl);
3955 gtk_container_add (GTK_CONTAINER (wbutton), new_box);
3956 gtk_widget_unref (wimage);
3957 gtk_widget_unref (wlbl);
3958 vb = GTK_BOX (new_box);
3959 }
3960
3961 if (show_label) gtk_widget_show (wlbl);
3962 else gtk_widget_hide (wlbl);
3963 if (show_image) gtk_widget_show (wimage);
3964 else gtk_widget_hide (wimage);
3965 gtk_widget_show (GTK_WIDGET (vb));
3966 gtk_widget_show (GTK_WIDGET (wbutton));
3967 gtk_widget_show (GTK_WIDGET (ti));
3968}
3969
3970
3837/* Update the tool bar for frame F. Add new buttons and remove old. */ 3971/* Update the tool bar for frame F. Add new buttons and remove old. */
3838 3972
3839extern Lisp_Object Qx_gtk_map_stock; 3973extern Lisp_Object Qx_gtk_map_stock;
@@ -3885,8 +4019,8 @@ update_frame_tool_bar (f)
3885 4019
3886 wtoolbar = GTK_TOOLBAR (x->toolbar_widget); 4020 wtoolbar = GTK_TOOLBAR (x->toolbar_widget);
3887 gtk_widget_size_request (GTK_WIDGET (wtoolbar), &old_req); 4021 gtk_widget_size_request (GTK_WIDGET (wtoolbar), &old_req);
3888 dir = gtk_widget_get_direction (x->toolbar_widget); 4022 dir = gtk_widget_get_direction (GTK_WIDGET (wtoolbar));
3889 4023
3890 for (i = 0; i < f->n_tool_bar_items; ++i) 4024 for (i = 0; i < f->n_tool_bar_items; ++i)
3891 { 4025 {
3892 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P)); 4026 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
@@ -3904,8 +4038,10 @@ update_frame_tool_bar (f)
3904 GtkWidget *wbutton = NULL; 4038 GtkWidget *wbutton = NULL;
3905 GtkWidget *weventbox; 4039 GtkWidget *weventbox;
3906 Lisp_Object specified_file; 4040 Lisp_Object specified_file;
3907 4041 Lisp_Object lbl = PROP (TOOL_BAR_ITEM_LABEL);
3908 ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (x->toolbar_widget), i); 4042 char *label = SSDATA (PROP (TOOL_BAR_ITEM_LABEL));
4043
4044 ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (wtoolbar), i);
3909 4045
3910 if (ti) 4046 if (ti)
3911 { 4047 {
@@ -3913,6 +4049,7 @@ update_frame_tool_bar (f)
3913 wbutton = gtk_bin_get_child (GTK_BIN (weventbox)); 4049 wbutton = gtk_bin_get_child (GTK_BIN (weventbox));
3914 } 4050 }
3915 4051
4052
3916 image = PROP (TOOL_BAR_ITEM_IMAGES); 4053 image = PROP (TOOL_BAR_ITEM_IMAGES);
3917 4054
3918 /* Ignore invalid image specifications. */ 4055 /* Ignore invalid image specifications. */
@@ -3944,7 +4081,7 @@ update_frame_tool_bar (f)
3944 icon_size = gtk_toolbar_get_icon_size (wtoolbar); 4081 icon_size = gtk_toolbar_get_icon_size (wtoolbar);
3945 } 4082 }
3946 else if (gtk_stock_lookup (SSDATA (stock), &stock_item)) 4083 else if (gtk_stock_lookup (SSDATA (stock), &stock_item))
3947 icon_size = gtk_toolbar_get_icon_size (wtoolbar); 4084 icon_size = gtk_toolbar_get_icon_size (wtoolbar);
3948 else 4085 else
3949 { 4086 {
3950 stock = Qnil; 4087 stock = Qnil;
@@ -3988,22 +4125,15 @@ update_frame_tool_bar (f)
3988 4125
3989 if (img->load_failed_p || img->pixmap == None) 4126 if (img->load_failed_p || img->pixmap == None)
3990 { 4127 {
3991 if (ti) 4128 if (ti)
3992 gtk_widget_hide_all (GTK_WIDGET (ti)); 4129 gtk_widget_hide_all (GTK_WIDGET (ti));
3993 else 4130 else
3994 { 4131 {
3995 /* Insert an empty (non-image) button */ 4132 /* Insert an empty (non-image) button */
3996 weventbox = gtk_event_box_new (); 4133 ti = xg_make_tool_item (f, NULL, NULL, "", i);
3997 wbutton = gtk_button_new (); 4134 gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, -1);
3998 gtk_button_set_focus_on_click (GTK_BUTTON (wbutton), FALSE);
3999 gtk_button_set_relief (GTK_BUTTON (wbutton),
4000 GTK_RELIEF_NONE);
4001 gtk_container_add (GTK_CONTAINER (weventbox), wbutton);
4002 ti = gtk_tool_item_new ();
4003 gtk_container_add (GTK_CONTAINER (ti), weventbox);
4004 gtk_toolbar_insert (GTK_TOOLBAR (x->toolbar_widget), ti, -1);
4005 } 4135 }
4006 continue; 4136 continue;
4007 } 4137 }
4008 } 4138 }
4009 4139
@@ -4034,73 +4164,27 @@ update_frame_tool_bar (f)
4034 } 4164 }
4035 4165
4036 gtk_misc_set_padding (GTK_MISC (w), hmargin, vmargin); 4166 gtk_misc_set_padding (GTK_MISC (w), hmargin, vmargin);
4037 wbutton = gtk_button_new (); 4167 ti = xg_make_tool_item (f, w, &wbutton, label, i);
4038 gtk_button_set_focus_on_click (GTK_BUTTON (wbutton), FALSE); 4168 gtk_toolbar_insert (GTK_TOOLBAR (wtoolbar), ti, -1);
4039 gtk_button_set_relief (GTK_BUTTON (wbutton), GTK_RELIEF_NONE);
4040 gtk_container_add (GTK_CONTAINER (wbutton), w);
4041 weventbox = gtk_event_box_new ();
4042 gtk_container_add (GTK_CONTAINER (weventbox), wbutton);
4043 ti = gtk_tool_item_new ();
4044 gtk_container_add (GTK_CONTAINER (ti), weventbox);
4045 gtk_toolbar_insert (GTK_TOOLBAR (x->toolbar_widget), ti, -1);
4046
4047
4048 /* The EMACS_INT cast avoids a warning. */
4049 g_signal_connect (G_OBJECT (ti), "create-menu-proxy",
4050 G_CALLBACK (xg_tool_bar_menu_proxy),
4051 (gpointer) (EMACS_INT) i);
4052
4053 g_signal_connect (G_OBJECT (wbutton), "clicked",
4054 G_CALLBACK (xg_tool_bar_callback),
4055 (gpointer) (EMACS_INT) i);
4056
4057 gtk_widget_show_all (GTK_WIDGET (ti));
4058
4059
4060 g_object_set_data (G_OBJECT (weventbox), XG_FRAME_DATA, (gpointer)f);
4061
4062 /* Catch expose events to overcome an annoying redraw bug, see
4063 comment for xg_tool_bar_item_expose_callback. */
4064 g_signal_connect (G_OBJECT (ti),
4065 "expose-event",
4066 G_CALLBACK (xg_tool_bar_item_expose_callback),
4067 0);
4068
4069 gtk_widget_set_sensitive (wbutton, enabled_p); 4169 gtk_widget_set_sensitive (wbutton, enabled_p);
4070 gtk_tool_item_set_homogeneous (ti, FALSE);
4071
4072 /* Callback to save modifyer mask (Shift/Control, etc). GTK makes
4073 no distinction based on modifiers in the activate callback,
4074 so we have to do it ourselves. */
4075 g_signal_connect (wbutton, "button-release-event",
4076 G_CALLBACK (xg_tool_bar_button_cb),
4077 NULL);
4078
4079 g_object_set_data (G_OBJECT (wbutton), XG_FRAME_DATA, (gpointer)f);
4080
4081 /* Use enter/leave notify to show help. We use the events
4082 rather than the GtkButton specific signals "enter" and
4083 "leave", so we can have only one callback. The event
4084 will tell us what kind of event it is. */
4085 /* The EMACS_INT cast avoids a warning. */
4086 g_signal_connect (G_OBJECT (weventbox),
4087 "enter-notify-event",
4088 G_CALLBACK (xg_tool_bar_help_callback),
4089 (gpointer) (EMACS_INT) i);
4090 g_signal_connect (G_OBJECT (weventbox),
4091 "leave-notify-event",
4092 G_CALLBACK (xg_tool_bar_help_callback),
4093 (gpointer) (EMACS_INT) i);
4094 } 4170 }
4095 else 4171 else
4096 { 4172 {
4097 GtkWidget *wimage = gtk_bin_get_child (GTK_BIN (wbutton)); 4173 GtkBox *vb = GTK_BOX (gtk_bin_get_child (GTK_BIN (wbutton)));
4174 GtkBoxChild *c1 = (GtkBoxChild *) vb->children->data;
4175 GtkBoxChild *c2 = (GtkBoxChild *) vb->children->next->data;
4176 GtkWidget *wimage = GTK_IS_IMAGE (c1->widget)
4177 ? c1->widget : c2->widget;
4178 GtkWidget *wlbl = GTK_IS_LABEL (c1->widget)
4179 ? c1->widget : c2->widget;
4180
4098 Pixmap old_img = (Pixmap)g_object_get_data (G_OBJECT (wimage), 4181 Pixmap old_img = (Pixmap)g_object_get_data (G_OBJECT (wimage),
4099 XG_TOOL_BAR_IMAGE_DATA); 4182 XG_TOOL_BAR_IMAGE_DATA);
4100 gpointer old_stock_name = g_object_get_data (G_OBJECT (wimage), 4183 gpointer old_stock_name = g_object_get_data (G_OBJECT (wimage),
4101 XG_TOOL_BAR_STOCK_NAME); 4184 XG_TOOL_BAR_STOCK_NAME);
4102 gpointer old_icon_name = g_object_get_data (G_OBJECT (wimage), 4185 gpointer old_icon_name = g_object_get_data (G_OBJECT (wimage),
4103 XG_TOOL_BAR_ICON_NAME); 4186 XG_TOOL_BAR_ICON_NAME);
4187 gtk_label_set_text (GTK_LABEL (wlbl), label);
4104 if (stock_name && 4188 if (stock_name &&
4105 (! old_stock_name || strcmp (old_stock_name, stock_name) != 0)) 4189 (! old_stock_name || strcmp (old_stock_name, stock_name) != 0))
4106 { 4190 {
@@ -4111,7 +4195,8 @@ update_frame_tool_bar (f)
4111 (GDestroyNotify) xfree); 4195 (GDestroyNotify) xfree);
4112 g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_IMAGE_DATA, 4196 g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_IMAGE_DATA,
4113 NULL); 4197 NULL);
4114 g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_ICON_NAME, NULL); 4198 g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_ICON_NAME,
4199 NULL);
4115 } 4200 }
4116 else if (icon_name && 4201 else if (icon_name &&
4117 (! old_icon_name || strcmp (old_icon_name, icon_name) != 0)) 4202 (! old_icon_name || strcmp (old_icon_name, icon_name) != 0))
@@ -4134,14 +4219,15 @@ update_frame_tool_bar (f)
4134 4219
4135 g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_STOCK_NAME, 4220 g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_STOCK_NAME,
4136 NULL); 4221 NULL);
4137 g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_ICON_NAME, NULL); 4222 g_object_set_data (G_OBJECT (wimage), XG_TOOL_BAR_ICON_NAME,
4223 NULL);
4138 } 4224 }
4139 4225
4140 gtk_misc_set_padding (GTK_MISC (wimage), hmargin, vmargin); 4226 gtk_misc_set_padding (GTK_MISC (wimage), hmargin, vmargin);
4141 4227
4142 gtk_widget_set_sensitive (wbutton, enabled_p); 4228 gtk_widget_set_sensitive (wbutton, enabled_p);
4143 gtk_widget_show_all (GTK_WIDGET (ti)); 4229 }
4144 } 4230 xg_show_toolbar_item (ti);
4145 4231
4146#undef PROP 4232#undef PROP
4147 } 4233 }
@@ -4150,16 +4236,16 @@ update_frame_tool_bar (f)
4150 can be reused later on. */ 4236 can be reused later on. */
4151 do 4237 do
4152 { 4238 {
4153 ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (x->toolbar_widget), i++); 4239 ti = gtk_toolbar_get_nth_item (GTK_TOOLBAR (wtoolbar), i++);
4154 if (ti) gtk_widget_hide_all (GTK_WIDGET (ti)); 4240 if (ti) gtk_widget_hide_all (GTK_WIDGET (ti));
4155 } while (ti != NULL); 4241 } while (ti != NULL);
4156 4242
4157 new_req.height = 0; 4243 new_req.height = 0;
4158 if (pack_tool_bar && f->n_tool_bar_items != 0) 4244 if (pack_tool_bar && f->n_tool_bar_items != 0)
4159 xg_pack_tool_bar (f); 4245 xg_pack_tool_bar (f);
4160 4246
4161 4247
4162 gtk_widget_size_request (GTK_WIDGET (x->toolbar_widget), &new_req); 4248 gtk_widget_size_request (GTK_WIDGET (wtoolbar), &new_req);
4163 if (old_req.height != new_req.height 4249 if (old_req.height != new_req.height
4164 && ! FRAME_X_OUTPUT (f)->toolbar_detached) 4250 && ! FRAME_X_OUTPUT (f)->toolbar_detached)
4165 { 4251 {
@@ -4203,7 +4289,7 @@ free_frame_tool_bar (f)
4203 4289
4204/*********************************************************************** 4290/***********************************************************************
4205 Initializing 4291 Initializing
4206 ***********************************************************************/ 4292***********************************************************************/
4207void 4293void
4208xg_initialize () 4294xg_initialize ()
4209{ 4295{
diff --git a/src/keyboard.c b/src/keyboard.c
index 1d99c31999f..74efb856852 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -496,7 +496,7 @@ Lisp_Object Qevent_symbol_elements;
496/* menu item parts */ 496/* menu item parts */
497Lisp_Object Qmenu_enable; 497Lisp_Object Qmenu_enable;
498Lisp_Object QCenable, QCvisible, QChelp, QCfilter, QCkeys, QCkey_sequence; 498Lisp_Object QCenable, QCvisible, QChelp, QCfilter, QCkeys, QCkey_sequence;
499Lisp_Object QCbutton, QCtoggle, QCradio; 499Lisp_Object QCbutton, QCtoggle, QCradio, QClabel;
500extern Lisp_Object Qmenu_item; 500extern Lisp_Object Qmenu_item;
501 501
502/* An event header symbol HEAD may have a property named 502/* An event header symbol HEAD may have a property named
@@ -8248,7 +8248,11 @@ process_tool_bar_item (key, def, data, args)
8248 8248
8249 - `:help HELP-STRING'. 8249 - `:help HELP-STRING'.
8250 8250
8251 Gives a help string to display for the tool bar item. */ 8251 Gives a help string to display for the tool bar item.
8252
8253 - `:label LABEL-STRING'.
8254
8255 A text label to show with the tool bar button if labels are enabled. */
8252 8256
8253static int 8257static int
8254parse_tool_bar_item (key, item) 8258parse_tool_bar_item (key, item)
@@ -8259,7 +8263,7 @@ parse_tool_bar_item (key, item)
8259 8263
8260 Lisp_Object filter = Qnil; 8264 Lisp_Object filter = Qnil;
8261 Lisp_Object caption; 8265 Lisp_Object caption;
8262 int i; 8266 int i, have_label = 0;
8263 8267
8264 /* Defininition looks like `(menu-item CAPTION BINDING PROPS...)'. 8268 /* Defininition looks like `(menu-item CAPTION BINDING PROPS...)'.
8265 Rule out items that aren't lists, don't start with 8269 Rule out items that aren't lists, don't start with
@@ -8337,6 +8341,12 @@ parse_tool_bar_item (key, item)
8337 else if (EQ (key, QChelp)) 8341 else if (EQ (key, QChelp))
8338 /* `:help HELP-STRING'. */ 8342 /* `:help HELP-STRING'. */
8339 PROP (TOOL_BAR_ITEM_HELP) = value; 8343 PROP (TOOL_BAR_ITEM_HELP) = value;
8344 else if (EQ (key, QClabel))
8345 {
8346 /* `:label LABEL-STRING'. */
8347 PROP (TOOL_BAR_ITEM_LABEL) = value;
8348 have_label = 1;
8349 }
8340 else if (EQ (key, QCfilter)) 8350 else if (EQ (key, QCfilter))
8341 /* ':filter FORM'. */ 8351 /* ':filter FORM'. */
8342 filter = value; 8352 filter = value;
@@ -8364,6 +8374,49 @@ parse_tool_bar_item (key, item)
8364 PROP (TOOL_BAR_ITEM_RTL_IMAGE) = value; 8374 PROP (TOOL_BAR_ITEM_RTL_IMAGE) = value;
8365 } 8375 }
8366 8376
8377
8378 if (!have_label)
8379 {
8380 /* Try to make one from caption and key. */
8381 Lisp_Object key = PROP (TOOL_BAR_ITEM_KEY);
8382 Lisp_Object capt = PROP (TOOL_BAR_ITEM_CAPTION);
8383 char *label = SYMBOLP (key) ? (char *) SDATA (SYMBOL_NAME (key)) : "";
8384 char *caption = STRINGP (capt) ? (char *) SDATA (capt) : "";
8385 char buf[64];
8386 EMACS_INT max_lbl = 2*tool_bar_max_label_size;
8387 Lisp_Object new_lbl;
8388
8389 if (strlen (caption) < max_lbl && caption[0] != '\0')
8390 {
8391 strcpy (buf, caption);
8392 while (buf[0] != '\0' && buf[strlen (buf) -1] == '.')
8393 buf[strlen (buf)-1] = '\0';
8394 if (strlen (buf) <= max_lbl)
8395 caption = buf;
8396 }
8397
8398 if (strlen (caption) <= max_lbl)
8399 label = caption;
8400
8401 if (strlen (label) <= max_lbl && label[0] != '\0')
8402 {
8403 int i;
8404 if (label != buf) strcpy (buf, label);
8405
8406 for (i = 0; i < strlen (buf); ++i)
8407 {
8408 if (buf[i] == '-') buf[i] = ' ';
8409 }
8410 label = buf;
8411
8412 }
8413 else label = "";
8414
8415 new_lbl = Fupcase_initials (make_string (label, strlen (label)));
8416 if (SCHARS (new_lbl) <= tool_bar_max_label_size)
8417 PROP (TOOL_BAR_ITEM_LABEL) = new_lbl;
8418 }
8419
8367 /* If got a filter apply it on binding. */ 8420 /* If got a filter apply it on binding. */
8368 if (!NILP (filter)) 8421 if (!NILP (filter))
8369 PROP (TOOL_BAR_ITEM_BINDING) 8422 PROP (TOOL_BAR_ITEM_BINDING)
@@ -11699,6 +11752,8 @@ syms_of_keyboard ()
11699 staticpro (&QCtoggle); 11752 staticpro (&QCtoggle);
11700 QCradio = intern_c_string (":radio"); 11753 QCradio = intern_c_string (":radio");
11701 staticpro (&QCradio); 11754 staticpro (&QCradio);
11755 QClabel = intern_c_string (":label");
11756 staticpro (&QClabel);
11702 11757
11703 Qmode_line = intern_c_string ("mode-line"); 11758 Qmode_line = intern_c_string ("mode-line");
11704 staticpro (&Qmode_line); 11759 staticpro (&Qmode_line);
diff --git a/src/lisp.h b/src/lisp.h
index 357fc6fada3..84e2fad4483 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2635,7 +2635,7 @@ extern Lisp_Object Qinhibit_point_motion_hooks;
2635extern Lisp_Object Qinhibit_redisplay, Qdisplay; 2635extern Lisp_Object Qinhibit_redisplay, Qdisplay;
2636extern Lisp_Object Qinhibit_eval_during_redisplay; 2636extern Lisp_Object Qinhibit_eval_during_redisplay;
2637extern Lisp_Object Qmessage_truncate_lines; 2637extern Lisp_Object Qmessage_truncate_lines;
2638extern Lisp_Object Qimage; 2638extern Lisp_Object Qimage, Qtext, Qboth, Qboth_horiz;
2639extern Lisp_Object Vmessage_log_max; 2639extern Lisp_Object Vmessage_log_max;
2640extern int message_enable_multibyte; 2640extern int message_enable_multibyte;
2641extern Lisp_Object echo_area_buffer[2]; 2641extern Lisp_Object echo_area_buffer[2];
diff --git a/src/xdisp.c b/src/xdisp.c
index 3f590f3ccd9..a0f97acdcb1 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -357,6 +357,14 @@ EMACS_INT tool_bar_button_relief;
357 357
358Lisp_Object Vauto_resize_tool_bars; 358Lisp_Object Vauto_resize_tool_bars;
359 359
360/* Type of tool bar. Can be symbols image, text, both or both-hroiz. */
361
362Lisp_Object Vtool_bar_style;
363
364/* Maximum number of characters a label can have to be shown. */
365
366EMACS_INT tool_bar_max_label_size;
367
360/* Non-zero means draw block and hollow cursor as wide as the glyph 368/* Non-zero means draw block and hollow cursor as wide as the glyph
361 under it. For example, if a block cursor is over a tab, it will be 369 under it. For example, if a block cursor is over a tab, it will be
362 drawn as wide as that tab on the display. */ 370 drawn as wide as that tab on the display. */
@@ -442,7 +450,7 @@ Lisp_Object Qescape_glyph;
442Lisp_Object Qnobreak_space; 450Lisp_Object Qnobreak_space;
443 451
444/* The symbol `image' which is the car of the lists used to represent 452/* The symbol `image' which is the car of the lists used to represent
445 images in Lisp. */ 453 images in Lisp. Also a tool bar style. */
446 454
447Lisp_Object Qimage; 455Lisp_Object Qimage;
448 456
@@ -450,6 +458,9 @@ Lisp_Object Qimage;
450Lisp_Object QCmap, QCpointer; 458Lisp_Object QCmap, QCpointer;
451Lisp_Object Qrect, Qcircle, Qpoly; 459Lisp_Object Qrect, Qcircle, Qpoly;
452 460
461/* Tool bar styles */
462Lisp_Object Qtext, Qboth, Qboth_horiz;
463
453/* Non-zero means print newline to stdout before next mini-buffer 464/* Non-zero means print newline to stdout before next mini-buffer
454 message. */ 465 message. */
455 466
@@ -25781,6 +25792,12 @@ syms_of_xdisp ()
25781 staticpro (&Qnobreak_space); 25792 staticpro (&Qnobreak_space);
25782 Qimage = intern_c_string ("image"); 25793 Qimage = intern_c_string ("image");
25783 staticpro (&Qimage); 25794 staticpro (&Qimage);
25795 Qtext = intern_c_string ("text");
25796 staticpro (&Qtext);
25797 Qboth = intern_c_string ("both");
25798 staticpro (&Qboth);
25799 Qboth_horiz = intern_c_string ("both-horiz");
25800 staticpro (&Qboth_horiz);
25784 QCmap = intern_c_string (":map"); 25801 QCmap = intern_c_string (":map");
25785 staticpro (&QCmap); 25802 staticpro (&QCmap);
25786 QCpointer = intern_c_string (":pointer"); 25803 QCpointer = intern_c_string (":pointer");
@@ -26121,6 +26138,22 @@ vertical margin. */);
26121 doc: /* *Relief thickness of tool-bar buttons. */); 26138 doc: /* *Relief thickness of tool-bar buttons. */);
26122 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF; 26139 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
26123 26140
26141 DEFVAR_LISP ("tool-bar-style", &Vtool_bar_style,
26142 doc: /* *Tool bar style to use.
26143It can be one of
26144 image - show images only
26145 text - show text only
26146 both - show both, text under image
26147 both-horiz - show text to the right of the image
26148 any other - use system default or image if no system default. */);
26149 Vtool_bar_style = Qnil;
26150
26151 DEFVAR_INT ("tool-bar-max-label-size", &tool_bar_max_label_size,
26152 doc: /* *Maximum number of characters a label can have to be shown.
26153The tool bar style must also show labels for this to have any effect, see
26154`tool-bar-style'. */);
26155 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
26156
26124 DEFVAR_LISP ("fontification-functions", &Vfontification_functions, 26157 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
26125 doc: /* List of functions to call to fontify regions of text. 26158 doc: /* List of functions to call to fontify regions of text.
26126Each function is called with one argument POS. Functions must 26159Each function is called with one argument POS. Functions must
diff --git a/src/xsettings.c b/src/xsettings.c
index 1db7a24ebad..b30e79b904e 100644
--- a/src/xsettings.c
+++ b/src/xsettings.c
@@ -41,10 +41,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
41static char *current_mono_font; 41static char *current_mono_font;
42static char *current_font; 42static char *current_font;
43static struct x_display_info *first_dpyinfo; 43static struct x_display_info *first_dpyinfo;
44static Lisp_Object Qfont_name, Qfont_render; 44static Lisp_Object Qmonospace_font_name, Qfont_name, Qfont_render,
45 Qtool_bar_style;
45static int use_system_font; 46static int use_system_font;
46static Lisp_Object Vxft_settings; 47static Lisp_Object Vxft_settings;
47 48static Lisp_Object current_tool_bar_style;
48 49
49#ifdef HAVE_GCONF 50#ifdef HAVE_GCONF
50static GConfClient *gconf_client; 51static GConfClient *gconf_client;
@@ -52,7 +53,7 @@ static GConfClient *gconf_client;
52 53
53 54
54static void 55static void
55store_font_changed_event (arg, display_name) 56store_config_changed_event (arg, display_name)
56 Lisp_Object arg; 57 Lisp_Object arg;
57 Lisp_Object display_name; 58 Lisp_Object display_name;
58{ 59{
@@ -64,13 +65,38 @@ store_font_changed_event (arg, display_name)
64 kbd_buffer_store_event (&event); 65 kbd_buffer_store_event (&event);
65} 66}
66 67
67#define XSETTINGS_FONT_NAME "Gtk/FontName" 68#define XSETTINGS_FONT_NAME "Gtk/FontName"
69#define XSETTINGS_TOOL_BAR_STYLE "Gtk/ToolbarStyle"
68 70
69#ifdef HAVE_GCONF 71#ifdef HAVE_GCONF
70 72
71#define SYSTEM_MONO_FONT "/desktop/gnome/interface/monospace_font_name" 73#define SYSTEM_MONO_FONT "/desktop/gnome/interface/monospace_font_name"
72#define SYSTEM_FONT "/desktop/gnome/interface/font_name" 74#define SYSTEM_FONT "/desktop/gnome/interface/font_name"
73 75
76enum {
77 SEEN_AA = 0x01,
78 SEEN_HINTING = 0x02,
79 SEEN_RGBA = 0x04,
80 SEEN_LCDFILTER = 0x08,
81 SEEN_HINTSTYLE = 0x10,
82 SEEN_DPI = 0x20,
83 SEEN_FONT = 0x40,
84 SEEN_TB_STYLE = 0x80,
85};
86struct xsettings
87{
88#ifdef HAVE_XFT
89 FcBool aa, hinting;
90 int rgba, lcdfilter, hintstyle;
91 double dpi;
92#endif
93
94 char *font;
95 char *tb_style;
96
97 unsigned seen;
98};
99
74/* Callback called when something changed in GConf that we care about, 100/* Callback called when something changed in GConf that we care about,
75 that is SYSTEM_MONO_FONT. */ 101 that is SYSTEM_MONO_FONT. */
76 102
@@ -105,8 +131,8 @@ something_changedCB (client, cnxn_id, entry, user_data)
105 found = dpyinfo == first_dpyinfo; 131 found = dpyinfo == first_dpyinfo;
106 132
107 if (found && use_system_font) 133 if (found && use_system_font)
108 store_font_changed_event (Qfont_name, 134 store_config_changed_event (Qmonospace_font_name,
109 XCAR (first_dpyinfo->name_list_element)); 135 XCAR (first_dpyinfo->name_list_element));
110 } 136 }
111} 137}
112#endif /* HAVE_GCONF */ 138#endif /* HAVE_GCONF */
@@ -124,6 +150,8 @@ something_changedCB (client, cnxn_id, entry, user_data)
124#define FC_LCD_FILTER "lcdfilter" 150#define FC_LCD_FILTER "lcdfilter"
125#endif 151#endif
126 152
153#endif /* HAVE_XFT */
154
127/* Find the window that contains the XSETTINGS property values. */ 155/* Find the window that contains the XSETTINGS property values. */
128 156
129static void 157static void
@@ -144,23 +172,6 @@ get_prop_window (dpyinfo)
144 XUngrabServer (dpy); 172 XUngrabServer (dpy);
145} 173}
146 174
147enum {
148 SEEN_AA = 0x01,
149 SEEN_HINTING = 0x02,
150 SEEN_RGBA = 0x04,
151 SEEN_LCDFILTER = 0x08,
152 SEEN_HINTSTYLE = 0x10,
153 SEEN_DPI = 0x20,
154};
155struct xsettings
156{
157 FcBool aa, hinting;
158 int rgba, lcdfilter, hintstyle;
159 double dpi;
160
161 unsigned seen;
162};
163
164#define SWAP32(nr) (((nr) << 24) | (((nr) << 8) & 0xff0000) \ 175#define SWAP32(nr) (((nr) << 24) | (((nr) << 8) & 0xff0000) \
165 | (((nr) >> 8) & 0xff00) | ((nr) >> 24)) 176 | (((nr) >> 8) & 0xff00) | ((nr) >> 24))
166#define SWAP16(nr) (((nr) << 8) | ((nr) >> 8)) 177#define SWAP16(nr) (((nr) << 8) | ((nr) >> 8))
@@ -217,7 +228,7 @@ struct xsettings
217*/ 228*/
218 229
219static int 230static int
220parse_xft_settings (prop, bytes, settings) 231parse_settings (prop, bytes, settings)
221 unsigned char *prop; 232 unsigned char *prop;
222 unsigned long bytes; 233 unsigned long bytes;
223 struct xsettings *settings; 234 struct xsettings *settings;
@@ -268,8 +279,13 @@ parse_xft_settings (prop, bytes, settings)
268 bytes_parsed += 4; /* Skip serial for this value */ 279 bytes_parsed += 4; /* Skip serial for this value */
269 if (bytes_parsed > bytes) return BadLength; 280 if (bytes_parsed > bytes) return BadLength;
270 281
271 want_this = (nlen > 6 && strncmp (name, "Xft/", 4) == 0) 282 want_this =
272 || (strcmp (XSETTINGS_FONT_NAME, name) == 0); 283#ifdef HAVE_XFT
284 (nlen > 6 && strncmp (name, "Xft/", 4) == 0)
285 ||
286#endif
287 (strcmp (XSETTINGS_FONT_NAME, name) == 0)
288 || (strcmp (XSETTINGS_TOOL_BAR_STYLE, name) == 0);
273 289
274 switch (type) 290 switch (type)
275 { 291 {
@@ -311,7 +327,18 @@ parse_xft_settings (prop, bytes, settings)
311 if (want_this) 327 if (want_this)
312 { 328 {
313 ++settings_seen; 329 ++settings_seen;
314 if (strcmp (name, "Xft/Antialias") == 0) 330 if (strcmp (name, XSETTINGS_FONT_NAME) == 0)
331 {
332 settings->font = xstrdup (sval);
333 settings->seen |= SEEN_FONT;
334 }
335 else if (strcmp (name, XSETTINGS_TOOL_BAR_STYLE) == 0)
336 {
337 settings->tb_style = xstrdup (sval);
338 settings->seen |= SEEN_TB_STYLE;
339 }
340#ifdef HAVE_XFT
341 else if (strcmp (name, "Xft/Antialias") == 0)
315 { 342 {
316 settings->seen |= SEEN_AA; 343 settings->seen |= SEEN_AA;
317 settings->aa = ival != 0; 344 settings->aa = ival != 0;
@@ -366,11 +393,7 @@ parse_xft_settings (prop, bytes, settings)
366 else 393 else
367 settings->seen &= ~SEEN_LCDFILTER; 394 settings->seen &= ~SEEN_LCDFILTER;
368 } 395 }
369 else if (strcmp (name, XSETTINGS_FONT_NAME) == 0) 396#endif /* HAVE_XFT */
370 {
371 free (current_font);
372 current_font = xstrdup (sval);
373 }
374 } 397 }
375 } 398 }
376 399
@@ -378,7 +401,7 @@ parse_xft_settings (prop, bytes, settings)
378} 401}
379 402
380static int 403static int
381read_xft_settings (dpyinfo, settings) 404read_settings (dpyinfo, settings)
382 struct x_display_info *dpyinfo; 405 struct x_display_info *dpyinfo;
383 struct xsettings *settings; 406 struct xsettings *settings;
384{ 407{
@@ -400,7 +423,7 @@ read_xft_settings (dpyinfo, settings)
400 423
401 if (rc == Success && prop != NULL && act_form == 8 && nitems > 0 424 if (rc == Success && prop != NULL && act_form == 8 && nitems > 0
402 && act_type == dpyinfo->Xatom_xsettings_prop) 425 && act_type == dpyinfo->Xatom_xsettings_prop)
403 rc = parse_xft_settings (prop, nitems, settings); 426 rc = parse_settings (prop, nitems, settings);
404 427
405 XFree (prop); 428 XFree (prop);
406 429
@@ -411,18 +434,17 @@ read_xft_settings (dpyinfo, settings)
411 434
412 435
413static void 436static void
414apply_xft_settings (dpyinfo, send_event_p) 437apply_xft_settings (dpyinfo, send_event_p, settings)
415 struct x_display_info *dpyinfo; 438 struct x_display_info *dpyinfo;
416 int send_event_p; 439 int send_event_p;
440 struct xsettings *settings;
417{ 441{
442#ifdef HAVE_XFT
418 FcPattern *pat; 443 FcPattern *pat;
419 struct xsettings settings, oldsettings; 444 struct xsettings oldsettings;
420 int changed = 0; 445 int changed = 0;
421 char buf[256]; 446 char buf[256];
422 447
423 if (!read_xft_settings (dpyinfo, &settings))
424 return;
425
426 memset (&oldsettings, 0, sizeof (oldsettings)); 448 memset (&oldsettings, 0, sizeof (oldsettings));
427 buf[0] = '\0'; 449 buf[0] = '\0';
428 pat = FcPatternCreate (); 450 pat = FcPatternCreate ();
@@ -436,74 +458,74 @@ apply_xft_settings (dpyinfo, send_event_p)
436 FcPatternGetInteger (pat, FC_RGBA, 0, &oldsettings.rgba); 458 FcPatternGetInteger (pat, FC_RGBA, 0, &oldsettings.rgba);
437 FcPatternGetDouble (pat, FC_DPI, 0, &oldsettings.dpi); 459 FcPatternGetDouble (pat, FC_DPI, 0, &oldsettings.dpi);
438 460
439 if ((settings.seen & SEEN_AA) != 0 && oldsettings.aa != settings.aa) 461 if ((settings->seen & SEEN_AA) != 0 && oldsettings.aa != settings->aa)
440 { 462 {
441 FcPatternDel (pat, FC_ANTIALIAS); 463 FcPatternDel (pat, FC_ANTIALIAS);
442 FcPatternAddBool (pat, FC_ANTIALIAS, settings.aa); 464 FcPatternAddBool (pat, FC_ANTIALIAS, settings->aa);
443 ++changed; 465 ++changed;
444 oldsettings.aa = settings.aa; 466 oldsettings.aa = settings->aa;
445 } 467 }
446 sprintf (buf, "Antialias: %d", oldsettings.aa); 468 sprintf (buf, "Antialias: %d", oldsettings.aa);
447 469
448 if ((settings.seen & SEEN_HINTING) != 0 470 if ((settings->seen & SEEN_HINTING) != 0
449 && oldsettings.hinting != settings.hinting) 471 && oldsettings.hinting != settings->hinting)
450 { 472 {
451 FcPatternDel (pat, FC_HINTING); 473 FcPatternDel (pat, FC_HINTING);
452 FcPatternAddBool (pat, FC_HINTING, settings.hinting); 474 FcPatternAddBool (pat, FC_HINTING, settings->hinting);
453 ++changed; 475 ++changed;
454 oldsettings.hinting = settings.hinting; 476 oldsettings.hinting = settings->hinting;
455 } 477 }
456 if (strlen (buf) > 0) strcat (buf, ", "); 478 if (strlen (buf) > 0) strcat (buf, ", ");
457 sprintf (buf+strlen (buf), "Hinting: %d", oldsettings.hinting); 479 sprintf (buf+strlen (buf), "Hinting: %d", oldsettings.hinting);
458 if ((settings.seen & SEEN_RGBA) != 0 && oldsettings.rgba != settings.rgba) 480 if ((settings->seen & SEEN_RGBA) != 0 && oldsettings.rgba != settings->rgba)
459 { 481 {
460 FcPatternDel (pat, FC_RGBA); 482 FcPatternDel (pat, FC_RGBA);
461 FcPatternAddInteger (pat, FC_RGBA, settings.rgba); 483 FcPatternAddInteger (pat, FC_RGBA, settings->rgba);
462 oldsettings.rgba = settings.rgba; 484 oldsettings.rgba = settings->rgba;
463 ++changed; 485 ++changed;
464 } 486 }
465 if (strlen (buf) > 0) strcat (buf, ", "); 487 if (strlen (buf) > 0) strcat (buf, ", ");
466 sprintf (buf+strlen (buf), "RGBA: %d", oldsettings.rgba); 488 sprintf (buf+strlen (buf), "RGBA: %d", oldsettings.rgba);
467 489
468 /* Older fontconfig versions don't have FC_LCD_FILTER. */ 490 /* Older fontconfig versions don't have FC_LCD_FILTER. */
469 if ((settings.seen & SEEN_LCDFILTER) != 0 491 if ((settings->seen & SEEN_LCDFILTER) != 0
470 && oldsettings.lcdfilter != settings.lcdfilter) 492 && oldsettings.lcdfilter != settings->lcdfilter)
471 { 493 {
472 FcPatternDel (pat, FC_LCD_FILTER); 494 FcPatternDel (pat, FC_LCD_FILTER);
473 FcPatternAddInteger (pat, FC_LCD_FILTER, settings.lcdfilter); 495 FcPatternAddInteger (pat, FC_LCD_FILTER, settings->lcdfilter);
474 ++changed; 496 ++changed;
475 oldsettings.lcdfilter = settings.lcdfilter; 497 oldsettings.lcdfilter = settings->lcdfilter;
476 } 498 }
477 if (strlen (buf) > 0) strcat (buf, ", "); 499 if (strlen (buf) > 0) strcat (buf, ", ");
478 sprintf (buf+strlen (buf), "LCDFilter: %d", oldsettings.lcdfilter); 500 sprintf (buf+strlen (buf), "LCDFilter: %d", oldsettings.lcdfilter);
479 501
480 if ((settings.seen & SEEN_HINTSTYLE) != 0 502 if ((settings->seen & SEEN_HINTSTYLE) != 0
481 && oldsettings.hintstyle != settings.hintstyle) 503 && oldsettings.hintstyle != settings->hintstyle)
482 { 504 {
483 FcPatternDel (pat, FC_HINT_STYLE); 505 FcPatternDel (pat, FC_HINT_STYLE);
484 FcPatternAddInteger (pat, FC_HINT_STYLE, settings.hintstyle); 506 FcPatternAddInteger (pat, FC_HINT_STYLE, settings->hintstyle);
485 ++changed; 507 ++changed;
486 oldsettings.hintstyle = settings.hintstyle; 508 oldsettings.hintstyle = settings->hintstyle;
487 } 509 }
488 if (strlen (buf) > 0) strcat (buf, ", "); 510 if (strlen (buf) > 0) strcat (buf, ", ");
489 sprintf (buf+strlen (buf), "Hintstyle: %d", oldsettings.hintstyle); 511 sprintf (buf+strlen (buf), "Hintstyle: %d", oldsettings.hintstyle);
490 512
491 if ((settings.seen & SEEN_DPI) != 0 && oldsettings.dpi != settings.dpi 513 if ((settings->seen & SEEN_DPI) != 0 && oldsettings.dpi != settings->dpi
492 && settings.dpi > 0) 514 && settings->dpi > 0)
493 { 515 {
494 Lisp_Object frame, tail; 516 Lisp_Object frame, tail;
495 517
496 FcPatternDel (pat, FC_DPI); 518 FcPatternDel (pat, FC_DPI);
497 FcPatternAddDouble (pat, FC_DPI, settings.dpi); 519 FcPatternAddDouble (pat, FC_DPI, settings->dpi);
498 ++changed; 520 ++changed;
499 oldsettings.dpi = settings.dpi; 521 oldsettings.dpi = settings->dpi;
500 522
501 /* Change the DPI on this display and all frames on the display. */ 523 /* Change the DPI on this display and all frames on the display. */
502 dpyinfo->resy = dpyinfo->resx = settings.dpi; 524 dpyinfo->resy = dpyinfo->resx = settings->dpi;
503 FOR_EACH_FRAME (tail, frame) 525 FOR_EACH_FRAME (tail, frame)
504 if (FRAME_X_P (XFRAME (frame)) 526 if (FRAME_X_P (XFRAME (frame))
505 && FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo) 527 && FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
506 XFRAME (frame)->resy = XFRAME (frame)->resx = settings.dpi; 528 XFRAME (frame)->resy = XFRAME (frame)->resx = settings->dpi;
507 } 529 }
508 530
509 if (strlen (buf) > 0) strcat (buf, ", "); 531 if (strlen (buf) > 0) strcat (buf, ", ");
@@ -513,23 +535,68 @@ apply_xft_settings (dpyinfo, send_event_p)
513 { 535 {
514 XftDefaultSet (dpyinfo->display, pat); 536 XftDefaultSet (dpyinfo->display, pat);
515 if (send_event_p) 537 if (send_event_p)
516 store_font_changed_event (Qfont_render, 538 store_config_changed_event (Qfont_render,
517 XCAR (dpyinfo->name_list_element)); 539 XCAR (dpyinfo->name_list_element));
518 Vxft_settings = make_string (buf, strlen (buf)); 540 Vxft_settings = make_string (buf, strlen (buf));
519 } 541 }
520 else 542 else
521 FcPatternDestroy (pat); 543 FcPatternDestroy (pat);
544#endif /* HAVE_XFT */
522} 545}
523 546
524#endif /* HAVE_XFT */ 547static void
548read_and_apply_settings (dpyinfo, send_event_p)
549 struct x_display_info *dpyinfo;
550 int send_event_p;
551{
552 struct xsettings settings;
553 Lisp_Object dpyname = XCAR (dpyinfo->name_list_element);
554
555 if (!read_settings (dpyinfo, &settings))
556 return;
557
558 apply_xft_settings (dpyinfo, True, &settings);
559 if (settings.seen & SEEN_TB_STYLE)
560 {
561 Lisp_Object style = Qnil;
562 if (strcmp (settings.tb_style, "both") == 0)
563 style = Qboth;
564 else if (strcmp (settings.tb_style, "both-horiz") == 0)
565 style = Qboth_horiz;
566 else if (strcmp (settings.tb_style, "icons") == 0)
567 style = Qimage;
568 else if (strcmp (settings.tb_style, "text") == 0)
569 style = Qtext;
570 if (!NILP (style) && !EQ (style, current_tool_bar_style))
571 {
572 current_tool_bar_style = style;
573 if (send_event_p)
574 store_config_changed_event (Qtool_bar_style, dpyname);
575 }
576 free (settings.tb_style);
577 }
578
579 if (settings.seen & SEEN_FONT)
580 {
581 if (strcmp (current_font, settings.font) != 0)
582 {
583 free (current_font);
584 current_font = settings.font;
585 if (send_event_p)
586 store_config_changed_event (Qfont_name, dpyname);
587 }
588 else
589 free (settings.font);
590 }
591}
525 592
526void 593void
527xft_settings_event (dpyinfo, event) 594xft_settings_event (dpyinfo, event)
528 struct x_display_info *dpyinfo; 595 struct x_display_info *dpyinfo;
529 XEvent *event; 596 XEvent *event;
530{ 597{
531#ifdef HAVE_XFT
532 int check_window_p = 0; 598 int check_window_p = 0;
599 int apply_settings = 0;
533 600
534 switch (event->type) 601 switch (event->type)
535 { 602 {
@@ -549,20 +616,21 @@ xft_settings_event (dpyinfo, event)
549 if (event->xproperty.window == dpyinfo->xsettings_window 616 if (event->xproperty.window == dpyinfo->xsettings_window
550 && event->xproperty.state == PropertyNewValue 617 && event->xproperty.state == PropertyNewValue
551 && event->xproperty.atom == dpyinfo->Xatom_xsettings_prop) 618 && event->xproperty.atom == dpyinfo->Xatom_xsettings_prop)
552 { 619 apply_settings = 1;
553 apply_xft_settings (dpyinfo, True);
554 }
555 break; 620 break;
556 } 621 }
557 622
623
558 if (check_window_p) 624 if (check_window_p)
559 { 625 {
560 dpyinfo->xsettings_window = None; 626 dpyinfo->xsettings_window = None;
561 get_prop_window (dpyinfo); 627 get_prop_window (dpyinfo);
562 if (dpyinfo->xsettings_window != None) 628 if (dpyinfo->xsettings_window != None)
563 apply_xft_settings (dpyinfo, True); 629 apply_settings = 1;
564 } 630 }
565#endif /* HAVE_XFT */ 631
632 if (apply_settings)
633 read_and_apply_settings (dpyinfo, True);
566} 634}
567 635
568 636
@@ -600,10 +668,9 @@ init_gconf ()
600} 668}
601 669
602static void 670static void
603init_xfd_settings (dpyinfo) 671init_xsettings (dpyinfo)
604 struct x_display_info *dpyinfo; 672 struct x_display_info *dpyinfo;
605{ 673{
606#ifdef HAVE_XFT
607 char sel[64]; 674 char sel[64];
608 Display *dpy = dpyinfo->display; 675 Display *dpy = dpyinfo->display;
609 676
@@ -622,18 +689,9 @@ init_xfd_settings (dpyinfo)
622 689
623 get_prop_window (dpyinfo); 690 get_prop_window (dpyinfo);
624 if (dpyinfo->xsettings_window != None) 691 if (dpyinfo->xsettings_window != None)
625 apply_xft_settings (dpyinfo, False); 692 read_and_apply_settings (dpyinfo, False);
626 693
627 UNBLOCK_INPUT; 694 UNBLOCK_INPUT;
628
629#else /* ! HAVE_XFT */
630
631 dpyinfo->Xatom_xsettings_sel = None;
632 dpyinfo->Xatom_xsettings_prop = None;
633 dpyinfo->Xatom_xsettings_mgr = None;
634 dpyinfo->xsettings_window = None;
635
636#endif /* ! HAVE_XFT */
637} 695}
638 696
639void 697void
@@ -642,7 +700,7 @@ xsettings_initialize (dpyinfo)
642{ 700{
643 if (first_dpyinfo == NULL) first_dpyinfo = dpyinfo; 701 if (first_dpyinfo == NULL) first_dpyinfo = dpyinfo;
644 init_gconf (); 702 init_gconf ();
645 init_xfd_settings (dpyinfo); 703 init_xsettings (dpyinfo);
646} 704}
647 705
648const char * 706const char *
@@ -678,6 +736,23 @@ DEFUN ("font-get-system-font", Ffont_get_system_font, Sfont_get_system_font,
678 : Qnil; 736 : Qnil;
679} 737}
680 738
739DEFUN ("tool-bar-get-system-style", Ftool_bar_get_system_style, Stool_bar_get_system_style,
740 0, 0, 0,
741 doc: /* Get the system tool bar style.
742If no system tool bar style is known, return `tool-bar-style' is set to a
743known style. Otherwise return image. */)
744 ()
745{
746 if (EQ (Vtool_bar_style, Qimage)
747 || EQ (Vtool_bar_style, Qtext)
748 || EQ (Vtool_bar_style, Qboth)
749 || EQ (Vtool_bar_style, Qboth_horiz))
750 return Vtool_bar_style;
751 if (!NILP (current_tool_bar_style))
752 return current_tool_bar_style;
753 return Qimage;
754}
755
681void 756void
682syms_of_xsettings () 757syms_of_xsettings ()
683{ 758{
@@ -688,6 +763,8 @@ syms_of_xsettings ()
688 gconf_client = NULL; 763 gconf_client = NULL;
689#endif 764#endif
690 765
766 Qmonospace_font_name = intern_c_string ("monospace-font-name");
767 staticpro (&Qmonospace_font_name);
691 Qfont_name = intern_c_string ("font-name"); 768 Qfont_name = intern_c_string ("font-name");
692 staticpro (&Qfont_name); 769 staticpro (&Qfont_name);
693 Qfont_render = intern_c_string ("font-render"); 770 Qfont_render = intern_c_string ("font-render");
@@ -709,6 +786,13 @@ syms_of_xsettings ()
709 Fprovide (intern_c_string ("system-font-setting"), Qnil); 786 Fprovide (intern_c_string ("system-font-setting"), Qnil);
710#endif 787#endif
711#endif 788#endif
789
790 current_tool_bar_style = Qnil;
791 Qtool_bar_style = intern_c_string ("tool-bar-style");
792 staticpro (&Qtool_bar_style);
793 defsubr (&Stool_bar_get_system_style);
794
795 Fprovide (intern_c_string ("dynamic-setting"), Qnil);
712} 796}
713 797
714/* arch-tag: 541716ed-2e6b-42e1-8212-3197e01ea61d 798/* arch-tag: 541716ed-2e6b-42e1-8212-3197e01ea61d
diff --git a/src/xsettings.h b/src/xsettings.h
index f6399ea1bcc..53fca2ad6b5 100644
--- a/src/xsettings.h
+++ b/src/xsettings.h
@@ -22,6 +22,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22 22
23EXFUN (Ffont_get_system_font, 0); 23EXFUN (Ffont_get_system_font, 0);
24EXFUN (Ffont_get_system_normal_font, 0); 24EXFUN (Ffont_get_system_normal_font, 0);
25EXFUN (Ftool_bar_get_system_style, 0);
25 26
26extern void xsettings_initialize P_ ((struct x_display_info *dpyinfo)); 27extern void xsettings_initialize P_ ((struct x_display_info *dpyinfo));
27extern void xft_settings_event P_ ((struct x_display_info *dpyinfo, 28extern void xft_settings_event P_ ((struct x_display_info *dpyinfo,
diff --git a/src/xterm.c b/src/xterm.c
index 712d4aaa162..4f191922561 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -2322,10 +2322,13 @@ x_draw_image_relief (s)
2322 raised_p = s->img->relief > 0; 2322 raised_p = s->img->relief > 0;
2323 } 2323 }
2324 2324
2325 x0 = x - thick; 2325 int extra = s->face->id == TOOL_BAR_FACE_ID
2326 y0 = y - thick; 2326 ? XINT (Vtool_bar_button_margin) : 0;
2327 x1 = x + s->slice.width + thick - 1; 2327
2328 y1 = y + s->slice.height + thick - 1; 2328 x0 = x - thick - extra;
2329 y0 = y - thick - extra;
2330 x1 = x + s->slice.width + thick - 1 + extra;
2331 y1 = y + s->slice.height + thick - 1 + extra;
2329 2332
2330 x_setup_relief_colors (s); 2333 x_setup_relief_colors (s);
2331 get_glyph_string_clip_rect (s, &r); 2334 get_glyph_string_clip_rect (s, &r);