(XTread_socket) <KeyPress>: In case XmbLookupString
[bpt/emacs.git] / src / xterm.c
index 32c3515..3b774e3 100644 (file)
@@ -1,5 +1,5 @@
 /* X Communication module for terminals which understand the X protocol.
-   Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998, 1999
+   Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998, 1999, 2000
    Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -72,8 +72,8 @@ Boston, MA 02111-1307, USA.  */
 #include "charset.h"
 #include "ccl.h"
 #include "frame.h"
-#include "fontset.h"
 #include "dispextern.h"
+#include "fontset.h"
 #include "termhooks.h"
 #include "termopts.h"
 #include "termchar.h"
@@ -412,7 +412,6 @@ static void set_output_cursor P_ ((struct cursor_pos *));
 static struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int,
                                           int *, int *, int *));
 static void note_mode_line_highlight P_ ((struct window *, int, int));
-static void x_check_font P_ ((struct frame *, XFontStruct *));
 static void note_mouse_highlight P_ ((struct frame *, int, int));
 static void note_tool_bar_highlight P_ ((struct frame *f, int, int));
 static void x_handle_tool_bar_click P_ ((struct frame *, XButtonEvent *));
@@ -452,7 +451,7 @@ static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
 static void XTframe_rehighlight P_ ((struct frame *));
 static void x_frame_rehighlight P_ ((struct x_display_info *));
 static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
-static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *));
+static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int));
 static int x_intersect_rectangles P_ ((XRectangle *, XRectangle *,
                                       XRectangle *));
 static void expose_frame P_ ((struct frame *, int, int, int, int));
@@ -1094,7 +1093,8 @@ XTcursor_to (vpos, hpos, y, x)
 
 static struct face *x_get_glyph_face_and_encoding P_ ((struct frame *,
                                                       struct glyph *,
-                                                      XChar2b *));
+                                                      XChar2b *,
+                                                      int *));
 static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int,
                                                      int, XChar2b *, int));
 static XCharStruct *x_per_char_metric P_ ((XFontStruct *, XChar2b *));
@@ -1105,7 +1105,7 @@ static void x_append_stretch_glyph P_ ((struct it *it, Lisp_Object,
                                        int, int, double));
 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.  */
@@ -1120,9 +1120,8 @@ static void x_produce_image_glyph P_ ((struct it *it));
    : &((font)->max_bounds))
 
 
-/* Get metrics of character CHAR2B in FONT.  Value is always non-null.
-   If CHAR2B is not contained in FONT, the font's default character
-   metric is returned.  */
+/* Get metrics of character CHAR2B in FONT.  Value is null if CHAR2B
+   is not contained in the font.  */
 
 static INLINE XCharStruct *
 x_per_char_metric (font, char2b)
@@ -1186,28 +1185,9 @@ x_per_char_metric (font, char2b)
        pcm = &font->max_bounds;
     }
 
-
-  if (pcm == NULL || pcm->width == 0)
-    {
-      /* Character not contained in the font.  FONT->default_char
-        gives the character that will be printed.  FONT->default_char
-        is a 16-bit character code with byte1 in the most significant
-        byte and byte2 in the least significant byte.  */
-      XChar2b default_char;
-      default_char.byte1 = (font->default_char >> BITS_PER_CHAR) & 0xff;
-      default_char.byte2 = font->default_char & 0xff;
-
-      /* Avoid an endless recursion if FONT->default_char itself
-        hasn't per char metrics.  handa@etl.go.jp reports that some
-        fonts have this problem.  */
-      if (default_char.byte1 != char2b->byte1
-         || default_char.byte2 != char2b->byte2)
-       pcm = x_per_char_metric (font, &default_char);
-      else
-       pcm = &font->max_bounds;
-    }
-  
-  return pcm;
+  return ((pcm == NULL
+          || (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0))
+         ? NULL : pcm);
 }
 
 
@@ -1248,7 +1228,7 @@ x_encode_char (c, char2b, font_info)
       /* We assume that MSBs are appropriately set/reset by CCL
         program.  */
       if (font->max_byte1 == 0)        /* 1-byte font */
-       char2b->byte2 = ccl->reg[1];
+       char2b->byte1 = 0, char2b->byte2 = ccl->reg[1];
       else
        char2b->byte1 = ccl->reg[1], char2b->byte2 = ccl->reg[2];
     }
@@ -1288,12 +1268,8 @@ x_get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p)
         sure to use a face suitable for unibyte.  */
       char2b->byte1 = 0;
       char2b->byte2 = c;
-      
-      if (!FACE_SUITABLE_FOR_CHARSET_P (face, -1))
-       {
-         face_id = FACE_FOR_CHARSET (f, face_id, -1);
-         face = FACE_FROM_ID (f, face_id);
-       }
+      face_id = FACE_FOR_CHAR (f, face, c);
+      face = FACE_FROM_ID (f, face_id);
     }
   else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
     {
@@ -1313,32 +1289,13 @@ x_get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p)
       else
        char2b->byte1 = 0, char2b->byte2 = c1;
 
-      /* Get the face for displaying C.  If `face' is not suitable for
-        charset, get the one that fits.  (This can happen for the
-        translations of a composition where the glyph
-        specifies a face for the first component, but the other
-        components have a different charset.)  */
-      if (!FACE_SUITABLE_FOR_CHARSET_P (face, charset))
-       {
-         face_id = FACE_FOR_CHARSET (f, face_id, charset);
-         face = FACE_FROM_ID (f, face_id);
-       }
-  
       /* Maybe encode the character in *CHAR2B.  */
-      if (charset != CHARSET_ASCII)
+      if (face->font != NULL)
        {
          struct font_info *font_info
            = FONT_INFO_FROM_ID (f, face->font_info_id);
          if (font_info)
-           {
-             x_encode_char (c, char2b, font_info);
-             if (charset == charset_latin_iso8859_1)
-               {
-                 xassert (((XFontStruct *) font_info->font)->max_char_or_byte2
-                          >= 0x80);
-                 char2b->byte2 |= 0x80;
-               }
-           }
+           x_encode_char (c, char2b, font_info);
        }
     }
 
@@ -1355,16 +1312,20 @@ x_get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p)
    a pointer to a realized face that is ready for display.  */
 
 static INLINE struct face *
-x_get_glyph_face_and_encoding (f, glyph, char2b)
+x_get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
      struct frame *f;
      struct glyph *glyph;
      XChar2b *char2b;
+     int *two_byte_p;
 {
   struct face *face;
 
   xassert (glyph->type == CHAR_GLYPH);
   face = FACE_FROM_ID (f, glyph->face_id);
 
+  if (two_byte_p)
+    *two_byte_p = 0;
+
   if (!glyph->multibyte_p)
     {
       /* Unibyte case.  We don't have to encode, but we have to make
@@ -1399,8 +1360,9 @@ x_get_glyph_face_and_encoding (f, glyph, char2b)
          if (font_info)
            {
              x_encode_char (glyph->u.ch, char2b, font_info);
-             if (charset == charset_latin_iso8859_1)
-               char2b->byte2 |= 0x80;
+             if (two_byte_p)
+               *two_byte_p
+                 = ((XFontStruct *) (font_info->font))->max_byte1 > 0;
            }
        }
     }
@@ -1445,6 +1407,7 @@ x_append_glyph (it)
       glyph->multibyte_p = it->multibyte_p;
       glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
                                      || it->phys_descent > it->descent);
+      glyph->glyph_not_available_p = it->glyph_not_available_p;
       ++it->glyph_row->used[area];
     }
 }
@@ -1528,7 +1491,7 @@ x_produce_image_glyph (it)
   PREPARE_FACE_FOR_DISPLAY (it->f, face);
   prepare_image_for_display (it->f, img);
 
-  it->ascent = it->phys_ascent = IMAGE_ASCENT (img);
+  it->ascent = it->phys_ascent = image_ascent (img, face);
   it->descent = it->phys_descent = img->height + 2 * img->margin - it->ascent;
   it->pixel_width = img->width + 2 * img->margin;
 
@@ -1649,7 +1612,10 @@ x_produce_stretch_glyph (it)
      struct it *it;
 {
   /* (space :width WIDTH :height HEIGHT.  */
-  extern Lisp_Object QCwidth, QCheight, QCascent, Qspace;
+#if GLYPH_DEBUG
+  extern Lisp_Object Qspace;
+#endif
+  extern Lisp_Object QCwidth, QCheight, QCascent;
   extern Lisp_Object QCrelative_width, QCrelative_height;
   extern Lisp_Object QCalign_to;
   Lisp_Object prop, plist;
@@ -1791,32 +1757,45 @@ static void
 x_produce_glyphs (it)
      struct it *it;
 {
+  it->glyph_not_available_p = 0;
+
   if (it->what == IT_CHARACTER)
     {
       XChar2b char2b;
       XFontStruct *font;
-      struct face *face;
+      struct face *face = FACE_FROM_ID (it->f, it->face_id);
       XCharStruct *pcm;
       int font_not_found_p;
       struct font_info *font_info;
       int boff;                        /* baseline offset */
 
-      /* Maybe translate single-byte characters to multibyte.  */
+      /* Maybe translate single-byte characters to multibyte, or the
+        other way.  */
       it->char_to_display = it->c;
-      if (unibyte_display_via_language_environment
-         && SINGLE_BYTE_CHAR_P (it->c)
-         && (it->c >= 0240
-             || (it->c >= 0200
-                 && !NILP (Vnonascii_translation_table))))
+      if (!ASCII_BYTE_P (it->c))
        {
-         it->char_to_display = unibyte_char_to_multibyte (it->c);
-         it->charset = CHAR_CHARSET (it->char_to_display);
+         if (unibyte_display_via_language_environment
+             && SINGLE_BYTE_CHAR_P (it->c)
+             && (it->c >= 0240
+                 || !NILP (Vnonascii_translation_table)))
+           {
+             it->char_to_display = unibyte_char_to_multibyte (it->c);
+             it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
+             face = FACE_FROM_ID (it->f, it->face_id);
+           }
+         else if (!SINGLE_BYTE_CHAR_P (it->c)
+                  && !it->multibyte_p)
+           {
+             it->char_to_display = multibyte_char_to_unibyte (it->c, Qnil);
+             it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
+             face = FACE_FROM_ID (it->f, it->face_id);
+           }
        }
       
-      /* Get face and font to use.  Encode IT->char_to_display.  */
-      face = x_get_char_face_and_encoding (it->f, it->char_to_display,
-                                          it->face_id, &char2b,
-                                          it->multibyte_p);
+      /* Get font to use.  Encode IT->char_to_display.  */
+      x_get_char_face_and_encoding (it->f, it->char_to_display,
+                                   it->face_id, &char2b,
+                                   it->multibyte_p);
       font = face->font;
 
       /* When no suitable font found, use the default font.  */
@@ -1846,9 +1825,20 @@ x_produce_glyphs (it)
          pcm = x_per_char_metric (font, &char2b);
          it->ascent = font->ascent + boff;
          it->descent = font->descent - boff;
-         it->phys_ascent = pcm->ascent + boff;
-         it->phys_descent = pcm->descent - boff;
-         it->pixel_width = pcm->width;
+
+         if (pcm)
+           {
+             it->phys_ascent = pcm->ascent + boff;
+             it->phys_descent = pcm->descent - boff;
+             it->pixel_width = pcm->width;
+           }
+         else
+           {
+             it->glyph_not_available_p = 1;
+             it->phys_ascent = font->ascent + boff;
+             it->phys_descent = font->descent - boff;
+             it->pixel_width = FONT_WIDTH (font);
+           }
 
          /* If this is a space inside a region of text with
             `space-width' property, change its width.  */
@@ -1896,8 +1886,7 @@ x_produce_glyphs (it)
              /* If characters with lbearing or rbearing are displayed
                 in this line, record that fact in a flag of the
                 glyph row.  This is used to optimize X output code.  */
-             if (pcm->lbearing < 0
-                 || pcm->rbearing > pcm->width)
+             if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
                it->glyph_row->contains_overlapping_glyphs_p = 1;
            }
        }
@@ -1919,9 +1908,7 @@ x_produce_glyphs (it)
       else if (it->char_to_display == '\t')
        {
          int tab_width = it->tab_width * CANON_X_UNIT (it->f);
-         int x = (it->current_x
-                  - it->prompt_width
-                  + it->continuation_lines_width);
+         int x = it->current_x + it->continuation_lines_width;
          int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
       
          it->pixel_width = next_tab_x - x;
@@ -1948,19 +1935,29 @@ x_produce_glyphs (it)
             from the charset width; this is what old redisplay code
             did.  */
          pcm = x_per_char_metric (font, &char2b);
-         it->pixel_width = pcm->width;
-         if (font_not_found_p)
-           it->pixel_width *= CHARSET_WIDTH (it->charset);
+         if (font_not_found_p || !pcm)
+           {
+             int charset = CHAR_CHARSET (it->char_to_display);
+
+             it->glyph_not_available_p = 1;
+             it->pixel_width = (FONT_WIDTH (FRAME_FONT (it->f))
+                                * CHARSET_WIDTH (charset));
+             it->phys_ascent = font->ascent + boff;
+             it->phys_descent = font->descent - boff;
+           }
+         else
+           {
+             it->pixel_width = pcm->width;
+             it->phys_ascent = pcm->ascent + boff;
+             it->phys_descent = pcm->descent - boff;
+             if (it->glyph_row
+                 && (pcm->lbearing < 0
+                     || pcm->rbearing > pcm->width))
+               it->glyph_row->contains_overlapping_glyphs_p = 1;
+           }
          it->nglyphs = 1;
          it->ascent = font->ascent + boff;
          it->descent = font->descent - boff;
-         it->phys_ascent = pcm->ascent + boff;
-         it->phys_descent = pcm->descent - boff;
-         if (it->glyph_row
-             && (pcm->lbearing < 0
-                 || pcm->rbearing > pcm->width))
-           it->glyph_row->contains_overlapping_glyphs_p = 1;
-       
          if (face->box != FACE_NO_BOX)
            {
              int thick = face->box_line_width;
@@ -1990,7 +1987,7 @@ x_produce_glyphs (it)
         glyph matrix.  There are no padding glyphs.  */
       XChar2b char2b;
       XFontStruct *font;
-      struct face *face;
+      struct face *face = FACE_FROM_ID (it->f, it->face_id);
       XCharStruct *pcm;
       int font_not_found_p;
       struct font_info *font_info;
@@ -2006,13 +2003,13 @@ x_produce_glyphs (it)
                  && !NILP (Vnonascii_translation_table))))
        {
          it->char_to_display = unibyte_char_to_multibyte (it->c);
-         it->charset = CHAR_CHARSET (it->char_to_display);
        }
       
       /* Get face and font to use.  Encode IT->char_to_display.  */
-      face = x_get_char_face_and_encoding (it->f, it->char_to_display,
-                                          it->face_id, &char2b,
-                                          it->multibyte_p);
+      it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
+      face = FACE_FROM_ID (it->f, it->face_id);
+      x_get_char_face_and_encoding (it->f, it->char_to_display,
+                                   it->face_id, &char2b, it->multibyte_p);
       font = face->font;
 
       /* When no suitable font found, use the default font.  */
@@ -2054,16 +2051,30 @@ x_produce_glyphs (it)
          int font_descent = font->descent - boff;
          /* Bounding box of the overall glyphs.  */
          int leftmost, rightmost, lowest, highest;
-         int i;
+         int i, width, ascent, descent;
 
          cmp->font = (void *) font;
 
          /* Initialize the bounding box.  */
          pcm = x_per_char_metric (font, &char2b);
+         if (pcm)
+           {
+             width = pcm->width;
+             ascent = pcm->ascent;
+             descent = pcm->descent;
+           }
+         else
+           {
+             width = FONT_WIDTH (font);
+             ascent = font->ascent;
+             descent = font->descent;
+           }
+         
+         rightmost = width;
+         lowest = - descent + boff;
+         highest = ascent + boff;
          leftmost = 0;
-         rightmost = pcm->width;
-         lowest = - pcm->descent + boff;
-         highest = pcm->ascent + boff;
+         
          if (font_info
              && font_info->default_ascent
              && CHAR_TABLE_P (Vuse_default_ascent)
@@ -2082,10 +2093,11 @@ x_produce_glyphs (it)
            {
              int left, right, btm, top;
              int ch = COMPOSITION_GLYPH (cmp, i);
-
-             face = x_get_char_face_and_encoding (it->f, ch,
-                                                  it->face_id, &char2b,
-                                                  it->multibyte_p);
+             int face_id = FACE_FOR_CHAR (it->f, face, ch);
+             
+             face = FACE_FROM_ID (it->f, face_id);
+             x_get_char_face_and_encoding (it->f, ch, face->id, &char2b,
+                                           it->multibyte_p);
              font = face->font;
              if (font == NULL)
                {
@@ -2103,26 +2115,37 @@ x_produce_glyphs (it)
                }
 
              pcm = x_per_char_metric (font, &char2b);
+             if (pcm)
+               {
+                 width = pcm->width;
+                 ascent = pcm->ascent;
+                 descent = pcm->descent;
+               }
+             else
+               {
+                 width = FONT_WIDTH (font);
+                 ascent = font->ascent;
+                 descent = font->descent;
+               }
 
              if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
                {
                  /* Relative composition with or without
                     alternate chars.  */
-                 left = (leftmost + rightmost - pcm->width) / 2;
-                 btm = - pcm->descent + boff;
+                 left = (leftmost + rightmost - width) / 2;
+                 btm = - descent + boff;
                  if (font_info && font_info->relative_compose
                      && (! CHAR_TABLE_P (Vignore_relative_composition)
                          || NILP (Faref (Vignore_relative_composition,
                                          make_number (ch)))))
                    {
 
-                     if (- pcm->descent
-                         >= font_info->relative_compose)
+                     if (- descent >= font_info->relative_compose)
                        /* One extra pixel between two glyphs.  */
                        btm = highest + 1;
-                     else if (pcm->ascent <= 0)
+                     else if (ascent <= 0)
                        /* One extra pixel between two glyphs.  */
-                       btm = lowest - 1 - pcm->ascent - pcm->descent;
+                       btm = lowest - 1 - ascent - descent;
                    }
                }
              else
@@ -2151,23 +2174,23 @@ x_produce_glyphs (it)
 
                  left = (leftmost
                          + grefx * (rightmost - leftmost) / 2
-                         - nrefx * pcm->width / 2);
+                         - nrefx * width / 2);
                  btm = ((grefy == 0 ? highest
                          : grefy == 1 ? 0
                          : grefy == 2 ? lowest
                          : (highest + lowest) / 2)
-                        - (nrefy == 0 ? pcm->ascent + pcm->descent
-                           : nrefy == 1 ? pcm->descent - boff
+                        - (nrefy == 0 ? ascent + descent
+                           : nrefy == 1 ? descent - boff
                            : nrefy == 2 ? 0
-                           : (pcm->ascent + pcm->descent) / 2));
+                           : (ascent + descent) / 2));
                }
 
              cmp->offsets[i * 2] = left;
-             cmp->offsets[i * 2 + 1] = btm + pcm->descent;
+             cmp->offsets[i * 2 + 1] = btm + descent;
 
              /* Update the bounding box of the overall glyphs. */
-             right = left + pcm->width;
-             top = btm + pcm->descent + pcm->ascent;
+             right = left + width;
+             top = btm + descent + ascent;
              if (left < leftmost)
                leftmost = left;
              if (right > rightmost)
@@ -2228,11 +2251,14 @@ x_produce_glyphs (it)
   else if (it->what == IT_STRETCH)
     x_produce_stretch_glyph (it);
 
-  /* Accumulate dimensions.  */
-  xassert (it->ascent >= 0 && it->descent > 0);
+  /* Accumulate dimensions.  Note: can't assume that it->descent > 0
+     because this isn't true for images with `:ascent 100'.  */
+  xassert (it->ascent >= 0 && it->descent >= 0);
   if (it->area == TEXT_AREA)
     it->current_x += it->pixel_width;
   
+  it->descent += it->extra_line_spacing;
+  
   it->max_ascent = max (it->max_ascent, it->ascent);
   it->max_descent = max (it->max_descent, it->descent);
   it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
@@ -2324,9 +2350,6 @@ struct glyph_string
   XChar2b *char2b;
   int nchars;
 
-  /* Character set of this glyph string.  */
-  int charset;
-
   /* A face-override for drawing cursors, mouse face and similar.  */
   enum draw_glyphs_face hl;
 
@@ -2470,6 +2493,10 @@ static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
 static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *,
                                        enum glyph_row_area));
 
+#if GLYPH_DEBUG
+static void x_check_font P_ ((struct frame *, XFontStruct *));
+#endif
+
 
 /* Append the list of glyph strings with head H and tail T to the list
    with head *HEAD and tail *TAIL.  Set *HEAD and *TAIL to the result.  */
@@ -2586,10 +2613,15 @@ x_set_mouse_face_gc (s)
      struct glyph_string *s;
 {     
   int face_id;
+  struct face *face;
 
   /* What face has to be used for the mouse face?  */
   face_id = FRAME_X_DISPLAY_INFO (s->f)->mouse_face_face_id;
-  face_id = FACE_FOR_CHARSET (s->f, face_id, s->charset);
+  face = FACE_FROM_ID (s->f, face_id);
+  if (s->first_glyph->type == CHAR_GLYPH)
+    face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch);
+  else
+    face_id = FACE_FOR_CHAR (s->f, face, 0);
   s->face = FACE_FROM_ID (s->f, face_id);
   PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
 
@@ -2824,8 +2856,6 @@ x_get_glyph_overhangs (glyph, f, left, right)
      struct frame *f;
      int *left, *right;
 {
-  int c;
-  
   *left = *right = 0;
   
   if (glyph->type == CHAR_GLYPH)
@@ -2834,14 +2864,14 @@ x_get_glyph_overhangs (glyph, f, left, right)
       struct face *face;
       struct font_info *font_info;
       XChar2b char2b;
-      
-      face = x_get_glyph_face_and_encoding (f, glyph, &char2b);
+      XCharStruct *pcm;
+
+      face = x_get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
       font = face->font;
       font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
-      if (font)
+      if (font
+         && (pcm = x_per_char_metric (font, &char2b)))
        {
-         XCharStruct *pcm = x_per_char_metric (font, &char2b);
-         
          if (pcm->rbearing > pcm->width)
            *right = pcm->rbearing - pcm->width;
          if (pcm->lbearing < 0)
@@ -3128,21 +3158,20 @@ x_draw_composite_glyph_string_foreground (s)
 
 #ifdef USE_X_TOOLKIT
 
-/* Allocate the color COLOR->pixel on the screen and display of
-   widget WIDGET in colormap CMAP.  If an exact match cannot be
-   allocated, try the nearest color available.  Value is non-zero
-   if successful.  This is called from lwlib.  */
+static struct frame *x_frame_of_widget P_ ((Widget));
 
-int
-x_alloc_nearest_color_for_widget (widget, cmap, color)
+
+/* Return the frame on which widget WIDGET is used.. Abort if frame
+   cannot be determined.  */
+
+struct frame *
+x_frame_of_widget (widget)
      Widget widget;
-     Colormap cmap;
-     XColor *color;
 {
-  struct frame *f;
   struct x_display_info *dpyinfo;
   Lisp_Object tail;
-
+  struct frame *f;
+  
   dpyinfo = x_display_info_for_display (XtDisplay (widget));
   
   /* Find the top-level shell of the widget.  Note that this function
@@ -3160,11 +3189,28 @@ x_alloc_nearest_color_for_widget (widget, cmap, color)
            (f->output_data.nothing != 1
             && FRAME_X_DISPLAY_INFO (f) == dpyinfo))
        && f->output_data.x->widget == widget)
-      return x_alloc_nearest_color (f, cmap, color);
+      return f;
 
   abort ();
 }
 
+
+/* Allocate the color COLOR->pixel on the screen and display of
+   widget WIDGET in colormap CMAP.  If an exact match cannot be
+   allocated, try the nearest color available.  Value is non-zero
+   if successful.  This is called from lwlib.  */
+
+int
+x_alloc_nearest_color_for_widget (widget, cmap, color)
+     Widget widget;
+     Colormap cmap;
+     XColor *color;
+{
+  struct frame *f = x_frame_of_widget (widget);
+  return x_alloc_nearest_color (f, cmap, color);
+}
+
+
 #endif /* USE_X_TOOLKIT */
 
 
@@ -3220,10 +3266,62 @@ x_alloc_nearest_color (f, cmap, color)
       rc = XAllocColor (display, cmap, color);
     }
 
+#ifdef DEBUG_X_COLORS
+  if (rc)
+    register_color (color->pixel);
+#endif /* DEBUG_X_COLORS */
+  
   return rc;
 }
 
 
+/* Allocate color PIXEL on frame F.  PIXEL must already be allocated.
+   It's necessary to do this instead of just using PIXEL directly to
+   get color reference counts right.  */
+
+unsigned long
+x_copy_color (f, pixel)
+     struct frame *f;
+     unsigned long pixel;
+{
+  XColor color;
+
+  color.pixel = pixel;
+  BLOCK_INPUT;
+  XQueryColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color);
+  XAllocColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), &color);
+  UNBLOCK_INPUT;
+#ifdef DEBUG_X_COLORS
+  register_color (pixel);
+#endif
+  return color.pixel;
+}
+
+
+/* Allocate color PIXEL on display DPY.  PIXEL must already be allocated.
+   It's necessary to do this instead of just using PIXEL directly to
+   get color reference counts right.  */
+
+unsigned long
+x_copy_dpy_color (dpy, cmap, pixel)
+     Display *dpy;
+     Colormap cmap;
+     unsigned long pixel;
+{
+  XColor color;
+
+  color.pixel = pixel;
+  BLOCK_INPUT;
+  XQueryColor (dpy, cmap, &color);
+  XAllocColor (dpy, cmap, &color);
+  UNBLOCK_INPUT;
+#ifdef DEBUG_X_COLORS
+  register_color (pixel);
+#endif
+  return color.pixel;
+}
+
+
 /* 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
@@ -3261,15 +3359,7 @@ x_alloc_lighter_color (f, display, cmap, pixel, factor, delta)
        {
          /* If we end up with the same color as before, try adding
             delta to the RGB values.  */
-         int class = FRAME_X_DISPLAY_INFO (f)->visual->class;
-         
-         /* If display has an immutable color map, freeing colors is
-            not necessary and some servers don't allow it.  So don't
-            do it.  */
-         if (class != StaticColor
-             && class != StaticGray
-             && class != TrueColor)
-           XFreeColors (display, cmap, &new.pixel, 1, 0);
+         x_free_colors (f, &new.pixel, 1);
          
          new.red = min (0xffff, delta + color.red);
          new.green = min (0xffff, delta + color.green);
@@ -3305,7 +3395,7 @@ x_setup_relief_color (f, relief, factor, delta, default_pixel)
   unsigned long mask = GCForeground | GCLineWidth | GCGraphicsExposures;
   unsigned long pixel;
   unsigned long background = di->relief_background;
-  Colormap cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f));
+  Colormap cmap = FRAME_X_COLORMAP (f);
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   Display *dpy = FRAME_X_DISPLAY (f);
 
@@ -3318,13 +3408,7 @@ x_setup_relief_color (f, relief, factor, delta, default_pixel)
   if (relief->gc
       && relief->allocated_p)
     {
-      /* If display has an immutable color map, freeing colors is not
-        necessary and some servers don't allow it.  So don't do it.  */
-      int class = dpyinfo->visual->class;
-      if (class != StaticColor
-         && class != StaticGray
-         && class != TrueColor)
-       XFreeColors (dpy, cmap, &relief->pixel, 1, 0);
+      x_free_colors (f, &relief->pixel, 1);
       relief->allocated_p = 0;
     }
 
@@ -3547,7 +3631,7 @@ x_draw_image_foreground (s)
      struct glyph_string *s;
 {
   int x;
-  int y = s->ybase - IMAGE_ASCENT (s->img);
+  int y = s->ybase - image_ascent (s->img, s->face);
 
   /* If first glyph of S has a left box line, start drawing it to the
      right of that line.  */
@@ -3626,7 +3710,7 @@ x_draw_image_relief (s)
   int x0, y0, x1, y1, thick, raised_p;
   XRectangle r;
   int x;
-  int y = s->ybase - IMAGE_ASCENT (s->img);
+  int y = s->ybase - image_ascent (s->img, s->face);
   
   /* If first glyph of S has a left box line, start drawing it to the
      right of that line.  */
@@ -3675,7 +3759,7 @@ x_draw_image_foreground_1 (s, pixmap)
      Pixmap pixmap;
 {
   int x;
-  int y = s->ybase - s->y - IMAGE_ASCENT (s->img);
+  int y = s->ybase - s->y - image_ascent (s->img, s->face);
 
   /* If first glyph of S has a left box line, start drawing it to the
      right of that line.  */
@@ -4128,6 +4212,7 @@ x_fill_glyph_string (s, face_id, start, end, overlaps_p)
 {
   struct glyph *glyph, *last;
   int voffset;
+  int glyph_not_available_p;
   
   xassert (s->f == XFRAME (s->w->frame));
   xassert (s->nchars == 0);
@@ -4138,17 +4223,21 @@ x_fill_glyph_string (s, face_id, start, end, overlaps_p)
   last = s->row->glyphs[s->area] + end;
   voffset = glyph->voffset;
   
+  glyph_not_available_p = glyph->glyph_not_available_p;
+
   while (glyph < last
         && glyph->type == CHAR_GLYPH
         && glyph->voffset == voffset
-        /* Same face id implies same charset, nowadays.  */
-        && glyph->face_id == face_id)
+        /* Same face id implies same font, nowadays.  */
+        && glyph->face_id == face_id
+        && glyph->glyph_not_available_p == glyph_not_available_p)
     {
+      int two_byte_p;
+
       s->face = x_get_glyph_face_and_encoding (s->f, glyph,
-                                              s->char2b + s->nchars);
-      if (s->char2b[s->nchars].byte2 != 0)
-       s->two_byte_p = 1;
-      
+                                              s->char2b + s->nchars,
+                                              &two_byte_p);
+      s->two_byte_p = two_byte_p;
       ++s->nchars;
       xassert (s->nchars <= end - start);
       s->width += glyph->pixel_width;
@@ -4162,7 +4251,7 @@ x_fill_glyph_string (s, face_id, start, end, overlaps_p)
      but record the fact that we couldn't load it in
      S->font_not_found_p so that we can draw rectangles for the
      characters of the glyph string.  */
-  if (s->font == NULL)
+  if (s->font == NULL || glyph_not_available_p)
     {
       s->font_not_found_p = 1;
       s->font = FRAME_FONT (s->f);
@@ -4336,18 +4425,16 @@ x_set_glyph_string_background_width (s, start, last_x)
 #define BUILD_CHAR_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
      do                                                                           \
        {                                                                  \
-        int c, charset, face_id;                                          \
+        int c, face_id;                                                   \
         XChar2b *char2b;                                                  \
                                                                           \
         c = (ROW)->glyphs[AREA][START].u.ch;                              \
-        charset = CHAR_CHARSET (c);                                       \
         face_id = (ROW)->glyphs[AREA][START].face_id;                     \
                                                                           \
         s = (struct glyph_string *) alloca (sizeof *s);                   \
         char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b);     \
         x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL);         \
         x_append_glyph_string (&HEAD, &TAIL, s);                          \
-        s->charset = charset;                                             \
         s->x = (X);                                                       \
         START = x_fill_glyph_string (s, face_id, START, END,              \
                                           OVERLAPS_P);                    \
@@ -4368,6 +4455,7 @@ x_set_glyph_string_background_width (s, start, last_x)
   do {                                                                   \
     int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id;                    \
     int face_id = (ROW)->glyphs[AREA][START].face_id;                    \
+    struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id);          \
     struct composition *cmp = composition_table[cmp_id];                 \
     int glyph_len = cmp->glyph_len;                                      \
     XChar2b *char2b;                                                     \
@@ -4375,14 +4463,17 @@ x_set_glyph_string_background_width (s, start, last_x)
     struct glyph_string *first_s = NULL;                                 \
     int n;                                                               \
                                                                          \
+    base_face = base_face->ascii_face;                                   \
     char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len);                  \
     faces = (struct face **) alloca ((sizeof *faces) * glyph_len);       \
     /* At first, fill in `char2b' and `faces'.  */                       \
     for (n = 0; n < glyph_len; n++)                                      \
       {                                                                          \
        int c = COMPOSITION_GLYPH (cmp, n);                               \
-       faces[n] = x_get_char_face_and_encoding (XFRAME (w->frame), c,    \
-                                                face_id, char2b + n, 1); \
+       int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
+       faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id);        \
+       x_get_char_face_and_encoding (XFRAME (w->frame), c,               \
+                                     this_face_id, char2b + n, 1);       \
       }                                                                          \
                                                                          \
     /* Make glyph_strings for each glyph sequence that is drawable by    \
@@ -4394,7 +4485,6 @@ x_set_glyph_string_background_width (s, start, last_x)
        x_append_glyph_string (&(HEAD), &(TAIL), s);                      \
        s->cmp = cmp;                                                     \
        s->gidx = n;                                                      \
-       s->charset = 0;                                                   \
        s->x = (X);                                                       \
                                                                          \
        if (n == 0)                                                       \
@@ -6083,7 +6173,7 @@ x_y_to_hpos_vpos (w, x, y, hpos, vpos, area)
      int *hpos, *vpos, *area;
 {
   struct glyph *glyph, *end;
-  struct glyph_row *row;
+  struct glyph_row *row = NULL;
   int x0, i, left_area_width;
 
   /* Find row containing Y.  Give up if some row is not enabled.  */
@@ -6264,7 +6354,8 @@ note_mouse_highlight (f, x, y)
     return;
 #endif
 
-  if (disable_mouse_highlight)
+  if (disable_mouse_highlight
+      || !f->glyphs_initialized_p)
     return;
 
   dpyinfo->mouse_face_mouse_x = x;
@@ -6782,6 +6873,9 @@ fast_find_position (w, pos, hpos, vpos, x, y)
          best_row = row;
          best_row_vpos = row_vpos;
        }
+
+      if (row->y + row->height >= yb)
+       break;
       
       ++row;
       ++row_vpos;
@@ -7351,7 +7445,7 @@ x_send_scroll_bar_event (window, part, portion, whole)
   ev->display = FRAME_X_DISPLAY (f);
   ev->window = FRAME_X_WINDOW (f);
   ev->format = 32;
-  ev->data.l[0] = (long) window;
+  ev->data.l[0] = (long) XFASTINT (window);
   ev->data.l[1] = (long) part;
   ev->data.l[2] = (long) 0;
   ev->data.l[3] = (long) portion;
@@ -7378,8 +7472,11 @@ x_scroll_bar_to_input_event (event, ievent)
      struct input_event *ievent;
 {
   XClientMessageEvent *ev = (XClientMessageEvent *) event;
-  Lisp_Object window = (Lisp_Object) ev->data.l[0];
-  struct frame *f = XFRAME (XWINDOW (window)->frame);
+  Lisp_Object window;
+  struct frame *f;
+
+  XSETFASTINT (window, ev->data.l[0]);
+  f = XFRAME (XWINDOW (window)->frame);
   
   ievent->kind = scroll_bar_click;
   ievent->frame_or_window = window;
@@ -7833,7 +7930,7 @@ x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
          {
 #ifdef HAVE_XAW3D
            ScrollbarWidget sb = (ScrollbarWidget) widget;
-           int scroll_mode;
+           int scroll_mode = 0;
            
            /* `scroll_mode' only exists with Xaw3d + ARROW_SCROLLBAR.  */
            if (xaw3d_arrow_scroll)
@@ -9337,7 +9434,10 @@ XTread_socket (sd, bufp, numchars, expected)
                      if (status_return == XLookupNone)
                        break;
                      else if (status_return == XLookupChars)
-                       keysym = NoSymbol;
+                       {
+                         keysym = NoSymbol;
+                         modifiers = 0;
+                       }
                      else if (status_return != XLookupKeySym
                               && status_return != XLookupBoth)
                        abort ();
@@ -9557,7 +9657,20 @@ XTread_socket (sd, bufp, numchars, expected)
              if (event.xfocus.detail != NotifyPointer)
                dpyinfo->x_focus_event_frame = f;
              if (f)
-               x_new_focus_frame (dpyinfo, f);
+               {
+                 x_new_focus_frame (dpyinfo, f);
+
+                 /* Don't stop displaying the initial startup message
+                    for a switch-frame event we don't need.  */
+                 if (GC_NILP (Vterminal_frame)
+                     && GC_CONSP (Vframe_list)
+                     && !GC_NILP (XCDR (Vframe_list)))
+                   {
+                     bufp->kind = FOCUS_IN_EVENT;
+                     XSETFRAME (bufp->frame_or_window, f);
+                     ++bufp, ++count, --numchars;
+                   }
+               }
 
 #ifdef HAVE_X_I18N
              if (f && FRAME_XIC (f))
@@ -10068,9 +10181,10 @@ x_draw_hollow_cursor (w, row)
    --gerd.  */
 
 static void
-x_draw_bar_cursor (w, row)
+x_draw_bar_cursor (w, row, width)
      struct window *w;
      struct glyph_row *row;
+     int width;
 {
   /* If cursor hpos is out of bounds, don't draw garbage.  This can
      happen in mini-buffer windows when switching between echo area
@@ -10106,13 +10220,15 @@ x_draw_bar_cursor (w, row)
          FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc = gc;
        }
 
+      if (width < 0)
+       width = f->output_data.x->cursor_width;
+
       x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
       x_clip_to_row (w, row, gc, 0);
       XFillRectangle (dpy, window, gc,
                      x,
                      WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
-                     min (cursor_glyph->pixel_width,
-                          f->output_data.x->cursor_width),
+                     min (cursor_glyph->pixel_width, width),
                      row->height);
       XSetClipMask (dpy, gc, None);
     }
@@ -10209,7 +10325,8 @@ x_erase_phys_cursor (w)
         
   /* If the cursor is in the mouse face area, redisplay that when
      we clear the cursor.  */
-  if (w == XWINDOW (dpyinfo->mouse_face_window)
+  if (! NILP (dpyinfo->mouse_face_window)
+      && w == XWINDOW (dpyinfo->mouse_face_window)
       && (vpos > dpyinfo->mouse_face_beg_row
          || (vpos == dpyinfo->mouse_face_beg_row
              && hpos >= dpyinfo->mouse_face_beg_col))
@@ -10269,6 +10386,7 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
 {
   struct frame *f = XFRAME (w->frame);
   int new_cursor_type;
+  int new_cursor_width;
   struct glyph_matrix *current_glyphs;
   struct glyph_row *glyph_row;
   struct glyph *glyph;
@@ -10307,6 +10425,7 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
      the cursor type given by the frame parameter.  If explicitly
      marked off, draw no cursor.  In all other cases, we want a hollow
      box cursor.  */
+  new_cursor_width = -1;
   if (cursor_in_echo_area
       && FRAME_HAS_MINIBUF_P (f)
       && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
@@ -10331,7 +10450,15 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
       else if (w->cursor_off_p)
        new_cursor_type = NO_CURSOR;
       else
-       new_cursor_type = FRAME_DESIRED_CURSOR (f);
+       {
+         struct buffer *b = XBUFFER (w->buffer);
+
+         if (EQ (b->cursor_type, Qt))
+           new_cursor_type = FRAME_DESIRED_CURSOR (f);
+         else
+           new_cursor_type = x_specified_cursor_type (b->cursor_type, 
+                                                      &new_cursor_width);
+       }
     }
 
   /* If cursor is currently being shown and we don't want it to be or
@@ -10371,7 +10498,7 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y)
          break;
 
        case BAR_CURSOR:
-         x_draw_bar_cursor (w, glyph_row);
+         x_draw_bar_cursor (w, glyph_row, new_cursor_width);
          break;
 
        case NO_CURSOR:
@@ -10453,10 +10580,15 @@ x_update_window_cursor (w, on)
      struct window *w;
      int on;
 {
-  BLOCK_INPUT;
-  x_display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
-                           w->phys_cursor.x, w->phys_cursor.y);
-  UNBLOCK_INPUT;
+  /* Don't update cursor in windows whose frame is in the process
+     of being deleted.  */
+  if (w->current_matrix)
+    {
+      BLOCK_INPUT;
+      x_display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
+                               w->phys_cursor.x, w->phys_cursor.y);
+      UNBLOCK_INPUT;
+    }
 }
 
 
@@ -10709,11 +10841,14 @@ x_connection_closed (display, error_message)
 
   /* Indicate that this display is dead.  */
 
+#if 0 /* Closing the display caused a bus error on OpenWindows.  */
 #ifdef USE_X_TOOLKIT
   XtCloseDisplay (display);
+#endif
 #endif
 
-  dpyinfo->display = 0;
+  if (dpyinfo)
+    dpyinfo->display = 0;
 
   /* First delete frames whose mini-buffers are on frames
      that are on the dead display.  */
@@ -10826,7 +10961,7 @@ x_new_font (f, fontname)
      register char *fontname;
 {
   struct font_info *fontp
-    = fs_load_font (f, FRAME_X_FONT_TABLE (f), CHARSET_ASCII, fontname, -1);
+    = FS_LOAD_FONT (f, 0, fontname, -1);
 
   if (!fontp)
     return Qnil;
@@ -10878,8 +11013,7 @@ x_new_fontset (f, fontsetname)
      struct frame *f;
      char *fontsetname;
 {
-  int fontset = fs_query_fontset (f, fontsetname);
-  struct fontset_info *fontsetp;
+  int fontset = fs_query_fontset (build_string (fontsetname), 0);
   Lisp_Object result;
 
   if (fontset < 0)
@@ -10888,15 +11022,9 @@ x_new_fontset (f, fontsetname)
   if (f->output_data.x->fontset == fontset)
     /* This fontset is already set in frame F.  There's nothing more
        to do.  */
-    return build_string (fontsetname);
-
-  fontsetp = FRAME_FONTSET_DATA (f)->fontset_table[fontset];
+    return fontset_name (fontset);
 
-  if (!fontsetp->fontname[CHARSET_ASCII])
-    /* This fontset doesn't contain ASCII font.  */
-    return Qnil;
-
-  result = x_new_font (f, fontsetp->fontname[CHARSET_ASCII]);
+  result = x_new_font (f, (XSTRING (fontset_ascii (fontset))->data));
 
   if (!STRINGP (result))
     /* Can't load ASCII font.  */
@@ -10904,13 +11032,11 @@ x_new_fontset (f, fontsetname)
 
   /* Since x_new_font doesn't update any fontset information, do it now.  */
   f->output_data.x->fontset = fontset;
-  FS_LOAD_FONT (f, FRAME_X_FONT_TABLE (f),
-               CHARSET_ASCII, fontsetp->fontname[CHARSET_ASCII], fontset);
 
 #ifdef HAVE_X_I18N
   if (FRAME_XIC (f)
       && (FRAME_XIC_STYLE (f) & (XIMPreeditPosition | XIMStatusArea)))
-    xic_set_xfontset (f, fontsetp->fontname[CHARSET_ASCII]);
+    xic_set_xfontset (f, XSTRING (fontset_ascii (fontset))->data);
 #endif
   
   return build_string (fontsetname);
@@ -10994,7 +11120,7 @@ xim_open_dpy (dpyinfo, resource_name)
 }
 
 
-#ifdef HAVE_X11R6
+#ifdef HAVE_X11R6_XIM
 
 struct xim_inst_t
 {
@@ -11051,7 +11177,7 @@ xim_instantiate_callback (display, client_data, call_data)
     }
 }
 
-#endif /* HAVE_X11R6 */
+#endif /* HAVE_X11R6_XIM */
 
 
 /* Open a connection to the XIM server on display DPYINFO.
@@ -11064,7 +11190,7 @@ xim_initialize (dpyinfo, resource_name)
      struct x_display_info *dpyinfo;
      char *resource_name;
 {
-#ifdef HAVE_X11R6
+#ifdef HAVE_X11R6_XIM
   struct xim_inst_t *xim_inst;
   int len;
   
@@ -11077,11 +11203,14 @@ xim_initialize (dpyinfo, resource_name)
   XRegisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb,
                                  resource_name, EMACS_CLASS,
                                  xim_instantiate_callback,
-                                 (XPointer)xim_inst);
-#else /* not HAVE_X11R6 */
+                                 /* Fixme: This is XPointer in
+                                    XFree86 but (XPointer *) on
+                                    Tru64, at least.  */
+                                 (XPointer) xim_inst);
+#else /* not HAVE_X11R6_XIM */
   dpyinfo->xim = NULL;
   xim_open_dpy (dpyinfo, resource_name);
-#endif /* not HAVE_X11R6 */
+#endif /* not HAVE_X11R6_XIM */
 }
 
 
@@ -11091,17 +11220,17 @@ static void
 xim_close_dpy (dpyinfo)
      struct x_display_info *dpyinfo;
 {
-#ifdef HAVE_X11R6
+#ifdef HAVE_X11R6_XIM
   XUnregisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb,
                                    NULL, EMACS_CLASS,
                                    xim_instantiate_callback, NULL);
-#endif /* HAVE_X11R6 */
+#endif /* not HAVE_X11R6_XIM */
   XCloseIM (dpyinfo->xim);
   dpyinfo->xim = NULL;
   XFree (dpyinfo->xim_styles);
 }
 
-#endif /* HAVE_X_I18N */
+#endif /* not HAVE_X11R6_XIM */
 
 
 \f
@@ -11155,7 +11284,7 @@ x_calc_absolute_position (f)
            {
              Window newroot, newparent = 0xdeadbeef;
              Window *newchildren;
-             int nchildren;
+             unsigned int nchildren;
 
              if (! XQueryTree (FRAME_X_DISPLAY (f), this_window, &newroot,
                                &newparent, &newchildren, &nchildren))
@@ -11596,6 +11725,7 @@ x_make_frame_visible (f)
            /* It could be confusing if a real alarm arrives while
               processing the fake one.  Turn it off and let the
               handler reset it.  */
+           extern void poll_for_input_1 P_ ((void));
            int old_poll_suppress_count = poll_suppress_count;
            poll_suppress_count = 1;
            poll_for_input_1 ();
@@ -11827,6 +11957,21 @@ x_destroy_window (f)
       free_frame_menubar (f);
 #endif /* USE_X_TOOLKIT */
 
+      unload_color (f, f->output_data.x->foreground_pixel);
+      unload_color (f, f->output_data.x->background_pixel);
+      unload_color (f, f->output_data.x->cursor_pixel);
+      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)
+       unload_color (f, f->output_data.x->scroll_bar_foreground_pixel);
+      if (f->output_data.x->white_relief.allocated_p)
+       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);
+      
       free_frame_faces (f);
       XFlush (FRAME_X_DISPLAY (f));
     }
@@ -12144,7 +12289,7 @@ x_list_fonts (f, pattern, size, maxnames)
   for (; CONSP (patterns); patterns = XCDR (patterns))
     {
       int num_fonts;
-      char **names;
+      char **names = NULL;
 
       pattern = XCAR (patterns);
       /* See if we cached the result for this particular query.
@@ -12620,9 +12765,8 @@ x_load_font (f, fontname, size)
 
     /* The slot `encoding' specifies how to map a character
        code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
-       the font code-points (0:0x20..0x7F, 1:0xA0..0xFF, 0:0x2020..0x7F7F,
-       the font code-points (0:0x20..0x7F, 1:0xA0..0xFF,
-       0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF, or
+       the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
+       (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
        2:0xA020..0xFF7F).  For the moment, we don't know which charset
        uses this font.  So, we set information in fontp->encoding[1]
        which is never used by any charset.  If mapping can't be
@@ -12886,9 +13030,11 @@ x_term_init (display_name, xrm_option, resource_name)
        if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->function, Qunbound))
          {
            char *vendor = ServerVendor (dpy);
+           UNBLOCK_INPUT;
            dpyinfo->kboard->Vsystem_key_alist
              = call1 (Qvendor_specific_keysyms,
                       build_string (vendor ? vendor : ""));
+           BLOCK_INPUT;
          }
 
        dpyinfo->kboard->next_kboard = all_kboards;
@@ -12945,8 +13091,8 @@ x_term_init (display_name, xrm_option, resource_name)
 
   dpyinfo->screen = ScreenOfDisplay (dpyinfo->display,
                                     DefaultScreen (dpyinfo->display));
-  dpyinfo->visual = select_visual (dpyinfo->display, dpyinfo->screen,
-                                  &dpyinfo->n_planes);
+  select_visual (dpyinfo);
+  dpyinfo->cmap = DefaultColormapOfScreen (dpyinfo->screen);
   dpyinfo->height = HeightOfScreen (dpyinfo->screen);
   dpyinfo->width = WidthOfScreen (dpyinfo->screen);
   dpyinfo->root_window = RootWindowOfScreen (dpyinfo->screen);
@@ -12973,6 +13119,26 @@ x_term_init (display_name, xrm_option, resource_name)
   dpyinfo->x_highlight_frame = 0;
   dpyinfo->image_cache = make_image_cache ();
 
+  /* See if a private colormap is requested.  */
+  if (dpyinfo->visual == DefaultVisualOfScreen (dpyinfo->screen))
+    {
+      if (dpyinfo->visual->class == PseudoColor)
+       {
+         Lisp_Object value;
+         value = display_x_get_resource (dpyinfo,
+                                         build_string ("privateColormap"),
+                                         build_string ("PrivateColormap"),
+                                         Qnil, Qnil);
+         if (STRINGP (value)
+             && (!strcmp (XSTRING (value)->data, "true")
+                 || !strcmp (XSTRING (value)->data, "on")))
+           dpyinfo->cmap = XCopyColormapAndFree (dpyinfo->display, dpyinfo->cmap);
+       }
+    }
+  else
+    dpyinfo->cmap = XCreateColormap (dpyinfo->display, dpyinfo->root_window,
+                                    dpyinfo->visual, AllocNone);
+      
   {
     int screen_number = XScreenNumberOfScreen (dpyinfo->screen);
     double pixels = DisplayHeight (dpyinfo->display, screen_number);
@@ -13116,6 +13282,20 @@ x_term_init (display_name, xrm_option, resource_name)
 #endif
 #endif
 
+  /* See if we should run in synchronous mode.  This is useful
+     for debugging X code.  */
+  {
+    Lisp_Object value;
+    value = display_x_get_resource (dpyinfo,
+                                   build_string ("synchronous"),
+                                   build_string ("Synchronous"),
+                                   Qnil, Qnil);
+    if (STRINGP (value)
+       && (!strcmp (XSTRING (value)->data, "true")
+           || !strcmp (XSTRING (value)->data, "on")))
+      XSynchronize (dpyinfo->display, True);
+  }
+  
   UNBLOCK_INPUT;
 
   return dpyinfo;