]> code.delx.au - gnu-emacs/blobdiff - src/xterm.c
(expose_window): Don't redraw the window that's
[gnu-emacs] / src / xterm.c
index c4affa4a883c876c74d32fea07ada6322586eec1..d45dfd8c7e1856b3a646848afb88773c1129d5cd 100644 (file)
@@ -1139,19 +1139,6 @@ static void x_produce_glyphs P_ ((struct it *));
 static void x_produce_image_glyph P_ ((struct it *it));
 
 
-/* Return a pointer to per-char metric information in FONT of a
-   character pointed by B which is a pointer to an XChar2b.  */
-
-#define PER_CHAR_METRIC(font, b)                                          \
-  ((font)->per_char                                                       \
-   ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2                   \
-      + (((font)->min_byte1 || (font)->max_byte1)                         \
-        ? (((b)->byte1 - (font)->min_byte1)                               \
-           * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
-        : 0))                                                             \
-   : &((font)->max_bounds))
-
-
 /* Get metrics of character CHAR2B in FONT.  Value is null if CHAR2B
    is not contained in the font.  */
 
@@ -1775,10 +1762,11 @@ x_produce_stretch_glyph (it)
        F_HEIGHT = FRAME_LINE_HEIGHT (F)
 */
 
-#define VCENTER_BASELINE_OFFSET(FONT, F)               \
- ((FONT)->descent                                              \
-  + (FRAME_LINE_HEIGHT ((F)) + 1 - FONT_HEIGHT ((FONT))) / 2   \
-  - ((F)->output_data.x->font->descent - (F)->output_data.x->baseline_offset))
+#define VCENTER_BASELINE_OFFSET(FONT, F)                       \
+  ((FONT)->descent                                             \
+   + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT))           \
+      + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2  \
+   - ((F)->output_data.x->font->descent - (F)->output_data.x->baseline_offset))
 
 /* Produce glyphs/get display metrics for the display element IT is
    loaded with.  See the description of struct display_iterator in
@@ -2107,8 +2095,8 @@ x_produce_glyphs (it)
          cmp->font = (void *) font;
 
          /* Initialize the bounding box.  */
-         pcm = x_per_char_metric (font, &char2b);
-         if (pcm)
+         if (font_info
+             && (pcm = x_per_char_metric (font, &char2b)))
            {
              width = pcm->width;
              ascent = pcm->ascent;
@@ -2165,8 +2153,8 @@ x_produce_glyphs (it)
                    boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
                }
 
-             pcm = x_per_char_metric (font, &char2b);
-             if (pcm)
+             if (font_info
+                 && (pcm = x_per_char_metric (font, &char2b)))
                {
                  width = pcm->width;
                  ascent = pcm->ascent;
@@ -2175,8 +2163,8 @@ x_produce_glyphs (it)
              else
                {
                  width = FONT_WIDTH (font);
-                 ascent = font->ascent;
-                 descent = font->descent;
+                 ascent = 1;
+                 descent = 0;
                }
 
              if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
@@ -2325,7 +2313,7 @@ x_estimate_mode_line_height (f, face_id)
      struct frame *f;
      enum face_id face_id;
 {
-  int height = 1;
+  int height = FONT_HEIGHT (FRAME_FONT (f));
 
   /* This function is called so early when Emacs starts that the face
      cache and mode line face are not yet initialized.  */
@@ -2333,7 +2321,11 @@ x_estimate_mode_line_height (f, face_id)
       {
        struct face *face = FACE_FROM_ID (f, face_id);
        if (face)
-         height = FONT_HEIGHT (face->font) + 2 * face->box_line_width;
+         {
+           if (face->font)
+             height = FONT_HEIGHT (face->font);
+           height += 2 * face->box_line_width;
+         }
       }
   
   return height;
@@ -3412,6 +3404,25 @@ x_alloc_nearest_color (f, cmap, color)
       color->blue  = cells[nearest].blue;
       rc = XAllocColor (display, cmap, color);
     }
+  else
+    {
+      /* If allocation succeeded, and the allocated pixel color is not
+         equal to a cached pixel color recorded earlier, there was a
+         change in the colormap, so clear the color cache.  */
+      struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+      XColor *cached_color;
+      
+      if (dpyinfo->color_cells
+         && (cached_color = &dpyinfo->color_cells[color->pixel],
+             (cached_color->red != color->red
+              || cached_color->blue != color->blue
+              || cached_color->green != color->green)))
+       {
+         xfree (dpyinfo->color_cells);
+         dpyinfo->color_cells = NULL;
+         dpyinfo->ncolor_cells = 0;
+       }
+    }
 
 #ifdef DEBUG_X_COLORS
   if (rc)
@@ -3469,6 +3480,20 @@ x_copy_dpy_color (dpy, cmap, pixel)
 }
 
 
+/* Brightness beyond which a color won't have its highlight brightness
+   boosted.
+
+   Nominally, highlight colors for `3d' faces are calculated by
+   brightening an object's color by a constant scale factor, but this
+   doesn't yield good results for dark colors, so for colors who's
+   brightness is less than this value (on a scale of 0-65535) have an
+   use an additional additive factor.
+
+   The value here is set so that the default menu-bar/mode-line color
+   (grey75) will not have its highlights changed at all.  */
+#define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 48000
+
+
 /* Allocate a color which is lighter or darker than *PIXEL by FACTOR
    or DELTA.  Try a color with RGB values multiplied by FACTOR first.
    If this produces the same color as PIXEL, try a color where all RGB
@@ -3486,6 +3511,7 @@ x_alloc_lighter_color (f, display, cmap, pixel, factor, delta)
      int delta;
 {
   XColor color, new;
+  long bright;
   int success_p;
 
   /* Get RGB color values.  */
@@ -3498,6 +3524,34 @@ x_alloc_lighter_color (f, display, cmap, pixel, factor, delta)
   new.green = min (0xffff, factor * color.green);
   new.blue = min (0xffff, factor * color.blue);
 
+  /* Calculate brightness of COLOR.  */
+  bright = (2 * color.red + 3 * color.green + color.blue) / 6;
+
+  /* We only boost colors that are darker than
+     HIGHLIGHT_COLOR_DARK_BOOST_LIMIT.  */
+  if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
+    /* Make an additive adjustment to NEW, because it's dark enough so
+       that scaling by FACTOR alone isn't enough.  */
+    {
+      /* How far below the limit this color is (0 - 1, 1 being darker).  */
+      double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
+      /* The additive adjustment.  */
+      int min_delta = delta * dimness * factor / 2;
+
+      if (factor < 1)
+       {
+         new.red =   max (0, new.red -   min_delta);
+         new.green = max (0, new.green - min_delta);
+         new.blue =  max (0, new.blue -  min_delta);
+       }
+      else
+       {
+         new.red =   min (0xffff, min_delta + new.red);
+         new.green = min (0xffff, min_delta + new.green);
+         new.blue =  min (0xffff, min_delta + new.blue);
+       }
+    }
+
   /* Try to allocate the color.  */
   success_p = x_alloc_nearest_color (f, cmap, &new);
   if (success_p)
@@ -4217,23 +4271,38 @@ x_draw_glyph_string (s)
       /* Draw underline.  */
       if (s->face->underline_p)
        {
-         unsigned long dy, h;
+         unsigned long tem, h;
+         int y;
 
+         /* Get the underline thickness.  Default is 1 pixel.  */
          if (!XGetFontProperty (s->font, XA_UNDERLINE_THICKNESS, &h))
            h = 1;
-         if (!XGetFontProperty (s->font, XA_UNDERLINE_POSITION, &dy))
-           dy = s->height - h;
+
+         /* Get the underline position.  This is the recommended
+            vertical offset in pixels from the baseline to the top of
+            the underline.  This is a signed value according to the
+            specs, and its default is
+
+            ROUND ((maximum descent) / 2), with
+            ROUND(x) = floor (x + 0.5)  */
+         
+         if (XGetFontProperty (s->font, XA_UNDERLINE_POSITION, &tem))
+           y = s->ybase + (long) tem;
+         else if (s->face->font)
+           y = s->ybase + (s->face->font->max_bounds.descent + 1) / 2;
+         else
+           y = s->height - h;
       
          if (s->face->underline_defaulted_p)
-           XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy,
-                           s->width, h);
+           XFillRectangle (s->display, s->window, s->gc,
+                           s->x, y, s->width, h);
          else
            {
              XGCValues xgcv;
              XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
              XSetForeground (s->display, s->gc, s->face->underline_color);
-             XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy,
-                             s->width, h);
+             XFillRectangle (s->display, s->window, s->gc,
+                             s->x, y, s->width, h);
              XSetForeground (s->display, s->gc, xgcv.foreground);
            }
        }
@@ -5627,31 +5696,31 @@ expose_area (w, row, r, area)
      XRectangle *r;
      enum glyph_row_area area;
 {
-  int x;
   struct glyph *first = row->glyphs[area];
   struct glyph *end = row->glyphs[area] + row->used[area];
   struct glyph *last;
-  int first_x;
-
-  /* Set x to the window-relative start position for drawing glyphs of
-     AREA.  The first glyph of the text area can be partially visible.
-     The first glyphs of other areas cannot.  */
-  if (area == LEFT_MARGIN_AREA)
-    x = 0;
-  else if (area == TEXT_AREA)
-    x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
-  else
-    x = (window_box_width (w, LEFT_MARGIN_AREA)
-        + window_box_width (w, TEXT_AREA));
+  int first_x, start_x, x;
 
   if (area == TEXT_AREA && row->fill_line_p)
     /* If row extends face to end of line write the whole line.  */
-    x_draw_glyphs (w, x, row, area,
+    x_draw_glyphs (w, 0, row, area,
                   0, row->used[area],
                   row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
                   NULL, NULL, 0);
   else
     {
+      /* Set START_X to the window-relative start position for drawing glyphs of
+        AREA.  The first glyph of the text area can be partially visible.
+        The first glyphs of other areas cannot.  */
+      if (area == LEFT_MARGIN_AREA)
+       start_x = 0;
+      else if (area == TEXT_AREA)
+       start_x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
+      else
+       start_x = (window_box_width (w, LEFT_MARGIN_AREA)
+                  + window_box_width (w, TEXT_AREA));
+      x = start_x;
+
       /* Find the first glyph that must be redrawn.  */
       while (first < end
             && x + first->pixel_width < r->x)
@@ -5672,7 +5741,7 @@ expose_area (w, row, r, area)
       
       /* Repaint.  */
       if (last > first)
-       x_draw_glyphs (w, first_x, row, area,
+       x_draw_glyphs (w, first_x - start_x, row, area,
                       first - row->glyphs[area],
                       last - row->glyphs[area],
                       row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
@@ -5750,7 +5819,7 @@ expose_window (w, r)
      happen when toolkit scroll bars are used and a window is split.
      Reconfiguring the scroll bar will generate an expose for a newly
      created window.  */
-  if (w->current_matrix == NULL)
+  if (w->current_matrix == NULL || w == updated_window)
     return;
 
   TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
@@ -6426,7 +6495,7 @@ frame_to_window_pixel_xy (w, x, y)
 }
 
 
-/* Take proper action when mouse has moved to the mode or top line of
+/* Take proper action when mouse has moved to the mode or header line of
    window W, x-position X.  MODE_LINE_P non-zero means mouse is on the
    mode line.  X is relative to the start of the text display area of
    W, so the width of bitmap areas and scroll bars must be subtracted
@@ -6446,7 +6515,7 @@ note_mode_line_highlight (w, x, mode_line_p)
     row = MATRIX_MODE_LINE_ROW (w->current_matrix);
   else
     row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
-  
+
   if (row->enabled_p)
     {
       struct glyph *glyph, *end;
@@ -6458,6 +6527,7 @@ note_mode_line_highlight (w, x, mode_line_p)
       end = glyph + row->used[TEXT_AREA];
       x0 = - (FRAME_LEFT_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f)
              + FRAME_X_LEFT_FLAGS_AREA_WIDTH (f));
+      
       while (glyph < end
             && x >= x0 + glyph->pixel_width)
        {
@@ -6487,13 +6557,13 @@ note_mode_line_highlight (w, x, mode_line_p)
          /* Change the mouse pointer according to what is under X/Y.  */
          map = Fget_text_property (make_number (glyph->charpos),
                                    Qlocal_map, glyph->object);
-         if (!NILP (Fkeymapp (map)))
+         if (KEYMAPP (map))
            cursor = f->output_data.x->nontext_cursor;
          else
            {
              map = Fget_text_property (make_number (glyph->charpos),
                                        Qkeymap, glyph->object);
-             if (!NILP (Fkeymapp (map)))
+             if (KEYMAPP (map))
                cursor = f->output_data.x->nontext_cursor;
            }
        }
@@ -6570,6 +6640,9 @@ note_mouse_highlight (f, x, y)
       note_mode_line_highlight (w, x, portion == 1);
       return;
     }
+  else if (portion == 2)
+    XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+                  f->output_data.x->horizontal_drag_cursor);
   else
     XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                   f->output_data.x->text_cursor);
@@ -6817,7 +6890,7 @@ static int last_tool_bar_item;
    Return in *GLYPH a pointer to the glyph of the tool-bar item in
    the current matrix of the tool-bar window of F, or NULL if not
    on a tool-bar item.  Return in *PROP_IDX the index of the tool-bar
-   item in F->current_tool_bar_items.  Value is
+   item in F->tool_bar_items.  Value is
 
    -1  if X/Y is not on a tool-bar item
    0   if X/Y is on the same item that was highlighted before.
@@ -6840,7 +6913,7 @@ x_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
     return -1;
 
   /* Get the start of this tool-bar item's properties in
-     f->current_tool_bar_items.  */
+     f->tool_bar_items.  */
   if (!tool_bar_item_info (f, *glyph, prop_idx))
     return -1;
 
@@ -6882,8 +6955,7 @@ x_handle_tool_bar_click (f, button_event)
     return;
 
   /* If item is disabled, do nothing.  */
-  enabled_p = (XVECTOR (f->current_tool_bar_items)
-              ->contents[prop_idx + TOOL_BAR_ITEM_ENABLED_P]);
+  enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
   if (NILP (enabled_p))
     return;
   
@@ -6903,8 +6975,7 @@ x_handle_tool_bar_click (f, button_event)
       show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
       dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
 
-      key = (XVECTOR (f->current_tool_bar_items)
-            ->contents[prop_idx + TOOL_BAR_ITEM_KEY]);
+      key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
 
       XSETFRAME (frame, f);
       event.kind = TOOL_BAR_EVENT;
@@ -6977,8 +7048,7 @@ note_tool_bar_highlight (f, x, y)
   draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
   
   /* If tool-bar item is not enabled, don't highlight it.  */
-  enabled_p = (XVECTOR (f->current_tool_bar_items)
-              ->contents[prop_idx + TOOL_BAR_ITEM_ENABLED_P]);
+  enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
   if (!NILP (enabled_p))
     {
       /* Compute the x-position of the glyph.  In front and past the
@@ -7012,11 +7082,9 @@ note_tool_bar_highlight (f, x, y)
      XTread_socket does the rest.  */
   help_echo_object = help_echo_window = Qnil;
   help_echo_pos = -1;
-  help_echo = (XVECTOR (f->current_tool_bar_items)
-              ->contents[prop_idx + TOOL_BAR_ITEM_HELP]);
+  help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
   if (NILP (help_echo))
-    help_echo = (XVECTOR (f->current_tool_bar_items)
-                ->contents[prop_idx + TOOL_BAR_ITEM_CAPTION]);
+    help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
 }
 
 
@@ -7222,7 +7290,7 @@ void
 clear_mouse_face (dpyinfo)
      struct x_display_info *dpyinfo;
 {
-  if (tip_frame)
+  if (!NILP (tip_frame))
     return;
   
   if (! NILP (dpyinfo->mouse_face_window))
@@ -7417,6 +7485,15 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
 
            /* Is win one of our frames?  */
            f1 = x_any_window_to_frame (FRAME_X_DISPLAY_INFO (*fp), win);
+
+#ifdef USE_X_TOOLKIT
+           /* If we end up with the menu bar window, say it's not
+              on the frame.  */
+           if (f1 != NULL
+               && f1->output_data.x->menubar_widget
+               && win == XtWindow (f1->output_data.x->menubar_widget))
+             f1 = NULL;
+#endif /* USE_X_TOOLKIT */
          }
 
        if (x_had_errors_p (FRAME_X_DISPLAY (*fp)))
@@ -7560,7 +7637,7 @@ x_window_to_scroll_bar (window_id)
                         Toolkit scroll bars
  ************************************************************************/
 
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
 
 static void x_scroll_bar_to_input_event P_ ((XEvent *, struct input_event *));
 static void x_send_scroll_bar_event P_ ((Lisp_Object, int, int, int));
@@ -7639,6 +7716,12 @@ xt_action_hook (widget, client_data, action_name, event, params,
     }
 }
 
+/* A vector of windows used for communication between
+   x_send_scroll_bar_event and x_scroll_bar_to_input_event.  */
+
+static struct window **scroll_bar_windows;
+static int scroll_bar_windows_size;
+
 
 /* Send a client message with message type Xatom_Scrollbar for a
    scroll action to the frame of WINDOW.  PART is a value identifying
@@ -7652,15 +7735,41 @@ x_send_scroll_bar_event (window, part, portion, whole)
 {
   XEvent event;
   XClientMessageEvent *ev = (XClientMessageEvent *) &event;
-  struct frame *f = XFRAME (XWINDOW (window)->frame);
+  struct window *w = XWINDOW (window);
+  struct frame *f = XFRAME (w->frame);
+  int i;
 
+  BLOCK_INPUT;
+  
   /* Construct a ClientMessage event to send to the frame.  */
   ev->type = ClientMessage;
   ev->message_type = FRAME_X_DISPLAY_INFO (f)->Xatom_Scrollbar;
   ev->display = FRAME_X_DISPLAY (f);
   ev->window = FRAME_X_WINDOW (f);
   ev->format = 32;
-  ev->data.l[0] = (long) XFASTINT (window);
+
+  /* We can only transfer 32 bits in the XClientMessageEvent, which is
+     not enough to store a pointer or Lisp_Object on a 64 bit system.
+     So, store the window in scroll_bar_windows and pass the index
+     into that array in the event.  */
+  for (i = 0; i < scroll_bar_windows_size; ++i)
+    if (scroll_bar_windows[i] == NULL)
+      break;
+
+  if (i == scroll_bar_windows_size)
+    {
+      int new_size = max (10, 2 * scroll_bar_windows_size);
+      size_t nbytes = new_size * sizeof *scroll_bar_windows;
+      size_t old_nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows;
+      
+      scroll_bar_windows = (struct window **) xrealloc (scroll_bar_windows,
+                                                       nbytes);
+      bzero (&scroll_bar_windows[i], nbytes - old_nbytes);
+      scroll_bar_windows_size = new_size;
+    }
+
+  scroll_bar_windows[i] = w;
+  ev->data.l[0] = (long) i;
   ev->data.l[1] = (long) part;
   ev->data.l[2] = (long) 0;
   ev->data.l[3] = (long) portion;
@@ -7672,7 +7781,6 @@ x_send_scroll_bar_event (window, part, portion, whole)
   /* Setting the event mask to zero means that the message will
      be sent to the client that created the window, and if that
      window no longer exists, no event will be sent.  */
-  BLOCK_INPUT;
   XSendEvent (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), False, 0, &event);
   UNBLOCK_INPUT;
 }
@@ -7689,9 +7797,13 @@ x_scroll_bar_to_input_event (event, ievent)
   XClientMessageEvent *ev = (XClientMessageEvent *) event;
   Lisp_Object window;
   struct frame *f;
+  struct window *w;
+  
+  w = scroll_bar_windows[ev->data.l[0]];
+  scroll_bar_windows[ev->data.l[0]] = NULL;
 
-  XSETFASTINT (window, ev->data.l[0]);
-  f = XFRAME (XWINDOW (window)->frame);
+  XSETWINDOW (window, w);
+  f = XFRAME (w->frame);
   
   ievent->kind = scroll_bar_click;
   ievent->frame_or_window = window;
@@ -8049,8 +8161,9 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
      struct scroll_bar *bar;
      int portion, position, whole;
 {
+  struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
+  Widget widget = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
   float top, shown;
-  Widget widget = SCROLL_BAR_X_WIDGET (bar);
 
   if (whole == 0)
     top = 0, shown = 1;
@@ -8200,7 +8313,7 @@ x_scroll_bar_create (w, top, left, width, height)
 
   BLOCK_INPUT;
 
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
   x_create_toolkit_scroll_bar (f, bar);
 #else /* not USE_TOOLKIT_SCROLL_BARS */
   {
@@ -8260,13 +8373,16 @@ x_scroll_bar_create (w, top, left, width, height)
     XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
 
   /* Map the window/widget.  */
-#if USE_TOOLKIT_SCROLL_BARS
-  XtMapWidget (SCROLL_BAR_X_WIDGET (bar));
-  XtConfigureWidget (SCROLL_BAR_X_WIDGET (bar),
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ {
+   Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
+   XtConfigureWidget (scroll_bar,
                     left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
                     top,
                     width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
                     height, 0);
+   XtMapWidget (scroll_bar);
+ }
 #else /* not USE_TOOLKIT_SCROLL_BARS */
   XMapRaised (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar));
 #endif /* not USE_TOOLKIT_SCROLL_BARS */
@@ -8399,16 +8515,14 @@ static void
 x_scroll_bar_remove (bar)
      struct scroll_bar *bar;
 {
+  struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
   BLOCK_INPUT;
 
-#if USE_TOOLKIT_SCROLL_BARS
-  XtDestroyWidget (SCROLL_BAR_X_WIDGET (bar));
-#else /* not USE_TOOLKIT_SCROLL_BARS */
-  {
-    FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
-    XDestroyWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar));
-  }
-#endif /* not USE_TOOLKIT_SCROLL_BARS */
+#ifdef USE_TOOLKIT_SCROLL_BARS
+  XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar));
+#else
+  XDestroyWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar));
+#endif
   
   /* Disassociate this scroll bar from its window.  */
   XWINDOW (bar->window)->vertical_scroll_bar = Qnil;
@@ -8502,7 +8616,7 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
 
       /* Move/size the scroll bar widget.  */
       if (mask)
-       XtConfigureWidget (SCROLL_BAR_X_WIDGET (bar),
+       XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar),
                           sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
                           top,
                           sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
@@ -8549,7 +8663,7 @@ XTset_vertical_scroll_bar (w, portion, whole, position)
       UNBLOCK_INPUT;
     }
 
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
   x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
 #else /* not USE_TOOLKIT_SCROLL_BARS */
   /* Set the scroll bar's current state, unless we're currently being
@@ -8603,13 +8717,16 @@ XTcondemn_scroll_bars (frame)
     }
 }
 
+
 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
    Note that WINDOW isn't necessarily condemned at all.  */
+
 static void
 XTredeem_scroll_bar (window)
      struct window *window;
 {
   struct scroll_bar *bar;
+  struct frame *f;
 
   /* We can't redeem this window's scroll bar if it doesn't have one.  */
   if (NILP (window->vertical_scroll_bar))
@@ -8618,36 +8735,33 @@ XTredeem_scroll_bar (window)
   bar = XSCROLL_BAR (window->vertical_scroll_bar);
 
   /* Unlink it from the condemned list.  */
-  {
-    FRAME_PTR f = XFRAME (WINDOW_FRAME (window));
-
-    if (NILP (bar->prev))
-      {
-       /* If the prev pointer is nil, it must be the first in one of
-           the lists.  */
-       if (EQ (FRAME_SCROLL_BARS (f), window->vertical_scroll_bar))
-         /* It's not condemned.  Everything's fine.  */
-         return;
-       else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
-                    window->vertical_scroll_bar))
-         FRAME_CONDEMNED_SCROLL_BARS (f) = bar->next;
-       else
-         /* If its prev pointer is nil, it must be at the front of
-             one or the other!  */
-         abort ();
-      }
-    else
-      XSCROLL_BAR (bar->prev)->next = bar->next;
+  f = XFRAME (WINDOW_FRAME (window));
+  if (NILP (bar->prev))
+    {
+      /* If the prev pointer is nil, it must be the first in one of
+        the lists.  */
+      if (EQ (FRAME_SCROLL_BARS (f), window->vertical_scroll_bar))
+       /* It's not condemned.  Everything's fine.  */
+       return;
+      else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
+                  window->vertical_scroll_bar))
+       FRAME_CONDEMNED_SCROLL_BARS (f) = bar->next;
+      else
+       /* If its prev pointer is nil, it must be at the front of
+          one or the other!  */
+       abort ();
+    }
+  else
+    XSCROLL_BAR (bar->prev)->next = bar->next;
 
-    if (! NILP (bar->next))
-      XSCROLL_BAR (bar->next)->prev = bar->prev;
+  if (! NILP (bar->next))
+    XSCROLL_BAR (bar->next)->prev = bar->prev;
 
-    bar->next = FRAME_SCROLL_BARS (f);
-    bar->prev = Qnil;
-    XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
-    if (! NILP (bar->next))
-      XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
-  }
+  bar->next = FRAME_SCROLL_BARS (f);
+  bar->prev = Qnil;
+  XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
+  if (! NILP (bar->next))
+    XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
 }
 
 /* Remove all scroll bars on FRAME that haven't been saved since the
@@ -9602,7 +9716,7 @@ XTread_socket (sd, bufp, numchars, expected)
            case KeyPress:
              f = x_any_window_to_frame (dpyinfo, event.xkey.window);
 
-#ifdef USE_MOTIF
+#if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS
              /* I couldn't find a way to prevent LessTif scroll bars
                 from consuming key events.  */
              if (f == 0)
@@ -9615,7 +9729,7 @@ XTread_socket (sd, bufp, numchars, expected)
                      f = x_any_window_to_frame (dpyinfo, XtWindow (widget));
                    }
                }
-#endif /* USE_MOTIF */
+#endif /* USE_MOTIF and USE_TOOLKIT_SCROLL_BARS */
 
              if (f != 0)
                {
@@ -11149,14 +11263,26 @@ x_connection_closed (display, error_message)
   struct x_display_info *dpyinfo = x_display_info_for_display (display);
   Lisp_Object frame, tail;
 
-  /* Indicate that this display is dead.  */
+  /* We have to close the display to inform Xt that it doesn't
+     exist anymore.  If we don't, Xt will continue to wait for
+     events from the display.  As a consequence, a sequence of
+
+     M-x make-frame-on-display RET :1 RET
+     ...kill the new frame, so that we get an IO error...
+     M-x make-frame-on-display RET :1 RET
 
-#if 0 /* Closing the display caused a bus error on OpenWindows.  */
+     will indefinitely wait in Xt for events for display `:1', opened
+     in the first class to make-frame-on-display.
+
+     Closing the display is reported to lead to a bus error on
+     OpenWindows in certain situations.  I suspect that is a bug
+     in OpenWindows.  I don't know how to cicumvent it here.  */
+  
 #ifdef USE_X_TOOLKIT
   XtCloseDisplay (display);
-#endif
 #endif
 
+  /* Indicate that this display is dead.  */
   if (dpyinfo)
     dpyinfo->display = 0;
 
@@ -11205,6 +11331,7 @@ x_connection_closed (display, error_message)
   TOTALLY_UNBLOCK_INPUT;
 
   clear_waiting_for_input ();
+  handling_signal = 0;
   error ("%s", error_message);
 }
 
@@ -11543,11 +11670,13 @@ xim_close_dpy (dpyinfo)
 {
 #ifdef USE_XIM
 #ifdef HAVE_X11R6_XIM
-  XUnregisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb,
-                                   NULL, EMACS_CLASS,
-                                   xim_instantiate_callback, NULL);
+  if (dpyinfo->display)
+    XUnregisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb,
+                                     NULL, EMACS_CLASS,
+                                     xim_instantiate_callback, NULL);
 #endif /* not HAVE_X11R6_XIM */
-  XCloseIM (dpyinfo->xim);
+  if (dpyinfo->display)
+    XCloseIM (dpyinfo->xim);
   dpyinfo->xim = NULL;
   XFree (dpyinfo->xim_styles);
 #endif /* USE_XIM */
@@ -11633,25 +11762,33 @@ x_calc_absolute_position (f)
                                  - PIXEL_WIDTH (f)
                                  + f->output_data.x->left_pos);
 
-  if (flags & YNegative)
-    {
-      int menubar_height = 0;
+  {
+    int height = PIXEL_HEIGHT (f);
 
-#ifdef USE_X_TOOLKIT
-      if (f->output_data.x->menubar_widget)
-       menubar_height
-         = (f->output_data.x->menubar_widget->core.height
-            + f->output_data.x->menubar_widget->core.border_width);
+#if defined USE_X_TOOLKIT && defined USE_MOTIF
+    /* Something is fishy here.  When using Motif, starting Emacs with
+       `-g -0-0', the frame appears too low by a few pixels.
+
+       This seems to be so because initially, while Emacs is starting,
+       the column widget's height and the frame's pixel height are
+       different.  The column widget's height is the right one.  In
+       later invocations, when Emacs is up, the frame's pixel height
+       is right, though.
+
+       It's not obvious where the initial small difference comes from.
+       2000-12-01, gerd.  */
+    
+    XtVaGetValues (f->output_data.x->column_widget, XtNheight, &height, NULL);
 #endif
-      
-      f->output_data.x->top_pos = (FRAME_X_DISPLAY_INFO (f)->height
-                                  - 2 * f->output_data.x->border_width
-                                  - win_y
-                                  - PIXEL_HEIGHT (f)
-                                  - menubar_height
-                                  + f->output_data.x->top_pos);
-    }
 
+  if (flags & YNegative)
+    f->output_data.x->top_pos = (FRAME_X_DISPLAY_INFO (f)->height
+                                - 2 * f->output_data.x->border_width
+                                - win_y
+                                - height
+                                + f->output_data.x->top_pos);
+  }
+  
   /* The left_pos and top_pos
      are now relative to the top and left screen edges,
      so the flags should correspond.  */
@@ -12269,11 +12406,12 @@ x_iconify_frame (f)
   UNBLOCK_INPUT;
 #endif /* not USE_X_TOOLKIT */
 }
+
 \f
-/* Destroy the X window of frame F.  */
+/* Free X resources of frame F.  */
 
 void
-x_destroy_window (f)
+x_free_frame_resources (f)
      struct frame *f;
 {
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
@@ -12282,15 +12420,19 @@ x_destroy_window (f)
 
   /* If a display connection is dead, don't try sending more
      commands to the X server.  */
-  if (dpyinfo->display != 0)
+  if (dpyinfo->display)
     {
-      if (f->output_data.x->icon_desc != 0)
+      if (f->output_data.x->icon_desc)
        XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->icon_desc);
+      
 #ifdef HAVE_X_I18N
       if (FRAME_XIC (f))
        free_frame_xic (f);
 #endif
-      XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->window_desc);
+      
+      if (FRAME_X_WINDOW (f))
+       XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
+      
 #ifdef USE_X_TOOLKIT
       if (f->output_data.x->widget)
        XtDestroyWidget (f->output_data.x->widget);
@@ -12303,6 +12445,7 @@ x_destroy_window (f)
       unload_color (f, f->output_data.x->cursor_foreground_pixel);
       unload_color (f, f->output_data.x->border_pixel);
       unload_color (f, f->output_data.x->mouse_pixel);
+      
       if (f->output_data.x->scroll_bar_background_pixel != -1)
        unload_color (f, f->output_data.x->scroll_bar_background_pixel);
       if (f->output_data.x->scroll_bar_foreground_pixel != -1)
@@ -12311,8 +12454,11 @@ x_destroy_window (f)
        unload_color (f, f->output_data.x->white_relief.pixel);
       if (f->output_data.x->black_relief.allocated_p)
        unload_color (f, f->output_data.x->black_relief.pixel);
+
+      if (FRAME_FACE_CACHE (f))
+       free_frame_faces (f);
       
-      free_frame_faces (f);
+      x_free_gcs (f);
       XFlush (FRAME_X_DISPLAY (f));
     }
 
@@ -12320,7 +12466,8 @@ x_destroy_window (f)
     xfree (f->output_data.x->saved_menu_event);
 
   xfree (f->output_data.x);
-  f->output_data.x = 0;
+  f->output_data.x = NULL;
+  
   if (f == dpyinfo->x_focus_frame)
     dpyinfo->x_focus_frame = 0;
   if (f == dpyinfo->x_focus_event_frame)
@@ -12328,8 +12475,6 @@ x_destroy_window (f)
   if (f == dpyinfo->x_highlight_frame)
     dpyinfo->x_highlight_frame = 0;
 
-  dpyinfo->reference_count--;
-
   if (f == dpyinfo->mouse_face_mouse_frame)
     {
       dpyinfo->mouse_face_beg_row
@@ -12343,6 +12488,24 @@ x_destroy_window (f)
 
   UNBLOCK_INPUT;
 }
+
+
+/* Destroy the X window of frame F.  */
+
+void
+x_destroy_window (f)
+     struct frame *f;
+{
+  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+
+  /* If a display connection is dead, don't try sending more
+     commands to the X server.  */
+  if (dpyinfo->display != 0)
+    x_free_frame_resources (f);
+
+  dpyinfo->reference_count--;
+}
+
 \f
 /* Setting window manager hints.  */
 
@@ -13072,13 +13235,6 @@ x_load_font (f, fontname, size)
 
     fontp->size = font->max_bounds.width;
     fontp->height = FONT_HEIGHT (font);
-    {
-      /* For some font, ascent and descent in max_bounds field is
-        larger than the above value.  */
-      int max_height = font->max_bounds.ascent + font->max_bounds.descent;
-      if (max_height > fontp->height)
-       fontp->height = max_height;
-    }
 
     if (NILP (font_names))
       {
@@ -13567,7 +13723,7 @@ x_term_init (display_name, xrm_option, resource_name)
 
   {
     extern int gray_bitmap_width, gray_bitmap_height;
-    extern unsigned char *gray_bitmap_bits;
+    extern char *gray_bitmap_bits;
     dpyinfo->gray
       = XCreatePixmapFromBitmapData (dpyinfo->display, dpyinfo->root_window,
                                     gray_bitmap_bits,
@@ -13789,7 +13945,7 @@ x_initialize ()
   }
 #endif
   
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
   xaw3d_arrow_scroll = False;
   xaw3d_pick_top = True;
 #endif
@@ -13844,7 +14000,7 @@ wide as that tab on the display.");
 
   DEFVAR_BOOL ("x-toolkit-scroll-bars-p", &x_toolkit_scroll_bars_p,
     "If not nil, Emacs uses toolkit scroll bars.");
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
   x_toolkit_scroll_bars_p = 1;
 #else
   x_toolkit_scroll_bars_p = 0;
@@ -13855,4 +14011,3 @@ wide as that tab on the display.");
 }
 
 #endif /* not HAVE_X_WINDOWS */
-