(XTflash): Don't flash in the internal borders.
[bpt/emacs.git] / src / xterm.c
index 1671158..d06335b 100644 (file)
@@ -51,9 +51,9 @@ Boston, MA 02111-1307, USA.  */
 #endif /* makedev */
 #endif /* USG */
 
-#ifdef BSD
+#ifdef BSD_SYSTEM
 #include <sys/ioctl.h>
-#endif /* ! defined (BSD) */
+#endif /* ! defined (BSD_SYSTEM) */
 
 #include "systty.h"
 #include "systime.h"
@@ -195,9 +195,10 @@ static int curs_y;
 
 /* Where the mouse was last time we reported a mouse event.  */
 static FRAME_PTR last_mouse_frame;
-static FRAME_PTR last_mouse_press_frame;
 static XRectangle last_mouse_glyph;
 
+static Lisp_Object last_mouse_press_frame;
+
 /* The scroll bar in which the last X motion event occurred.
 
    If the last X motion event occurred in a scroll bar, we set this
@@ -333,6 +334,9 @@ XTupdate_begin (f)
 
   BLOCK_INPUT;
 
+  curs_x = FRAME_CURSOR_X (f);
+  curs_y = FRAME_CURSOR_Y (f);
+
   if (f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
     {
       /* Don't do highlighting for mouse motion during the update.  */
@@ -385,10 +389,9 @@ XTupdate_end (f)
   BLOCK_INPUT;
 
   do_line_dance ();
-  x_display_cursor (f, 1);
+  x_display_cursor (f, 1, curs_x, curs_y);
 
-  if (f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
-    FRAME_X_DISPLAY_INFO (f)->mouse_face_defer = 0;
+  FRAME_X_DISPLAY_INFO (f)->mouse_face_defer = 0;
 #if 0
   /* This fails in the case of having updated only the echo area
      if we have switched buffers.  In that case, FRAME_CURRENT_GLYPHS
@@ -442,7 +445,7 @@ XTchange_line_highlight (new_highlight, vpos, first_unused_hpos)
 {
   highlight = new_highlight;
   XTcursor_to (vpos, 0);
-  XTclear_end_of_line (updating_frame->width);
+  XTclear_end_of_line (FRAME_WINDOW_WIDTH (updating_frame));
 }
 
 /* This is used when starting Emacs and when restarting after suspend.
@@ -481,7 +484,7 @@ XTcursor_to (row, col)
   if (updating_frame == 0)
     {
       BLOCK_INPUT;
-      x_display_cursor (selected_frame, 1);
+      x_display_cursor (selected_frame, 1, curs_x, curs_y);
       XFlush (FRAME_X_DISPLAY (selected_frame));
       UNBLOCK_INPUT;
     }
@@ -516,7 +519,7 @@ dumpglyphs (f, left, top, gp, n, hl, just_foreground)
      int just_foreground;
 {
   /* Holds characters to be displayed. */
-  char *buf = (char *) alloca (f->width * sizeof (*buf));
+  char *buf = (char *) alloca (FRAME_WINDOW_WIDTH (f) * sizeof (*buf));
   register char *cp;           /* Steps through buf[]. */
   register int tlen = GLYPH_TABLE_LENGTH;
   register Lisp_Object *tbase = GLYPH_TABLE_BASE;
@@ -802,11 +805,7 @@ XTwrite_glyphs (start, len)
     f->phys_cursor_x = -1;
 
   if (updating_frame == 0)
-    {
-      f->cursor_x += len;
-      x_display_cursor (f, 1);
-      f->cursor_x -= len;
-    }
+    x_display_cursor (f, 1, FRAME_CURSOR_X (f) + len, FRAME_CURSOR_Y (f));
   else
     curs_x += len;
 
@@ -833,8 +832,10 @@ XTclear_end_of_line (first_unused)
   if (first_unused <= 0)
     return;
 
-  if (first_unused >= f->width)
-    first_unused = f->width;
+  if (first_unused >= FRAME_WINDOW_WIDTH (f))
+    first_unused = FRAME_WINDOW_WIDTH (f);
+
+  first_unused += FRAME_LEFT_SCROLL_BAR_WIDTH (f);
 
   BLOCK_INPUT;
 
@@ -1116,11 +1117,49 @@ XTflash (f)
     }
 
     {
-      int width  = PIXEL_WIDTH  (f);
-      int height = PIXEL_HEIGHT (f);
+      /* Get the height not including a menu bar widget.  */
+      int height = CHAR_TO_PIXEL_HEIGHT (f, FRAME_HEIGHT (f));
+      /* Height of each line to flash.  */
+      int flash_height = FRAME_LINE_HEIGHT (f);
+      /* These will be the left and right margins of the rectangles.  */
+      int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
+      int flash_right = PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
+
+      int width;
+
+      /* Don't flash the area between a scroll bar and the frame
+        edge it is next to.  */
+      switch (FRAME_VERTICAL_SCROLL_BAR_TYPE (f))
+       {
+       case vertical_scroll_bar_left:
+         flash_left += VERTICAL_SCROLL_BAR_WIDTH_TRIM;
+         break;
+
+       case vertical_scroll_bar_right:
+         flash_right -= VERTICAL_SCROLL_BAR_WIDTH_TRIM;
+         break;
+       }
+
+      width = flash_right - flash_left;
+
+      /* If window is tall, flash top and bottom line.  */
+      if (height > 3 * FRAME_LINE_HEIGHT (f))
+       {
+         XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
+                         flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
+                         width, flash_height);
+         XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
+                         flash_left,
+                         (height - flash_height
+                          - FRAME_INTERNAL_BORDER_WIDTH (f)),
+                         width, flash_height);
+       }
+      else
+       /* If it is short, flash it all.  */ 
+       XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
+                       flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
+                       width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
 
-      XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
-                     width/4, height/4, width/2, height/2);
       XFlush (FRAME_X_DISPLAY (f));
 
       {
@@ -1150,8 +1189,24 @@ XTflash (f)
          }
       }
 
-      XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
-                     width/4, height/4, width/2, height/2);
+      /* If window is tall, flash top and bottom line.  */
+      if (height > 3 * FRAME_LINE_HEIGHT (f))
+       {
+         XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
+                         flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
+                         width, flash_height);
+         XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
+                         flash_left,
+                         (height - flash_height
+                          - FRAME_INTERNAL_BORDER_WIDTH (f)),
+                         width, flash_height);
+       }
+      else
+       /* If it is short, flash it all.  */ 
+       XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
+                       flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
+                       width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
+
       XFreeGC (FRAME_X_DISPLAY (f), gc);
       XFlush (FRAME_X_DISPLAY (f));
     }
@@ -1302,9 +1357,9 @@ do_line_dance ()
     abort ();
 
   ht = f->height;
-  intborder = f->output_data.x->internal_border_width;
+  intborder = CHAR_TO_PIXEL_COL (f, FRAME_LEFT_SCROLL_BAR_WIDTH (f));
 
-  x_display_cursor (updating_frame, 0);
+  x_update_cursor (updating_frame, 0);
 
   for (i = 0; i < ht; ++i)
     if (line_dance[i] != -1 && (distance = line_dance[i]-i) > 0)
@@ -1315,7 +1370,7 @@ do_line_dance ()
        XCopyArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                   FRAME_X_WINDOW (f), f->output_data.x->normal_gc,
                   intborder, CHAR_TO_PIXEL_ROW (f, i+distance),
-                  f->width * FONT_WIDTH (f->output_data.x->font),
+                  FRAME_WINDOW_WIDTH (f) * FONT_WIDTH (f->output_data.x->font),
                   (j-i) * f->output_data.x->line_height,
                   intborder, CHAR_TO_PIXEL_ROW (f, i));
        i = j-1;
@@ -1330,7 +1385,7 @@ do_line_dance ()
        XCopyArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                   FRAME_X_WINDOW (f), f->output_data.x->normal_gc,
                   intborder, CHAR_TO_PIXEL_ROW (f, j+1+distance),
-                  f->width * FONT_WIDTH (f->output_data.x->font),
+                  FRAME_WINDOW_WIDTH (f) * FONT_WIDTH (f->output_data.x->font),
                   (i-j) * f->output_data.x->line_height,
                   intborder, CHAR_TO_PIXEL_ROW (f, j+1));
        i = j+1;
@@ -1343,7 +1398,7 @@ do_line_dance ()
        /* Clear [i,j) */
        XClearArea (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                    intborder, CHAR_TO_PIXEL_ROW (f, i),
-                   f->width * FONT_WIDTH (f->output_data.x->font),
+                   FRAME_WINDOW_WIDTH (f) * FONT_WIDTH (f->output_data.x->font),
                    (j-i) * f->output_data.x->line_height, False);
        i = j-1;
       }
@@ -1390,8 +1445,8 @@ dumprectangle (f, left, top, cols, rows)
     left = 0;
   if (top < 0)
     top = 0;
-  if (right > f->width)
-    right = f->width;
+  if (right > FRAME_WINDOW_WIDTH (f))
+    right = FRAME_WINDOW_WIDTH (f);
   if (bottom > f->height)
     bottom = f->height;
 
@@ -1431,7 +1486,7 @@ dumprectangle (f, left, top, cols, rows)
   /* Turn the cursor on if we turned it off.  */
 
   if (cursor_cleared)
-    x_display_cursor (f, 1);
+    x_update_cursor (f, 1);
 }
 \f
 static void
@@ -1744,8 +1799,8 @@ pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
     {
       if (pix_x < 0)
        pix_x = 0;
-      else if (pix_x > f->width)
-       pix_x = f->width;
+      else if (pix_x > FRAME_WINDOW_WIDTH (f))
+       pix_x = FRAME_WINDOW_WIDTH (f);
 
       if (pix_y < 0)
        pix_y = 0;
@@ -1914,7 +1969,8 @@ note_mouse_highlight (f, x, y)
   if (WINDOWP (window) && portion == 0 && row >= 0 && column >= 0
       && row < FRAME_HEIGHT (f) && column < FRAME_WIDTH (f)
       && EQ (w->window_end_valid, w->buffer)
-      && w->last_modified == BUF_MODIFF (XBUFFER (w->buffer)))
+      && w->last_modified == BUF_MODIFF (XBUFFER (w->buffer))
+      && w->last_overlay_modified == BUF_OVERLAY_MODIFF (XBUFFER (w->buffer)))
     {
       int *ptr = FRAME_CURRENT_GLYPHS (f)->charstarts[row];
       int i, pos;
@@ -1997,11 +2053,11 @@ note_mouse_highlight (f, x, y)
              before = Foverlay_start (overlay);
              after = Foverlay_end (overlay);
              /* Record this as the current active region.  */
-             fast_find_position (window, before,
+             fast_find_position (window, XFASTINT (before),
                                  &FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_col,
                                  &FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row);
              FRAME_X_DISPLAY_INFO (f)->mouse_face_past_end
-               = !fast_find_position (window, after,
+               = !fast_find_position (window, XFASTINT (after),
                                       &FRAME_X_DISPLAY_INFO (f)->mouse_face_end_col,
                                       &FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row);
              FRAME_X_DISPLAY_INFO (f)->mouse_face_window = window;
@@ -2031,11 +2087,11 @@ note_mouse_highlight (f, x, y)
                = Fnext_single_property_change (position, Qmouse_face,
                                                w->buffer, end);
              /* Record this as the current active region.  */
-             fast_find_position (window, before,
+             fast_find_position (window, XFASTINT (before),
                                  &FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_col,
                                  &FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row);
              FRAME_X_DISPLAY_INFO (f)->mouse_face_past_end
-               = !fast_find_position (window, after,
+               = !fast_find_position (window, XFASTINT (after),
                                       &FRAME_X_DISPLAY_INFO (f)->mouse_face_end_col,
                                       &FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row);
              FRAME_X_DISPLAY_INFO (f)->mouse_face_window = window;
@@ -2072,7 +2128,7 @@ fast_find_position (window, pos, columnp, rowp)
   FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
   int i;
   int row = 0;
-  int left = w->left;
+  int left = WINDOW_LEFT_MARGIN (w);
   int top = w->top;
   int height = XFASTINT (w->height) - ! MINI_WINDOW_P (w);
   int width = window_internal_width (w);
@@ -2122,7 +2178,7 @@ fast_find_position (window, pos, columnp, rowp)
   if (maybe_next_line)
     {
       row++;
-      i = 0;
+      lastcol = left;
     }
 
   *rowp = row + top;
@@ -2143,24 +2199,16 @@ show_mouse_face (dpyinfo, hl)
   FRAME_PTR f = XFRAME (WINDOW_FRAME (w));
   int i;
   int cursor_off = 0;
-  int old_curs_x = curs_x;
-  int old_curs_y = curs_y;
-
-  /* Set these variables temporarily
-     so that if we have to turn the cursor off and on again
-     we will put it back at the same place.  */
-  curs_x = f->phys_cursor_x;
-  curs_y = f->phys_cursor_y;
 
   for (i = FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row;
        i <= FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row; i++)
     {
       int column = (i == FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_row
                    ? FRAME_X_DISPLAY_INFO (f)->mouse_face_beg_col
-                   : w->left);
+                   : WINDOW_LEFT_MARGIN (w));
       int endcolumn = (i == FRAME_X_DISPLAY_INFO (f)->mouse_face_end_row
                       ? FRAME_X_DISPLAY_INFO (f)->mouse_face_end_col
-                      : w->left + width);
+                      : WINDOW_LEFT_MARGIN (w) + width);
       endcolumn = min (endcolumn, FRAME_CURRENT_GLYPHS (f)->used[i]);
 
       /* If the cursor's in the text we are about to rewrite,
@@ -2169,7 +2217,7 @@ show_mouse_face (dpyinfo, hl)
          && curs_x >= column - 1
          && curs_x <= endcolumn)
        {
-         x_display_cursor (f, 0);
+         x_update_cursor (f, 0);
          cursor_off = 1;
        }
 
@@ -2184,10 +2232,7 @@ show_mouse_face (dpyinfo, hl)
 
   /* If we turned the cursor off, turn it back on.  */
   if (cursor_off)
-    x_display_cursor (f, 1);
-
-  curs_x = old_curs_x;
-  curs_y = old_curs_y;
+    x_update_cursor (f, 1);
 
   /* Change the mouse cursor according to the value of HL.  */
   if (hl > 0)
@@ -2486,7 +2531,8 @@ x_scroll_bar_create (window, top, left, width, height)
        XCreateWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
 
                      /* Position and size of scroll bar.  */
-                     left, top, width, height,
+                     left + VERTICAL_SCROLL_BAR_WIDTH_TRIM, top,
+                     width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2, height,
 
                      /* Border width, depth, class, and visual.  */
                      0, CopyFromParent, CopyFromParent, CopyFromParent,
@@ -2549,9 +2595,9 @@ x_scroll_bar_set_handle (bar, start, end, rebuild)
   BLOCK_INPUT;
 
   {
-    int inside_width = VERTICAL_SCROLL_BAR_INSIDE_WIDTH (XINT (bar->width));
-    int inside_height = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (XINT (bar->height));
-    int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (XINT (bar->height));
+    int inside_width = VERTICAL_SCROLL_BAR_INSIDE_WIDTH (f, XINT (bar->width));
+    int inside_height = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f, XINT (bar->height));
+    int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
 
     /* Make sure the values are reasonable, and try to preserve
        the distance between start and end.  */
@@ -2635,9 +2681,10 @@ x_scroll_bar_move (bar, top, left, width, height)
     XWindowChanges wc;
     unsigned int mask = 0;
 
-    wc.x = left;
+    wc.x = left + VERTICAL_SCROLL_BAR_WIDTH_TRIM;
     wc.y = top;
-    wc.width = width;
+
+    wc.width = width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2;
     wc.height = height;
 
     if (left != XINT (bar->left))      mask |= CWX;
@@ -2718,7 +2765,7 @@ XTset_vertical_scroll_bar (window, portion, whole, position)
      dragged.  */
   if (NILP (bar->dragging))
     {
-      int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (pixel_height);
+      int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, pixel_height);
 
       if (whole == 0)
        x_scroll_bar_set_handle (bar, 0, top_range, 0);
@@ -2852,6 +2899,7 @@ x_scroll_bar_expose (bar, event)
   Window w = SCROLL_BAR_X_WINDOW (bar);
   FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
   GC gc = f->output_data.x->normal_gc;
+  int width_trim = VERTICAL_SCROLL_BAR_WIDTH_TRIM;
 
   BLOCK_INPUT;
 
@@ -2861,8 +2909,10 @@ x_scroll_bar_expose (bar, event)
   XDrawRectangle (FRAME_X_DISPLAY (f), w, gc,
 
                  /* x, y, width, height */
-                 0, 0, XINT (bar->width) - 1, XINT (bar->height) - 1);
-
+                 0, 0,
+                 XINT (bar->width) - 1 - width_trim - width_trim,
+                 XINT (bar->height) - 1);
+    
   UNBLOCK_INPUT;
 }
 
@@ -2892,10 +2942,11 @@ x_scroll_bar_handle_click (bar, event, emacs_event)
   emacs_event->frame_or_window = bar->window;
   emacs_event->timestamp = event->xbutton.time;
   {
+    FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
     int internal_height
-      = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (XINT (bar->height));
+      = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f, XINT (bar->height));
     int top_range
-      = VERTICAL_SCROLL_BAR_TOP_RANGE (XINT (bar->height));
+      = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
     int y = event->xbutton.y - VERTICAL_SCROLL_BAR_TOP_BORDER;
 
     if (y < 0) y = 0;
@@ -3014,9 +3065,9 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
   else
     {
       int inside_height
-       = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (XINT (bar->height));
+       = VERTICAL_SCROLL_BAR_INSIDE_HEIGHT (f, XINT (bar->height));
       int top_range
-       = VERTICAL_SCROLL_BAR_TOP_RANGE     (XINT (bar->height));
+       = VERTICAL_SCROLL_BAR_TOP_RANGE     (f, XINT (bar->height));
 
       win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
 
@@ -3237,15 +3288,13 @@ static struct x_display_info *next_noop_dpyinfo;
    We return the number of characters stored into the buffer,
    thus pretending to be `read'.
 
-   WAITP is nonzero if we should block until input arrives.
    EXPECTED is nonzero if the caller knows input is available.  */
 
 int
-XTread_socket (sd, bufp, numchars, waitp, expected)
+XTread_socket (sd, bufp, numchars, expected)
      register int sd;
      /* register */ struct input_event *bufp;
      /* register */ int numchars;
-     int waitp;
      int expected;
 {
   int count = 0;
@@ -3322,6 +3371,16 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
          XtAppNextEvent (Xt_app_con, &event);
 #else
          XNextEvent (dpyinfo->display, &event);
+#endif
+#ifdef HAVE_X_I18N
+         {
+           struct frame *f1 = x_any_window_to_frame (dpyinfo,
+                                                     &event.xclient.window);
+           /* The necessity of the following line took me
+              a full work-day to decipher from the docs!!  */
+           if (f1 != 0 && FRAME_XIC (f1) && XFilterEvent (&event, None))
+             break;
+         }
 #endif
          event_found = 1;
 
@@ -3633,7 +3692,11 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                  unsigned char copy_buffer[81];
                  int modifiers;
 
-#ifdef USE_X_TOOLKIT
+#if 0 /* This was how we made f10 work in Motif.
+        The drawback is, you can't type at Emacs when the
+        the mouse is in the menu bar.  So it is better to
+        turn off f10 in Motif and let Emacs handle it.  */
+#ifdef USE_MOTIF
                   if (lw_window_is_in_menubar (event.xkey.window,
                                                f->output_data.x->menubar_widget
                                                ))
@@ -3641,7 +3704,8 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                       SET_SAVED_KEY_EVENT;
                       break;
                     }
-#endif /* USE_X_TOOLKIT */
+#endif /* USE_MOTIF */
+#endif /* 0 */
 
                  event.xkey.state
                    |= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f),
@@ -3661,10 +3725,6 @@ XTread_socket (sd, bufp, numchars, waitp, 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,
@@ -4048,17 +4108,29 @@ XTread_socket (sd, bufp, numchars, waitp, expected)
                    && event.xbutton.same_screen)
                  {
                    SET_SAVED_BUTTON_EVENT;
-                   last_mouse_press_frame = f;
+                   XSETFRAME (last_mouse_press_frame, f);
+                 }
+               else if (event.type == ButtonPress)
+                 {
+                   last_mouse_press_frame = Qnil;
+                   goto OTHER;
                  }
+#ifdef USE_MOTIF /* This should do not harm for Lucid,
+                   but I am trying to be cautious.  */
                else if (event.type == ButtonRelease)
                  {
-                   if (!f)
-                     f = last_mouse_press_frame;
-                   if (f)
+                   if (!NILP (last_mouse_press_frame))
                      {
-                       SET_SAVED_BUTTON_EVENT;
+                       f = XFRAME (last_mouse_press_frame);
+                       if (f->output_data.x)
+                         {
+                           SET_SAVED_BUTTON_EVENT;
+                         }
                      }
+                   else 
+                     goto OTHER;
                  }
+#endif /* USE_MOTIF */
                else
                  goto OTHER;
 #endif /* USE_X_TOOLKIT */
@@ -4166,7 +4238,7 @@ clear_cursor (f)
       || f->phys_cursor_x < 0)
     return;
 
-  x_display_cursor (f, 0);
+  x_update_cursor (f, 0);
   f->phys_cursor_x = -1;
 }
 
@@ -4349,29 +4421,19 @@ x_display_box_cursor (f, on, x, y)
 }
 
 /* Display the cursor on frame F, or clear it, according to ON.
-   Use the position specified by curs_x and curs_y
-   if we are doing an update of frame F now.
-   Otherwise use the position in the FRAME_CURSOR_X and FRAME_CURSOR_Y fields
-   of F.  */
+   Also set the frame's cursor position to X and Y.  */
 
-x_display_cursor (f, on)
+x_display_cursor (f, on, x, y)
      struct frame *f;
      int on;
+     int x, y;
 {
   BLOCK_INPUT;
 
-  /* If we're not updating, then don't change the physical cursor
-     position.  Just change (if appropriate) the style of display.  */
-  if (f != updating_frame)
-    {
-      curs_x = FRAME_CURSOR_X (f);
-      curs_y = FRAME_CURSOR_Y (f);
-    }
-
   if (FRAME_DESIRED_CURSOR (f) == filled_box_cursor)
-    x_display_box_cursor (f, on, curs_x, curs_y);
+    x_display_box_cursor (f, on, x, y);
   else if (FRAME_DESIRED_CURSOR (f) == bar_cursor)
-    x_display_bar_cursor (f, on, curs_x, curs_y);
+    x_display_bar_cursor (f, on, x, y);
   else
     /* Those are the only two we have implemented!  */
     abort ();
@@ -4510,6 +4572,10 @@ x_connection_closed (display, error_message)
 
   /* Indicate that this display is dead.  */
 
+  #ifdef USE_X_TOOLKIT
+  XtCloseDisplay (display);
+  #endif
+
   dpyinfo->display = 0;
 
   /* First delete frames whose minibuffers are on frames
@@ -4772,7 +4838,6 @@ x_new_font (f, fontname)
       char *full_name;
       XFontStruct *font;
       int n_fonts;
-      Atom FONT_atom;
 
       /* Try to find a character-cell font in the list.  */
 #if 0
@@ -4818,10 +4883,9 @@ x_new_font (f, fontname)
 
       /* Try to get the full name of FONT.  Put it in full_name.  */
       full_name = 0;
-      FONT_atom = XInternAtom (FRAME_X_DISPLAY (f), "FONT", False);
       for (i = 0; i < font->n_properties; i++)
        {
-         if (FONT_atom == font->properties[i].name)
+         if (FRAME_X_DISPLAY_INFO (f)->Xatom_FONT == font->properties[i].name)
            {
              char *name = XGetAtomName (FRAME_X_DISPLAY (f),
                                         (Atom) (font->properties[i].card32));
@@ -6042,6 +6106,8 @@ x_term_init (display_name, xrm_option, resource_name)
     = XInternAtom (dpyinfo->display, "WM_MOVED", False);
   dpyinfo->Xatom_editres
     = XInternAtom (dpyinfo->display, "Editres", False);
+  dpyinfo->Xatom_FONT
+    = XInternAtom (dpyinfo->display, "FONT", False);
   dpyinfo->Xatom_CLIPBOARD
     = XInternAtom (dpyinfo->display, "CLIPBOARD", False);
   dpyinfo->Xatom_TIMESTAMP
@@ -6090,6 +6156,30 @@ x_term_init (display_name, xrm_option, resource_name)
     init_sigio (connection);
 #endif /* ! defined (SIGIO) */
 
+#ifdef USE_LUCID
+  /* Make sure that we have a valid font for dialog boxes
+     so that Xt does not crash.  */
+  {
+    Display *dpy = dpyinfo->display;
+    XrmValue d, fr, to;
+    Font font;
+    
+    d.addr = (XPointer)&dpy;
+    d.size = sizeof (Display *);
+    fr.addr = XtDefaultFont;
+    fr.size = sizeof (XtDefaultFont);
+    to.size = sizeof (Font *);
+    to.addr = (XPointer)&font;
+    x_catch_errors (dpy);
+    if (!XtCallConverter (dpy, XtCvtStringToFont, &d, 1, &fr, &to, NULL))
+      abort ();
+    if (x_had_errors_p (dpy) || !XQueryFont (dpy, font))
+      XrmPutLineResource (&xrdb, "Emacs.dialog.*.font: 9x15");
+    x_uncatch_errors (dpy);
+  }
+#endif
+
+
   UNBLOCK_INPUT;
 
   return dpyinfo;
@@ -6223,6 +6313,9 @@ syms_of_xterm ()
 
   staticpro (&Qvendor_specific_keysyms);
   Qvendor_specific_keysyms = intern ("vendor-specific-keysyms");
+
+  staticpro (&last_mouse_press_frame);
+  last_mouse_press_frame = Qnil;
 }
 
 #endif /* not HAVE_X_WINDOWS */