Fix -Wimplicit warnings.
[bpt/emacs.git] / src / xterm.c
index 6393ae5..4afe386 100644 (file)
@@ -1,5 +1,5 @@
 /* X Communication module for terminals which understand the X protocol.
-   Copyright (C) 1989, 93, 94, 95, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1989, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -86,6 +86,7 @@ Boston, MA 02111-1307, USA.  */
 #include "window.h"
 #include "keyboard.h"
 #include "intervals.h"
+#include "process.h"
 
 #ifdef USE_X_TOOLKIT
 #include <X11/Shell.h>
@@ -147,7 +148,7 @@ Lisp_Object x_display_name_list;
    is the frame to apply to.  */
 extern struct frame *updating_frame;
 
-extern waiting_for_input;
+extern int waiting_for_input;
 
 /* This is a frame waiting to be autoraised, within XTread_socket.  */
 struct frame *pending_autoraise_frame;
@@ -265,8 +266,8 @@ static void clear_mouse_face ();
 static void show_mouse_face ();
 static void do_line_dance ();
 
-static int XTcursor_to ();
-static int XTclear_end_of_line ();
+static void XTcursor_to ();
+static void XTclear_end_of_line ();
 static int x_io_error_quitter ();
 int x_catch_errors ();
 void x_uncatch_errors ();
@@ -323,7 +324,7 @@ x_display_info_for_display (dpy)
    should never be called except during an update, the only exceptions
    being XTcursor_to, XTwrite_glyphs and XTreassert_line_highlight.  */
 
-static
+static void
 XTupdate_begin (f)
      struct frame *f;
 {
@@ -383,7 +384,7 @@ XTupdate_begin (f)
   UNBLOCK_INPUT;
 }
 
-static
+static void
 XTupdate_end (f)
      struct frame *f;
 {
@@ -413,7 +414,7 @@ XTupdate_end (f)
 
 /* This is called after a redisplay on frame F.  */
 
-static
+static void
 XTframe_up_to_date (f)
      FRAME_PTR f;
 {
@@ -421,9 +422,10 @@ XTframe_up_to_date (f)
   if (FRAME_X_DISPLAY_INFO (f)->mouse_face_deferred_gc
       || f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
     {
-      note_mouse_highlight (FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame,
-                           FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_x,
-                           FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_y);
+      if (FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
+       note_mouse_highlight (FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame,
+                             FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_x,
+                             FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_y);
       FRAME_X_DISPLAY_INFO (f)->mouse_face_deferred_gc = 0;
     }
   UNBLOCK_INPUT;
@@ -433,6 +435,7 @@ XTframe_up_to_date (f)
    Call this when about to modify line at position VPOS
    and not change whether it is highlighted.  */
 
+void
 XTreassert_line_highlight (new, vpos)
      int new, vpos;
 {
@@ -442,7 +445,7 @@ XTreassert_line_highlight (new, vpos)
 /* Call this when about to modify line at position VPOS
    and change whether it is highlighted.  */
 
-static
+static void
 XTchange_line_highlight (new_highlight, vpos, first_unused_hpos)
      int new_highlight, vpos, first_unused_hpos;
 {
@@ -455,7 +458,7 @@ XTchange_line_highlight (new_highlight, vpos, first_unused_hpos)
    When starting Emacs, no X window is mapped.  And nothing must be done
    to Emacs's own window if it is suspended (though that rarely happens).  */
 
-static
+static void
 XTset_terminal_modes ()
 {
 }
@@ -464,7 +467,7 @@ XTset_terminal_modes ()
    Exiting will make the X-windows go away, and suspending
    requires no action.  */
 
-static
+static void
 XTreset_terminal_modes ()
 {
 /*  XTclear_frame ();  */
@@ -474,7 +477,7 @@ XTreset_terminal_modes ()
    This is where display update commands will take effect.
    This does not affect the place where the cursor-box is displayed.  */
 
-static int
+static void
 XTcursor_to (row, col)
      register int row, col;
 {
@@ -543,8 +546,11 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp)
      struct cmpchar_info *cmpcharp;
 {
   /* Holds characters to be displayed. */
-  XChar2b *buf = (XChar2b *) alloca (FRAME_WINDOW_WIDTH (f) * sizeof (*buf));
-  register XChar2b *cp;                /* Steps through buf[]. */
+  XChar2b *x_2byte_buffer
+    = (XChar2b *) alloca (FRAME_WINDOW_WIDTH (f) * sizeof (*x_2byte_buffer));
+  register XChar2b *cp;                /* Steps through x_2byte_buffer[]. */
+  char *x_1byte_buffer
+    = (char *) alloca (FRAME_WINDOW_WIDTH (f) * sizeof (*x_1byte_buffer));
   register int tlen = GLYPH_TABLE_LENGTH;
   register Lisp_Object *tbase = GLYPH_TABLE_BASE;
   Window window = FRAME_X_WINDOW (f);
@@ -557,7 +563,8 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp)
       /* Get the face-code of the next GLYPH.  */
       int cf, len;
       GLYPH g = *gp;
-      int ch, first_ch, charset;
+      int ch, charset;
+      Lisp_Object first_ch;
       /* HIGHEST and LOWEST are used while drawing a composite
          character.  The meanings are described later.  */
       int highest, lowest;
@@ -565,7 +572,7 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp)
       GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
       cf = (cmpcharp ? cmpcharp->face_work : FAST_GLYPH_FACE (g));
       ch = FAST_GLYPH_CHAR (g);
-      if (gidx == 0) first_ch = ch;
+      if (gidx == 0) XSETFASTINT (first_ch, ch);
       charset = CHAR_CHARSET (ch);
       if (charset == CHARSET_COMPOSITION)
        {
@@ -591,10 +598,10 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp)
 
       /* Find the run of consecutive glyphs which can be drawn with
         the same GC (i.e. the same charset and the same face-code).
-        Extract their character codes into BUF.
+        Extract their character codes into X_2BYTE_BUFFER.
         If CMPCHARP is not NULL, face-code is not checked because we
         use only the face specified in `cmpcharp->face_work'.  */
-      cp = buf;
+      cp = x_2byte_buffer;
       while (n > 0)
        {
          int this_charset, c1, c2;
@@ -618,7 +625,7 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp)
        }
 
       /* LEN gets the length of the run.  */
-      len = cp - buf;
+      len = cp - x_2byte_buffer;
       /* Now output this run of chars, with the font and pixel values
         determined by the face code CF.  */
       {
@@ -724,20 +731,30 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp)
                struct ccl_program *ccl = fontp->font_encoder;
 
                if (CHARSET_DIMENSION (charset) == 1)
-                 for (cp = buf; cp < buf + len; cp++)
+                 for (cp = x_2byte_buffer; cp < x_2byte_buffer + len; cp++)
                    {
                      ccl->reg[0] = charset;
                      ccl->reg[1] = cp->byte2;
                      ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
-                     cp->byte2 = ccl->reg[1];
+                     /* We assume that MSBs are appropriately
+                         set/reset by CCL program.  */
+                     if (font->max_byte1 == 0) /* 1-byte font */
+                       cp->byte2 = ccl->reg[1];
+                     else
+                       cp->byte1 = ccl->reg[1], cp->byte2 = ccl->reg[2];
                    }
                else
-                 for (cp = buf; cp < buf + len; cp++)
+                 for (cp = x_2byte_buffer; cp < x_2byte_buffer + len; cp++)
                    {
                      ccl->reg[0] = charset;
                      ccl->reg[1] = cp->byte1, ccl->reg[2] = cp->byte2;
                      ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
-                     cp->byte1 = ccl->reg[1], cp->byte2 = ccl->reg[2];
+                     /* We assume that MSBs are appropriately
+                         set/reset by CCL program.  */
+                     if (font->max_byte1 == 0) /* 1-byte font */
+                       cp->byte2 = ccl->reg[1];
+                     else
+                       cp->byte1 = ccl->reg[1], cp->byte2 = ccl->reg[2];
                    }
              }
            else if (fontp->encoding[charset])
@@ -745,10 +762,10 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp)
                int enc = fontp->encoding[charset];
 
                if ((enc == 1 || enc == 2) && CHARSET_DIMENSION (charset) == 2)
-                 for (cp = buf; cp < buf + len; cp++)
+                 for (cp = x_2byte_buffer; cp < x_2byte_buffer + len; cp++)
                    cp->byte1 |= 0x80;
                if (enc == 1 || enc == 3)
-                 for (cp = buf; cp < buf + len; cp++)
+                 for (cp = x_2byte_buffer; cp < x_2byte_buffer + len; cp++)
                    cp->byte2 |= 0x80;
              }
          }
@@ -760,7 +777,7 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp)
                font = FACE_FONT (face);
                if (font == (XFontStruct *) FACE_DEFAULT)
                  font = f->output_data.x->font;
-               baseline = FONT_BASE (font);
+               baseline = FONT_BASE (f->output_data.x->font);
                if (charset == charset_latin_iso8859_1)
                  {
                    if (font->max_char_or_byte2 < 0x80)
@@ -768,7 +785,7 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp)
                      font = NULL;
                    else
                      {
-                       for (cp = buf; cp < buf + len; cp++)
+                       for (cp = x_2byte_buffer; cp < x_2byte_buffer + len; cp++)
                          cp->byte2 |= 0x80;
                      }
                  }
@@ -865,8 +882,7 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp)
          {
            /* Fill a area for the current run in background pixle of GC.  */
            XGCValues xgcv;
-           unsigned long mask = GCForeground | GCBackground;
-           unsigned long fore, back;
+           unsigned long mask = GCForeground | GCBackground | GCFillStyle;
 
            /* The current code at first set foreground to background,
              fill the area, then recover the original foreground.
@@ -874,6 +890,7 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp)
 
            XGetGCValues (FRAME_X_DISPLAY (f), gc, mask, &xgcv);
            XSetForeground (FRAME_X_DISPLAY (f), gc, xgcv.background);
+           XSetFillStyle (FRAME_X_DISPLAY (f), gc, FillSolid);
            XFillRectangle (FRAME_X_DISPLAY (f), window, gc,
                            left, top, run_width, line_height);
            XSetForeground (FRAME_X_DISPLAY (f), gc, xgcv.foreground);
@@ -912,24 +929,50 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp)
                      if (background_filled)
                        XDrawString16 (FRAME_X_DISPLAY (f), window, gc,
                                       left + glyph_width * i,
-                                      top + baseline, buf + i, 1);
+                                      top + baseline, x_2byte_buffer + i, 1);
                      else
                        XDrawImageString16 (FRAME_X_DISPLAY (f), window, gc,
                                            left + glyph_width * i,
-                                           top + baseline, buf + i, 1);
+                                           top + baseline, x_2byte_buffer + i, 1);
                    }
                else
                  {
-                   if (background_filled)
-                     XDrawString16 (FRAME_X_DISPLAY (f), window, gc,
-                                    left, top + baseline, buf, len);
+                   /* See if this whole buffer can be output as 8-bit chars.
+                      If so, copy x_2byte_buffer to x_1byte_buffer
+                      and do it as 8-bit chars.  */
+                   for (i = 0; i < len; i++)
+                     {
+                       if (x_2byte_buffer[i].byte1 != 0)
+                         break;
+                       x_1byte_buffer[i] = x_2byte_buffer[i].byte2;
+                     }
+
+                   if (i == len)
+                     {
+                       if (background_filled)
+                         XDrawString (FRAME_X_DISPLAY (f), window, gc,
+                                      left, top + baseline, x_1byte_buffer, len);
+                       else
+                         XDrawImageString (FRAME_X_DISPLAY (f), window, gc,
+                                           left, top + baseline, x_1byte_buffer, len);
+                     }
                    else
-                     XDrawImageString16 (FRAME_X_DISPLAY (f), window, gc,
-                                         left, top + baseline, buf, len);
+                     {
+                       /* We can't output them as 8-bit chars,
+                          so do it as 16-bit chars.  */
+
+                       if (background_filled)
+                         XDrawString16 (FRAME_X_DISPLAY (f), window, gc,
+                                        left, top + baseline, x_2byte_buffer, len);
+                       else
+                         XDrawImageString16 (FRAME_X_DISPLAY (f), window, gc,
+                                             left, top + baseline, x_2byte_buffer, len);
+                     }
                  }
              }
            else
              {
+               /* Handle composite characters.  */
                XCharStruct *pcm; /* Pointer to per char metric info.  */
 
                if ((cmpcharp->cmp_rule || relative_compose)
@@ -949,7 +992,7 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp)
                      }
                    else
                      {
-                       pcm = PER_CHAR_METRIC (font, buf);
+                       pcm = PER_CHAR_METRIC (font, x_2byte_buffer);
                        highest = pcm->ascent + 1;
                        lowest = - pcm->descent;
                      }
@@ -959,7 +1002,7 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp)
                                  * FONT_WIDTH (f->output_data.x->font));
                    /* Draw the first character at the normal position.  */
                    XDrawString16 (FRAME_X_DISPLAY (f), window, gc,
-                                  left + x_offset, top + baseline, buf, 1);
+                                  left + x_offset, top + baseline, x_2byte_buffer, 1);
                    i = 1;
                    gidx++;
                  }
@@ -972,18 +1015,33 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp)
 
                    if (relative_compose)
                      {
-                       pcm = PER_CHAR_METRIC (font, buf + i);
-                       if (- pcm->descent >= relative_compose)
+                       pcm = PER_CHAR_METRIC (font, x_2byte_buffer + i);
+                       if (NILP (Vignore_relative_composition)
+                           || NILP (Faref (Vignore_relative_composition,
+                                           make_number (cmpcharp->glyph[gidx]))))
                          {
-                           /* Draw above the current glyphs.  */
-                           y_offset = highest + pcm->descent;
-                           highest += pcm->ascent + pcm->descent;
+                           if (- pcm->descent >= relative_compose)
+                             {
+                               /* Draw above the current glyphs.  */
+                               y_offset = highest + pcm->descent;
+                               highest += pcm->ascent + pcm->descent;
+                             }
+                           else if (pcm->ascent <= 0)
+                             {
+                               /* Draw beneath the current glyphs.  */
+                               y_offset = lowest - pcm->ascent;
+                               lowest -= pcm->ascent + pcm->descent;
+                             }
                          }
-                       else if (pcm->ascent <= 0)
+                       else
                          {
-                           /* Draw beneath the current glyphs.  */
-                           y_offset = lowest - pcm->ascent;
-                           lowest -= pcm->ascent + pcm->descent;
+                           /* Draw the glyph at normal position.  If
+                               it sticks out of HIGHEST or LOWEST,
+                               update them appropriately.  */
+                           if (pcm->ascent > highest)
+                             highest = pcm->ascent;
+                           else if (- pcm->descent < lowest)
+                             lowest = - pcm->descent;
                          }
                      }
                    else if (cmpcharp->cmp_rule)
@@ -998,7 +1056,7 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp)
                        gref = gref / 3 + (gref == 4) * 2;
                        nref = nref / 3 + (nref == 4) * 2;
 
-                       pcm = PER_CHAR_METRIC (font, buf + i);
+                       pcm = PER_CHAR_METRIC (font, x_2byte_buffer + i);
                        bottom = ((gref == 0 ? highest : gref == 1 ? 0
                                   : gref == 2 ? lowest
                                   : (highest + lowest) / 2)
@@ -1016,7 +1074,7 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground, cmpcharp)
                      }
                    XDrawString16 (FRAME_X_DISPLAY (f), window, gc,
                                   left + x_offset, top + baseline - y_offset,
-                                  buf + i, 1);
+                                  x_2byte_buffer + i, 1);
                  }
              }
            if (require_clipping)
@@ -1128,7 +1186,7 @@ dumpglyphs (f, left, top, gp, n, hl, font)
    `highlight', set up by XTreassert_line_highlight or XTchange_line_highlight,
    controls the pixel values used for foreground and background.  */
 
-static
+static void
 XTwrite_glyphs (start, len)
      register GLYPH *start;
      int len;
@@ -1174,7 +1232,7 @@ XTwrite_glyphs (start, len)
    to column FIRST_UNUSED (exclusive).  The idea is that everything
    from FIRST_UNUSED onward is already erased.  */
 
-static
+static void
 XTclear_end_of_line (first_unused)
      register int first_unused;
 {
@@ -1216,7 +1274,7 @@ XTclear_end_of_line (first_unused)
   UNBLOCK_INPUT;
 }
 
-static
+static void
 XTclear_frame ()
 {
   int mask;
@@ -1452,6 +1510,7 @@ timeval_subtract (result, x, y)
   return x.tv_sec < y.tv_sec;
 }
 
+void
 XTflash (f)
      struct frame *f;
 {
@@ -1579,6 +1638,7 @@ XTflash (f)
 
 #define XRINGBELL XBell (FRAME_X_DISPLAY (selected_frame), 0)
 
+void
 XTring_bell ()
 {
   if (FRAME_X_DISPLAY (selected_frame) == 0)
@@ -1601,7 +1661,7 @@ XTring_bell ()
    These are not supposed to be used because we are supposed to turn
    off the feature of using them.  */
 
-static
+static void
 XTinsert_glyphs (start, len)
      register char *start;
      register int len;
@@ -1609,7 +1669,7 @@ XTinsert_glyphs (start, len)
   abort ();
 }
 
-static
+static void
 XTdelete_glyphs (n)
      register int n;
 {
@@ -1621,7 +1681,7 @@ XTdelete_glyphs (n)
    This, and those operations, are used only within an update
    that is bounded by calls to XTupdate_begin and XTupdate_end.  */
 
-static
+static void
 XTset_terminal_window (n)
      register int n;
 {
@@ -1652,6 +1712,7 @@ static int line_dance_in_progress;
 
 /* Perform an insert-lines or delete-lines operation,
    inserting N lines or deleting -N lines at vertical position VPOS.  */
+void
 XTins_del_lines (vpos, n)
      int vpos, n;
 {
@@ -2637,6 +2698,7 @@ clear_mouse_face (dpyinfo)
 /* Just discard the mouse face information for frame F, if any.
    This is used when the size of F is changed.  */
 
+void
 cancel_mouse_face (f)
      FRAME_PTR f;
 {
@@ -2688,7 +2750,7 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
 
   BLOCK_INPUT;
 
-  if (! NILP (last_mouse_scroll_bar))
+  if (! NILP (last_mouse_scroll_bar) && insist == 0)
     x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
   else
     {
@@ -2817,7 +2879,7 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
              }
          }
 
-       if (f1 == 0 && insist)
+       if (f1 == 0 && insist > 0)
          f1 = selected_frame;
 
        if (f1)
@@ -3504,6 +3566,7 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
    Clear out the scroll bars, and ask for expose events, so we can
    redraw them.  */
 
+void
 x_scroll_bar_clear (f)
      FRAME_PTR f;
 {
@@ -3791,20 +3854,32 @@ XTread_socket (sd, bufp, numchars, expected)
                    if (event.xclient.data.l[0]
                        == dpyinfo->Xatom_wm_take_focus)
                      {
-                       f = x_window_to_frame (dpyinfo, event.xclient.window);
-                       /* Since we set WM_TAKE_FOCUS, we must call
-                          XSetInputFocus explicitly.  But not if f is null,
-                          since that might be an event for a deleted frame.  */
+                       /* Use x_any_window_to_frame because this
+                          could be the shell widget window
+                          if the frame has no title bar.  */
+                       f = x_any_window_to_frame (dpyinfo, event.xclient.window);
 #ifdef HAVE_X_I18N
                        /* Not quite sure this is needed -pd */
-                       if (f)
+                       if (f && FRAME_XIC (f))
                          XSetICFocus (FRAME_XIC (f));
 #endif
+                       /* Since we set WM_TAKE_FOCUS, we must call
+                          XSetInputFocus explicitly.  But not if f is null,
+                          since that might be an event for a deleted frame.  */
                        if (f)
-                         XSetInputFocus (event.xclient.display,
-                                         event.xclient.window,
-                                         RevertToPointerRoot,
-                                         event.xclient.data.l[1]);
+                         {
+                           Display *d = event.xclient.display;
+                           /* Catch and ignore errors, in case window has been
+                              iconified by a window manager such as GWM.  */
+                           int count = x_catch_errors (d);
+                           XSetInputFocus (d, event.xclient.window,
+                                           RevertToPointerRoot,
+                                           event.xclient.data.l[1]);
+                           /* This is needed to detect the error
+                              if there is an error.  */
+                           XSync (d, False);
+                           x_uncatch_errors (d, count);
+                         }  
                        /* Not certain about handling scroll bars here */
                      }
                    else if (event.xclient.data.l[0]
@@ -3891,7 +3966,7 @@ XTread_socket (sd, bufp, numchars, expected)
              if (! x_window_to_frame (dpyinfo, event.xselection.requestor))
                goto OTHER;
 #endif /* not USE_X_TOOLKIT */
-             x_handle_selection_notify (&event);
+             x_handle_selection_notify (&event.xselection);
              break;
 
            case SelectionClear:        /* Someone has grabbed ownership. */
@@ -3952,7 +4027,7 @@ XTread_socket (sd, bufp, numchars, expected)
              if (!x_any_window_to_frame (dpyinfo, event.xproperty.window))
                goto OTHER;
 #endif /* not USE_X_TOOLKIT */
-             x_handle_property_notify (&event);
+             x_handle_property_notify (&event.xproperty);
              break;
 
            case ReparentNotify:
@@ -4135,6 +4210,10 @@ XTread_socket (sd, bufp, numchars, expected)
 #ifdef HAVE_X_I18N
                  if (FRAME_XIC (f))
                    {
+                     /* The necessity of the following line took me
+                        a full work-day to decipher from the docs!!  */
+                     if (XFilterEvent (&event, None))
+                       break;
                      nbytes = XmbLookupString (FRAME_XIC (f),
                                                &event.xkey, copy_buffer,
                                                80, &keysym,
@@ -4408,6 +4487,16 @@ XTread_socket (sd, bufp, numchars, expected)
                      f->output_data.x->win_gravity = NorthWestGravity;
                      x_wm_set_size_hint (f, (long) 0, 0);
                    }
+#ifdef USE_MOTIF
+                 /* Some window managers pass (0,0) as the location of
+                    the window, and the Motif event handler stores it
+                    in the emacs widget, which messes up Motif menus.  */
+                 if (event.xconfigure.x == 0 && event.xconfigure.y == 0)
+                   {
+                     event.xconfigure.x = f->output_data.x->widget->core.x;
+                     event.xconfigure.y = f->output_data.x->widget->core.y;
+                   }
+#endif
                }
              goto OTHER;
 
@@ -4588,12 +4677,27 @@ x_draw_box (f, x, y)
   int c = FAST_GLYPH_CHAR (f->phys_cursor_glyph);
   int charset = CHAR_CHARSET (c);
 
+  XGCValues xgcv;
+  unsigned long mask = GCForeground;
+
+  xgcv.foreground = f->output_data.x->cursor_pixel;
+
+  /* cursor_gc's foreground color is typically the same as the normal
+     background color, which can cause the cursor box to be invisible.  */
+  if (FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc)
+    XChangeGC (FRAME_X_DISPLAY (f),
+               FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc,
+               mask, &xgcv);
+  else
+    FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc
+      = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), mask, &xgcv);
+
   /* If cursor is on a multi-column character, multiply WIDTH by columns.  */
   width *= (charset == CHARSET_COMPOSITION
            ? cmpchar_table[COMPOSITE_CHAR_ID (c)]->width
            : CHARSET_WIDTH (charset));
   XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-                 f->output_data.x->cursor_gc,
+                  FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc,
                  left, top, width - 1, height - 1);
 }
 
@@ -4799,6 +4903,7 @@ x_display_box_cursor (f, on, x, y)
 /* Display the cursor on frame F, or clear it, according to ON.
    Also set the frame's cursor position to X and Y.  */
 
+void
 x_display_cursor (f, on, x, y)
      struct frame *f;
      int on;
@@ -4806,6 +4911,10 @@ x_display_cursor (f, on, x, y)
 {
   BLOCK_INPUT;
 
+ if ((unsigned) x >= FRAME_WIDTH (f) + FRAME_LEFT_SCROLL_BAR_WIDTH (f)
+      || (unsigned) y >= FRAME_HEIGHT (f))
+    abort ();
+
   if (FRAME_DESIRED_CURSOR (f) == filled_box_cursor)
     x_display_box_cursor (f, on, x, y);
   else if (FRAME_DESIRED_CURSOR (f) == bar_cursor)
@@ -4820,6 +4929,7 @@ x_display_cursor (f, on, x, y)
 /* Display the cursor on frame F, or clear it, according to ON.
    Don't change the cursor's position.  */
 
+void
 x_update_cursor (f, on)
      struct frame *f;
      int on;
@@ -4842,6 +4952,7 @@ x_update_cursor (f, on)
 /* Refresh bitmap kitchen sink icon for frame F
    when we get an expose event for it. */
 
+void
 refreshicon (f)
      struct frame *f;
 {
@@ -5218,7 +5329,10 @@ x_new_font (f, fontname)
       f->scroll_bar_cols = (f->scroll_bar_pixel_width + wid-1) / wid;
     }
   else
-    f->scroll_bar_cols = 2;
+    {
+      int wid = FONT_WIDTH (f->output_data.x->font);
+      f->scroll_bar_cols = (14 + wid - 1) / wid;
+    }
 
   /* Now make the frame display the given font.  */
   if (FRAME_X_WINDOW (f) != 0)
@@ -5286,6 +5400,7 @@ x_new_fontset (f, fontsetname)
 /* Calculate the absolute position in frame F
    from its current recorded position values and gravity.  */
 
+void
 x_calc_absolute_position (f)
      struct frame *f;
 {
@@ -5378,6 +5493,7 @@ x_calc_absolute_position (f)
    position values).  It is -1 when calling from x_set_frame_parameters,
    which means, do adjust for borders but don't change the gravity.  */
 
+void
 x_set_offset (f, xoff, yoff, change_gravity)
      struct frame *f;
      register int xoff, yoff;
@@ -5429,6 +5545,7 @@ x_set_offset (f, xoff, yoff, change_gravity)
    for this size change and subsequent size changes.
    Otherwise we leave the window gravity unchanged.  */
 
+void
 x_set_window_size (f, change_gravity, cols, rows)
      struct frame *f;
      int change_gravity;
@@ -5555,6 +5672,7 @@ x_set_mouse_pixel_position (f, pix_x, pix_y)
 \f
 /* focus shifting, raising and lowering.  */
 
+void
 x_focus_on_frame (f)
      struct frame *f;
 {
@@ -5570,6 +5688,7 @@ x_focus_on_frame (f)
 #endif /* ! 0 */
 }
 
+void
 x_unfocus_frame (f)
      struct frame *f;
 {
@@ -5583,6 +5702,7 @@ x_unfocus_frame (f)
 
 /* Raise frame F.  */
 
+void
 x_raise_frame (f)
      struct frame *f;
 {
@@ -5601,6 +5721,7 @@ x_raise_frame (f)
 
 /* Lower frame F.  */
 
+void
 x_lower_frame (f)
      struct frame *f;
 {
@@ -5637,6 +5758,7 @@ XTframe_raise_lower (f, raise_flag)
    but it will become visible later when the window manager
    finishes with it.  */
 
+void
 x_make_frame_visible (f)
      struct frame *f;
 {
@@ -5709,7 +5831,7 @@ x_make_frame_visible (f)
        because the window manager may choose the position
        and we don't want to override it.  */
 
-    if (! FRAME_VISIBLE_P (f)
+    if (! FRAME_VISIBLE_P (f) && ! FRAME_ICONIFIED_P (f)
        && f->output_data.x->win_gravity == NorthWestGravity
        && previously_visible)
       {
@@ -5747,7 +5869,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.  */
            alarm (0);
-           input_poll_signal ();
+           input_poll_signal (0);
          }
        /* Once we have handled input events,
           we should have received the MapNotify if one is coming.
@@ -5765,6 +5887,7 @@ x_make_frame_visible (f)
 
 /* Make the frame visible (mapped and not iconified).  */
 
+void
 x_make_frame_invisible (f)
      struct frame *f;
 {
@@ -5847,6 +5970,7 @@ x_make_frame_invisible (f)
 
 /* Change window state from mapped to iconified. */
 
+void
 x_iconify_frame (f)
      struct frame *f;
 {
@@ -5955,6 +6079,7 @@ x_iconify_frame (f)
 \f
 /* Destroy the X window of frame F.  */
 
+void
 x_destroy_window (f)
      struct frame *f;
 {
@@ -6011,6 +6136,8 @@ x_destroy_window (f)
       dpyinfo->mouse_face_end_row
        = dpyinfo->mouse_face_end_col = -1;
       dpyinfo->mouse_face_window = Qnil;
+      dpyinfo->mouse_face_deferred_gc = 0;
+      dpyinfo->mouse_face_mouse_frame = 0;
     }
 
   UNBLOCK_INPUT;
@@ -6024,6 +6151,7 @@ x_destroy_window (f)
    If USER_POSITION is nonzero, we set the USPosition
    flag (this is useful when FLAGS is 0).  */
 
+void
 x_wm_set_size_hint (f, flags, user_position)
      struct frame *f;
      long flags;
@@ -6167,6 +6295,7 @@ x_wm_set_size_hint (f, flags, user_position)
 }
 
 /* Used for IconicState or NormalState */
+void
 x_wm_set_window_state (f, state)
      struct frame *f;
      int state;
@@ -6186,6 +6315,7 @@ x_wm_set_window_state (f, state)
 #endif /* not USE_X_TOOLKIT */
 }
 
+void
 x_wm_set_icon_pixmap (f, pixmap_id)
      struct frame *f;
      int pixmap_id;
@@ -6235,6 +6365,7 @@ x_wm_set_icon_pixmap (f, pixmap_id)
 #endif /* not USE_X_TOOLKIT */
 }
 
+void
 x_wm_set_icon_position (f, icon_x, icon_y)
      struct frame *f;
      int icon_x, icon_y;
@@ -6278,20 +6409,27 @@ x_list_fonts (f, pattern, size, maxnames)
      int size;
      int maxnames;
 {
-  Lisp_Object list, patterns, newlist = Qnil, key, tem, second_best;
+  Lisp_Object list = Qnil, patterns, newlist = Qnil, key, tem, second_best;
   Display *dpy = f != NULL ? FRAME_X_DISPLAY (f) : x_display_list->display;
 
-  patterns = Fassoc (pattern, Valternative_fontname_alist);
+  patterns = Fassoc (pattern, Valternate_fontname_alist);
   if (NILP (patterns))
     patterns = Fcons (pattern, Qnil);
 
+  /* We try at least 10 fonts because X server will return auto-scaled
+     fonts at the head.  */
+  if (maxnames < 10) maxnames = 10;
+
   for (; CONSP (patterns); patterns = XCONS (patterns)->cdr)
     {
       int num_fonts;
       char **names;
 
       pattern = XCONS (patterns)->car;
-      /* See if we cached the result for this particular query.  */
+      /* See if we cached the result for this particular query.
+         The cache is an alist of the form:
+          (((PATTERN . MAXNAMES) (FONTNAME . WIDTH) ...) ...)
+      */
       if (f && (tem = XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr,
                key = Fcons (pattern, make_number (maxnames)),
                !NILP (list = Fassoc (key, tem))))
@@ -6365,6 +6503,8 @@ x_list_fonts (f, pattern, size, maxnames)
       /* Make a list of the fonts that have the right width.  */
       for (; CONSP (list); list = XCONS (list)->cdr)
        {
+         int found_size;
+
          tem = XCONS (list)->car;
 
          if (!CONSP (tem) || NILP (XCONS (tem)->car))
@@ -6388,7 +6528,10 @@ x_list_fonts (f, pattern, size, maxnames)
 
              if (thisinfo)
                {
-                 XCONS (tem)->cdr =  make_number (thisinfo->max_bounds.width);
+                 XCONS (tem)->cdr
+                   = (thisinfo->min_bounds.width == 0
+                      ? make_number (0)
+                      : make_number (thisinfo->max_bounds.width));
                  XFreeFont (dpy, thisinfo);
                }
              else
@@ -6397,21 +6540,26 @@ x_list_fonts (f, pattern, size, maxnames)
                  as 0 not to try to open it again.  */
                XCONS (tem)->cdr = make_number (0);
            }
-         if (XINT (XCONS (tem)->cdr) == size)
+
+         found_size = XINT (XCONS (tem)->cdr);
+         if (found_size == size)
            newlist = Fcons (XCONS (tem)->car, newlist);
-         else if (NILP (second_best))
-           second_best = tem;
-         else if (XINT (XCONS (tem)->cdr) < size)
+         else if (found_size > 0)
            {
-             if (XINT (XCONS (second_best)->cdr) > size
-                 || XINT (XCONS (second_best)->cdr) < XINT (XCONS (tem)->cdr))
-               second_best = tem;
-           }
-         else
-           {
-             if (XINT (XCONS (second_best)->cdr) > size
-                 && XINT (XCONS (second_best)->cdr) > XINT (XCONS (tem)->cdr))
+             if (NILP (second_best))
                second_best = tem;
+             else if (found_size < size)
+               {
+                 if (XINT (XCONS (second_best)->cdr) > size
+                     || XINT (XCONS (second_best)->cdr) < found_size)
+                   second_best = tem;
+               }
+             else
+               {
+                 if (XINT (XCONS (second_best)->cdr) > size
+                     && XINT (XCONS (second_best)->cdr) > found_size)
+                   second_best = tem;
+               }
            }
        }
       if (!NILP (newlist))
@@ -6543,7 +6691,7 @@ x_load_font (f, fontname, size)
       fontp->full_name = fontp->name;
 
     fontp->size = font->max_bounds.width;
-    fontp->height = font->ascent + font->descent;
+    fontp->height = font->max_bounds.ascent + font->max_bounds.descent;
 
     if (NILP (font_names))
       {
@@ -6810,8 +6958,8 @@ x_term_init (display_name, xrm_option, resource_name)
 #endif /* ! 0 */
 
   dpyinfo->x_id_name
-    = (char *) xmalloc (XSTRING (Vinvocation_name)->size
-                       + XSTRING (Vsystem_name)->size
+    = (char *) xmalloc (STRING_BYTES (XSTRING (Vinvocation_name))
+                       + STRING_BYTES (XSTRING (Vsystem_name))
                        + 2);
   sprintf (dpyinfo->x_id_name, "%s@%s",
           XSTRING (Vinvocation_name)->data, XSTRING (Vsystem_name)->data);
@@ -6916,7 +7064,9 @@ x_term_init (display_name, xrm_option, resource_name)
   dpyinfo->connection = connection;
 
   {
-    char null_bits[] = { 0x00 };
+    char null_bits[1];
+
+    null_bits[0] = 0x00;
 
     dpyinfo->null_pixel
       = XCreatePixmapFromBitmapData (dpyinfo->display, dpyinfo->root_window, 
@@ -6947,6 +7097,7 @@ x_term_init (display_name, xrm_option, resource_name)
 #endif /* ! defined (SIGIO) */
 
 #ifdef USE_LUCID
+#ifdef HAVE_X11R5 /* It seems X11R4 lacks XtCvtStringToFont, and XPointer.  */
   /* Make sure that we have a valid font for dialog boxes
      so that Xt does not crash.  */
   {
@@ -6969,6 +7120,7 @@ x_term_init (display_name, xrm_option, resource_name)
     x_uncatch_errors (dpy, count);
   }
 #endif
+#endif
 
 
   UNBLOCK_INPUT;
@@ -7034,6 +7186,7 @@ x_delete_display (dpyinfo)
 \f
 /* Set up use of X before we make the first connection.  */
 
+void
 x_initialize ()
 {
   clear_frame_hook = XTclear_frame;