diff src/xdisp.c @ 83484:a380ca43a190

Merged from emacs@sv.gnu.org Patches applied: * emacs@sv.gnu.org/emacs--devo--0--patch-128 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-129 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-130 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-131 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-132 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-133 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-134 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-135 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-43 Munge arch explicit ids in etc/images to match Emacs * emacs@sv.gnu.org/gnus--rel--5.10--patch-44 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-45 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-46 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-47 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-48 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-524
author Karoly Lorentey <lorentey@elte.hu>
date Sat, 04 Mar 2006 23:07:13 +0000
parents d08a7ef0cb8a b3f04bf9fce0
children 414faf8dce4e
line wrap: on
line diff
--- a/src/xdisp.c	Tue Feb 28 17:35:08 2006 +0000
+++ b/src/xdisp.c	Sat Mar 04 23:07:13 2006 +0000
@@ -269,6 +269,12 @@
 
 int make_cursor_line_fully_visible_p;
 
+/* Margin below tool bar in pixels.  0 or nil means no margin.
+   If value is `internal-border-width' or `border-width',
+   the corresponding frame parameter is used.  */
+
+Lisp_Object Vtool_bar_border;
+
 /* Margin around tool bar buttons in pixels.  */
 
 Lisp_Object Vtool_bar_button_margin;
@@ -839,7 +845,7 @@
 static int store_mode_line_noprop P_ ((const unsigned char *, int, int));
 static void x_consider_frame_title P_ ((Lisp_Object));
 static void handle_stop P_ ((struct it *));
-static int tool_bar_lines_needed P_ ((struct frame *));
+static int tool_bar_lines_needed P_ ((struct frame *, int *));
 static int single_display_spec_intangible_p P_ ((Lisp_Object));
 static void ensure_echo_area_buffers P_ ((void));
 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
@@ -950,7 +956,7 @@
 static void update_tool_bar P_ ((struct frame *, int));
 static void build_desired_tool_bar_string P_ ((struct frame *f));
 static int redisplay_tool_bar P_ ((struct frame *));
-static void display_tool_bar_line P_ ((struct it *));
+static void display_tool_bar_line P_ ((struct it *, int));
 static void notice_overwritten_cursor P_ ((struct window *,
 					   enum glyph_row_area,
 					   int, int, int, int));
@@ -9429,11 +9435,17 @@
 }
 
 
-/* Display one line of the tool-bar of frame IT->f.  */
-
-static void
-display_tool_bar_line (it)
-     struct it *it;
+/* Display one line of the tool-bar of frame IT->f.
+
+   HEIGHT specifies the desired height of the tool-bar line.
+   If the actual height of the glyph row is less than HEIGHT, the
+   row's height is increased to HEIGHT, and the icons are centered
+   vertically in the new height.  */
+
+static void
+display_tool_bar_line (it, height)
+     struct it *it;
+     int height;
 {
   struct glyph_row *row = it->glyph_row;
   int max_x = it->last_visible_x;
@@ -9489,11 +9501,22 @@
  out:;
 
   row->displays_text_p = row->used[TEXT_AREA] != 0;
+  /* Use default face for the border below the tool bar.  */
+  if (!row->displays_text_p)
+    it->face_id = DEFAULT_FACE_ID;
   extend_face_to_end_of_line (it);
   last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
   last->right_box_line_p = 1;
   if (last == row->glyphs[TEXT_AREA])
     last->left_box_line_p = 1;
+
+  /* Make line the desired height and center it vertically.  */
+  if ((height -= it->max_ascent + it->max_descent) > 0)
+    {
+      it->max_ascent += height / 2;
+      it->max_descent += (height + 1) / 2;
+    }
+
   compute_line_metrics (it);
 
   /* If line is empty, make it occupy the rest of the tool-bar.  */
@@ -9517,11 +9540,13 @@
 
 
 /* Value is the number of screen lines needed to make all tool-bar
-   items of frame F visible.  */
-
-static int
-tool_bar_lines_needed (f)
+   items of frame F visible.  The number of actual rows needed is
+   returned in *N_ROWS if non-NULL.  */
+
+static int
+tool_bar_lines_needed (f, n_rows)
      struct frame *f;
+     int *n_rows;
 {
   struct window *w = XWINDOW (f->tool_bar_window);
   struct it it;
@@ -9537,8 +9562,11 @@
     {
       it.glyph_row = w->desired_matrix->rows;
       clear_glyph_row (it.glyph_row);
-      display_tool_bar_line (&it);
-    }
+      display_tool_bar_line (&it, 0);
+    }
+
+  if (n_rows)
+    *n_rows = it.vpos;
 
   return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
 }
@@ -9568,7 +9596,7 @@
       if (f->n_tool_bar_items)
 	{
 	  build_desired_tool_bar_string (f);
-	  nlines = tool_bar_lines_needed (f);
+	  nlines = tool_bar_lines_needed (f, NULL);
 	}
     }
 
@@ -9613,9 +9641,50 @@
   build_desired_tool_bar_string (f);
   reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
 
+  if (f->n_tool_bar_rows == 0)
+    {
+      (void)tool_bar_lines_needed (f, &f->n_tool_bar_rows);
+      if (f->n_tool_bar_rows == 0)
+	f->n_tool_bar_rows = -1;
+    }
+
   /* Display as many lines as needed to display all tool-bar items.  */
-  while (it.current_y < it.last_visible_y)
-    display_tool_bar_line (&it);
+
+  if (f->n_tool_bar_rows > 0)
+    {
+      int border, rows, height, extra;
+
+      if (INTEGERP (Vtool_bar_border))
+	border = XINT (Vtool_bar_border);
+      else if (EQ (Vtool_bar_border, Qinternal_border_width))
+	border = FRAME_INTERNAL_BORDER_WIDTH (f);
+      else if (EQ (Vtool_bar_border, Qborder_width))
+	border = f->border_width;
+      else
+	border = 0;
+      if (border < 0)
+	border = 0;
+
+      rows = f->n_tool_bar_rows;
+      height = (it.last_visible_y - border) / rows;
+      extra = it.last_visible_y - border - height * rows;
+
+      while (it.current_y < it.last_visible_y)
+	{
+	  int h = 0;
+	  if (extra > 0 && rows-- > 0)
+	    {
+	      h = (extra + rows - 1) / rows;
+	      extra -= h;
+	    }
+	  display_tool_bar_line (&it, height + h);
+	}
+    }
+  else
+    {
+      while (it.current_y < it.last_visible_y)
+	display_tool_bar_line (&it, 0);
+    }
 
   /* It doesn't make much sense to try scrolling in the tool-bar
      window, so don't do it.  */
@@ -9648,7 +9717,7 @@
       /* Resize windows as needed by changing the `tool-bar-lines'
 	 frame parameter.  */
       if (change_height_p
-	  && (nlines = tool_bar_lines_needed (f),
+	  && (nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
 	      nlines != WINDOW_TOTAL_LINES (w)))
 	{
 	  extern Lisp_Object Qtool_bar_lines;
@@ -23661,6 +23730,14 @@
     doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible.  */);
   make_cursor_line_fully_visible_p = 1;
 
+  DEFVAR_LISP ("tool-bar-border", &Vtool_bar_border,
+    doc: /* *Border below tool-bar in pixels.
+If an integer, use it as the height of the border.
+If it is one of `internal-border-width' or `border-width', use the
+value of the corresponding frame parameter.
+Otherwise, no border is added below the tool-bar.  */);
+  Vtool_bar_border = Qinternal_border_width;
+
   DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
     doc: /* *Margin around tool-bar buttons in pixels.
 If an integer, use that for both horizontal and vertical margins.